From e884a69b1aa9edcb72a6f6a3ff6dc1d8e17816cd Mon Sep 17 00:00:00 2001
From: Brock Mendel <jbrockmendel@gmail.com>
Date: Mon, 15 Jan 2018 11:35:27 -0800
Subject: [PATCH 1/3] Fix Index mul/div ops with Series, closes #19080, #19042

---
 pandas/core/indexes/base.py                   |  5 ++-
 pandas/core/indexes/range.py                  |  3 ++
 pandas/tests/indexes/test_numeric.py          | 31 ++++++++++---------
 .../indexes/timedeltas/test_arithmetic.py     |  9 +++---
 4 files changed, 29 insertions(+), 19 deletions(-)

diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py
index f634d809560ee..48260c68d30f3 100644
--- a/pandas/core/indexes/base.py
+++ b/pandas/core/indexes/base.py
@@ -13,7 +13,7 @@
 from pandas import compat
 
 from pandas.core.dtypes.generic import (
-    ABCSeries,
+    ABCSeries, ABCDataFrame,
     ABCMultiIndex,
     ABCPeriodIndex,
     ABCDateOffset)
@@ -4020,6 +4020,9 @@ def _add_numeric_methods_binary(cls):
 
         def _make_evaluate_binop(op, opstr, reversed=False, constructor=Index):
             def _evaluate_numeric_binop(self, other):
+                if isinstance(other, (ABCSeries, ABCDataFrame)):
+                    return NotImplemented
+
                 other = self._validate_for_numeric_binop(other, op, opstr)
 
                 # handle time-based others
diff --git a/pandas/core/indexes/range.py b/pandas/core/indexes/range.py
index 741dca6be0630..10a923c056be2 100644
--- a/pandas/core/indexes/range.py
+++ b/pandas/core/indexes/range.py
@@ -8,6 +8,7 @@
     is_integer,
     is_scalar,
     is_int64_dtype)
+from pandas.core.dtypes.generic import ABCSeries
 
 from pandas import compat
 from pandas.compat import lrange, range, get_range_parameters
