diff --git a/pandas/core/indexes/datetimelike.py b/pandas/core/indexes/datetimelike.py index c3232627fce74..d5b4525e8a1eb 100644 --- a/pandas/core/indexes/datetimelike.py +++ b/pandas/core/indexes/datetimelike.py @@ -621,7 +621,9 @@ def _convert_scalar_indexer(self, key, kind=None): ._convert_scalar_indexer(key, kind=kind)) def _add_datelike(self, other): - raise AbstractMethodError(self) + raise TypeError("cannot add {0} and {1}" + .format(type(self).__name__, + type(other).__name__)) def _sub_datelike(self, other): raise AbstractMethodError(self) @@ -647,16 +649,13 @@ def __add__(self, other): return other._add_delta(self) raise TypeError("cannot add TimedeltaIndex and {typ}" .format(typ=type(other))) - elif isinstance(other, Index): - raise TypeError("cannot add {typ1} and {typ2}" - .format(typ1=type(self).__name__, - typ2=type(other).__name__)) elif isinstance(other, (DateOffset, timedelta, np.timedelta64, Timedelta)): return self._add_delta(other) elif is_integer(other): return self.shift(other) - elif isinstance(other, (Timestamp, datetime)): + elif isinstance(other, (Index, Timestamp, datetime, + np.datetime64)): return self._add_datelike(other) else: # pragma: no cover return NotImplemented diff --git a/pandas/core/indexes/datetimes.py b/pandas/core/indexes/datetimes.py index 9127864eab8a1..ef3af2acf46a7 100644 --- a/pandas/core/indexes/datetimes.py +++ b/pandas/core/indexes/datetimes.py @@ -747,7 +747,9 @@ def _add_datelike(self, other): # adding a timedeltaindex to a datetimelike if other is libts.NaT: return self._nat_new(box=True) - raise TypeError("cannot add a datelike to a DatetimeIndex") + raise TypeError("cannot add {0} and {1}" + .format(type(self).__name__, + type(other).__name__)) def _sub_datelike(self, other): # subtract a datetime from myself, yielding a TimedeltaIndex diff --git a/pandas/tests/indexes/datetimes/test_ops.py b/pandas/tests/indexes/datetimes/test_ops.py index 86e65feec04f3..f0f9b8ff1fc6d 100644 --- a/pandas/tests/indexes/datetimes/test_ops.py +++ b/pandas/tests/indexes/datetimes/test_ops.py @@ -434,31 +434,51 @@ def test_add_iadd(self): tm.assert_index_equal(rng, expected) idx = DatetimeIndex(['2011-01-01', '2011-01-02']) - msg = "cannot add a datelike to a DatetimeIndex" + msg = "cannot add DatetimeIndex and Timestamp" with tm.assert_raises_regex(TypeError, msg): idx + Timestamp('2011-01-01') with tm.assert_raises_regex(TypeError, msg): Timestamp('2011-01-01') + idx - def test_add_dti_dti(self): - # previously performed setop (deprecated in 0.16.0), now raises - # TypeError (GH14164) - - dti = date_range('20130101', periods=3) - dti_tz = date_range('20130101', periods=3).tz_localize('US/Eastern') - - with pytest.raises(TypeError): - dti + dti - - with pytest.raises(TypeError): - dti_tz + dti_tz - - with pytest.raises(TypeError): - dti_tz + dti - - with pytest.raises(TypeError): - dti + dti_tz + @pytest.mark.parametrize('addend', [ + datetime(2011, 1, 1), + DatetimeIndex(['2011-01-01', '2011-01-02']), + DatetimeIndex(['2011-01-01', '2011-01-02']) + .tz_localize('US/Eastern'), + np.datetime64('2011-01-01'), + Timestamp('2011-01-01'), + ]) + def test_add_datetimelike_and_dti(self, addend): + # issue #9631 + + dti = DatetimeIndex(['2011-01-01', '2011-01-02']) + msg = 'cannot add DatetimeIndex and {0}'.format( + type(addend).__name__) + with tm.assert_raises_regex(TypeError, msg): + dti + addend + with tm.assert_raises_regex(TypeError, msg): + addend + dti + + @pytest.mark.parametrize('addend', [ + datetime(2011, 1, 1), + DatetimeIndex(['2011-01-01', '2011-01-02']), + DatetimeIndex(['2011-01-01', '2011-01-02']) + .tz_localize('US/Eastern'), + np.datetime64('2011-01-01'), + Timestamp('2011-01-01'), + ]) + def test_add_datetimelike_and_dti_tz(self, addend): + # issue #9631 + + dti_tz = DatetimeIndex(['2011-01-01', '2011-01-02']) \ + .tz_localize('US/Eastern') + msg = 'cannot add DatetimeIndex and {0}'.format( + type(addend).__name__) + with tm.assert_raises_regex(TypeError, msg): + dti_tz + addend + with tm.assert_raises_regex(TypeError, msg): + addend + dti_tz def test_difference(self): for tz in self.tz: