diff --git a/pandas/core/arrays/datetimelike.py b/pandas/core/arrays/datetimelike.py index 9a723a88941b6..f8d4dd4c78bcb 100644 --- a/pandas/core/arrays/datetimelike.py +++ b/pandas/core/arrays/datetimelike.py @@ -1486,7 +1486,8 @@ def __rsub__(self, other): # GH#19959 datetime - datetime is well-defined as timedelta, # but any other type - datetime is not well-defined. raise TypeError( - f"cannot subtract {type(self).__name__} from {type(other).__name__}" + f"cannot subtract {type(self).__name__} from " + f"{type(other).__name__}[{other.dtype}]" ) elif isinstance(self.dtype, PeriodDtype) and lib.is_np_dtype(other_dtype, "m"): # TODO: Can we simplify/generalize these cases at all? @@ -1495,8 +1496,14 @@ def __rsub__(self, other): self = cast("TimedeltaArray", self) return (-self) + other + flipped = self - other + if flipped.dtype.kind == "M": + # GH#59571 give a more helpful exception message + raise TypeError( + f"cannot subtract {type(self).__name__} from {type(other).__name__}" + ) # We get here with e.g. datetime objects - return -(self - other) + return -flipped def __iadd__(self, other) -> Self: result = self + other diff --git a/pandas/tests/arithmetic/test_datetime64.py b/pandas/tests/arithmetic/test_datetime64.py index d439ff723b355..5d831e0ec25a1 100644 --- a/pandas/tests/arithmetic/test_datetime64.py +++ b/pandas/tests/arithmetic/test_datetime64.py @@ -955,7 +955,12 @@ def test_dt64arr_add_sub_td64ndarray(self, tz_naive_fixture, box_with_array): result = dtarr - tdarr tm.assert_equal(result, expected) - msg = "cannot subtract|(bad|unsupported) operand type for unary" + msg = "|".join( + [ + "cannot subtract DatetimeArray from ndarray", + "cannot subtract a datelike from a TimedeltaArray", + ] + ) with pytest.raises(TypeError, match=msg): tdarr - dtarr @@ -1272,7 +1277,7 @@ def test_dt64arr_series_sub_tick_DateOffset(self, box_with_array): result2 = -pd.offsets.Second(5) + ser tm.assert_equal(result2, expected) - msg = "(bad|unsupported) operand type for unary" + msg = "cannot subtract DatetimeArray from Second" with pytest.raises(TypeError, match=msg): pd.offsets.Second(5) - ser @@ -1317,9 +1322,7 @@ def test_dti_add_tick_tzaware(self, tz_aware_fixture, box_with_array): roundtrip = offset - scalar tm.assert_equal(roundtrip, dates) - msg = "|".join( - ["bad operand type for unary -", "cannot subtract DatetimeArray"] - ) + msg = "cannot subtract DatetimeArray from" with pytest.raises(TypeError, match=msg): scalar - dates @@ -1378,7 +1381,7 @@ def test_dt64arr_add_sub_relativedelta_offsets(self, box_with_array, unit): expected = DatetimeIndex([x - off for x in vec_items]).as_unit(exp_unit) expected = tm.box_expected(expected, box_with_array) tm.assert_equal(expected, vec - off) - msg = "(bad|unsupported) operand type for unary" + msg = "cannot subtract DatetimeArray from" with pytest.raises(TypeError, match=msg): off - vec @@ -1494,7 +1497,7 @@ def test_dt64arr_add_sub_DateOffsets( expected = DatetimeIndex([offset + x for x in vec_items]).as_unit(unit) expected = tm.box_expected(expected, box_with_array) tm.assert_equal(expected, offset + vec) - msg = "(bad|unsupported) operand type for unary" + msg = "cannot subtract DatetimeArray from" with pytest.raises(TypeError, match=msg): offset - vec @@ -1983,7 +1986,7 @@ def test_operators_datetimelike_with_timezones(self): result = dt1 - td1[0] exp = (dt1.dt.tz_localize(None) - td1[0]).dt.tz_localize(tz) tm.assert_series_equal(result, exp) - msg = "(bad|unsupported) operand type for unary" + msg = "cannot subtract DatetimeArray from" with pytest.raises(TypeError, match=msg): td1[0] - dt1 diff --git a/pandas/tests/arithmetic/test_timedelta64.py b/pandas/tests/arithmetic/test_timedelta64.py index 87e085fb22878..642420713aeba 100644 --- a/pandas/tests/arithmetic/test_timedelta64.py +++ b/pandas/tests/arithmetic/test_timedelta64.py @@ -320,7 +320,7 @@ def test_subtraction_ops(self): with pytest.raises(TypeError, match=msg): td - dt - msg = "(bad|unsupported) operand type for unary" + msg = "cannot subtract DatetimeArray from Timedelta" with pytest.raises(TypeError, match=msg): td - dti