@@ -583,6 +584,8 @@ def _make_evaluate_binop(op, opstr, reversed=False, step=False):
             """
 
             def _evaluate_numeric_binop(self, other):
+                if isinstance(other, ABCSeries):
+                    return NotImplemented
 
                 other = self._validate_for_numeric_binop(other, op, opstr)
                 attrs = self._get_attributes_dict()
diff --git a/pandas/tests/indexes/test_numeric.py b/pandas/tests/indexes/test_numeric.py
index dcd592345b91c..320ec3bd76987 100644
--- a/pandas/tests/indexes/test_numeric.py
+++ b/pandas/tests/indexes/test_numeric.py
@@ -68,12 +68,12 @@ def test_numeric_compat(self):
         tm.assert_index_equal(result, didx)
 
         result = idx * Series(np.arange(5, dtype=arr_dtype))
-        tm.assert_index_equal(result, didx)
+        tm.assert_series_equal(result, Series(didx))
 
-        result = idx * Series(np.arange(5, dtype='float64') + 0.1)
-        expected = Float64Index(np.arange(5, dtype='float64') *
-                                (np.arange(5, dtype='float64') + 0.1))
-        tm.assert_index_equal(result, expected)
+        rng5 = np.arange(5, dtype='float64')
+        result = idx * Series(rng5 + 0.1)
+        expected = Series(rng5 * (rng5 + 0.1))
+        tm.assert_series_equal(result, expected)
 
         # invalid
         pytest.raises(TypeError,
@@ -95,15 +95,6 @@ def test_numeric_compat(self):
         for r, e in zip(result, expected):
             tm.assert_index_equal(r, e)
 
-        result = divmod(idx, Series(full_like(idx.values, 2)))
-        with np.errstate(all='ignore'):
-            div, mod = divmod(
-                idx.values,
-                full_like(idx.values, 2),
-            )
-            expected = Index(div), Index(mod)
-        for r, e in zip(result, expected):
-            tm.assert_index_equal(r, e)
 
         # test power calculations both ways, GH 14973
         expected = pd.Float64Index(2.0**idx.values)
@@ -114,6 +105,18 @@ def test_numeric_compat(self):
         result = idx**2.0
         tm.assert_index_equal(result, expected)
 
+    @pytest.mark.xfail(reason='GH#19252 Series has no __rdivmod__')
+    def test_divmod_series(self):
+        idx = self.create_index()
+
+        result = divmod(idx, Series(full_like(idx.values, 2)))
+        with np.errstate(all='ignore'):
+            div, mod = divmod(idx.values, full_like(idx.values, 2))
+            expected = Series(div), Series(mod)
+
+        for r, e in zip(result, expected):
+            tm.assert_series_equal(r, e)
+
     def test_explicit_conversions(self):
 
         # GH 8608
diff --git a/pandas/tests/indexes/timedeltas/test_arithmetic.py b/pandas/tests/indexes/timedeltas/test_arithmetic.py
index 3ec918e391860..962de91ed0581 100644
--- a/pandas/tests/indexes/timedeltas/test_arithmetic.py
+++ b/pandas/tests/indexes/timedeltas/test_arithmetic.py
@@ -152,11 +152,12 @@ def test_numeric_compat(self):
         tm.assert_index_equal(result, didx)
 
         result = idx * Series(np.arange(5, dtype='int64'))
-        tm.assert_index_equal(result, didx)
+        tm.assert_series_equal(result, Series(didx))
 
-        result = idx * Series(np.arange(5, dtype='float64') + 0.1)
-        tm.assert_index_equal(result, self._holder(np.arange(
-            5, dtype='float64') * (np.arange(5, dtype='float64') + 0.1)))
+        rng5 = np.arange(5, dtype='float64')
+        result = idx * Series(rng5 + 0.1)
+        tm.assert_series_equal(result,
+                               Series(self._holder(rng5 * (rng5 + 0.1))))
 
         # invalid
         pytest.raises(TypeError, lambda: idx * idx)

From f1917a6195fb937534887dbc5a4e7d791877fe45 Mon Sep 17 00:00:00 2001
From: Brock Mendel <jbrockmendel@gmail.com>
Date: Mon, 15 Jan 2018 11:36:47 -0800
Subject: [PATCH 2/3] flake8 whitespce fixup

---
 pandas/tests/indexes/test_numeric.py | 1 -
 1 file changed, 1 deletion(-)

diff --git a/pandas/tests/indexes/test_numeric.py b/pandas/tests/indexes/test_numeric.py
index 320ec3bd76987..1ce8ade50c071 100644
--- a/pandas/tests/indexes/test_numeric.py
+++ b/pandas/tests/indexes/test_numeric.py
@@ -95,7 +95,6 @@ def test_numeric_compat(self):
         for r, e in zip(result, expected):
             tm.assert_index_equal(r, e)
 
-
         # test power calculations both ways, GH 14973
         expected = pd.Float64Index(2.0**idx.values)
         result = 2.0**idx

From 06ab12b4d3ad4f87d9274205e6dfa096925b307e Mon Sep 17 00:00:00 2001
From: Brock Mendel <jbrockmendel@gmail.com>
Date: Mon, 15 Jan 2018 20:59:02 -0800
Subject: [PATCH 3/3] whatsnew note

---
 doc/source/whatsnew/v0.23.0.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/doc/source/whatsnew/v0.23.0.txt b/doc/source/whatsnew/v0.23.0.txt
index e40318bd65db2..06e35bff0c565 100644
--- a/doc/source/whatsnew/v0.23.0.txt
+++ b/doc/source/whatsnew/v0.23.0.txt
@@ -423,7 +423,7 @@ Conversion
 - Bug in :class:`WeekOfMonth` and :class:`LastWeekOfMonth` where default keyword arguments for constructor raised ``ValueError`` (:issue:`19142`)
 - Bug in localization of a naive, datetime string in a ``Series`` constructor with a ``datetime64[ns, tz]`` dtype (:issue:`174151`)
 - :func:`Timestamp.replace` will now handle Daylight Savings transitions gracefully (:issue:`18319`)
-
+- Bug in :class:`Index` multiplication and division methods where operating with a ``Series`` would return an ``Index`` object instead of a ``Series`` object (:issue:`19042`)
 
 
 - Bug in ``.astype()`` to non-ns timedelta units would hold the incorrect dtype (:issue:`19176`, :issue:`19223`, :issue:`12425`)