diff --git a/pandas/core/ops/array_ops.py b/pandas/core/ops/array_ops.py index b84d468fff736..064e2e3ea4412 100644 --- a/pandas/core/ops/array_ops.py +++ b/pandas/core/ops/array_ops.py @@ -95,7 +95,9 @@ def masked_arith_op(x, y, op): else: if not is_scalar(y): - raise TypeError(type(y)) + raise TypeError( + f"Cannot broadcast np.ndarray with operand of type { type(y) }" + ) # mask is only meaningful for x result = np.empty(x.size, dtype=x.dtype) diff --git a/pandas/tests/arithmetic/test_numeric.py b/pandas/tests/arithmetic/test_numeric.py index f55e2b98ee912..7c0f94001d306 100644 --- a/pandas/tests/arithmetic/test_numeric.py +++ b/pandas/tests/arithmetic/test_numeric.py @@ -135,10 +135,11 @@ def test_div_td64arr(self, left, box_cls): result = right // left tm.assert_equal(result, expected) - with pytest.raises(TypeError): + msg = "Cannot divide" + with pytest.raises(TypeError, match=msg): left / right - with pytest.raises(TypeError): + with pytest.raises(TypeError, match=msg): left // right # TODO: de-duplicate with test_numeric_arr_mul_tdscalar @@ -187,7 +188,8 @@ def test_numeric_arr_rdiv_tdscalar(self, three_days, numeric_idx, box): result = three_days / index tm.assert_equal(result, expected) - with pytest.raises(TypeError): + msg = "cannot use operands with types dtype" + with pytest.raises(TypeError, match=msg): index / three_days @pytest.mark.parametrize( @@ -205,13 +207,19 @@ def test_numeric_arr_rdiv_tdscalar(self, three_days, numeric_idx, box): ) def test_add_sub_timedeltalike_invalid(self, numeric_idx, other, box): left = tm.box_expected(numeric_idx, box) - with pytest.raises(TypeError): + msg = ( + "unsupported operand type|" + "Addition/subtraction of integers and integer-arrays|" + "Instead of adding/subtracting|" + "cannot use operands with types dtype" + ) + with pytest.raises(TypeError, match=msg): left + other - with pytest.raises(TypeError): + with pytest.raises(TypeError, match=msg): other + left - with pytest.raises(TypeError): + with pytest.raises(TypeError, match=msg): left - other - with pytest.raises(TypeError): + with pytest.raises(TypeError, match=msg): other - left @pytest.mark.parametrize( @@ -229,13 +237,18 @@ def test_add_sub_datetimelike_invalid(self, numeric_idx, other, box): # NullFrequencyError instead of TypeError so is excluded. left = tm.box_expected(numeric_idx, box) - with pytest.raises(TypeError): + msg = ( + "unsupported operand type|" + "Cannot (add|subtract) NaT (to|from) ndarray|" + "Addition/subtraction of integers and integer-arrays" + ) + with pytest.raises(TypeError, match=msg): left + other - with pytest.raises(TypeError): + with pytest.raises(TypeError, match=msg): other + left - with pytest.raises(TypeError): + with pytest.raises(TypeError, match=msg): left - other - with pytest.raises(TypeError): + with pytest.raises(TypeError, match=msg): other - left @@ -607,14 +620,16 @@ def test_mul_index(self, numeric_idx): def test_mul_datelike_raises(self, numeric_idx): idx = numeric_idx - with pytest.raises(TypeError): + msg = "cannot perform __rmul__ with this index type" + with pytest.raises(TypeError, match=msg): idx * pd.date_range("20130101", periods=5) def test_mul_size_mismatch_raises(self, numeric_idx): idx = numeric_idx - with pytest.raises(ValueError): + msg = "operands could not be broadcast together" + with pytest.raises(ValueError, match=msg): idx * idx[0:3] - with pytest.raises(ValueError): + with pytest.raises(ValueError, match=msg): idx * np.array([1, 2]) @pytest.mark.parametrize("op", [operator.pow, ops.rpow]) @@ -792,10 +807,11 @@ def test_series_frame_radd_bug(self): # really raise this time now = pd.Timestamp.now().to_pydatetime() - with pytest.raises(TypeError): + msg = "unsupported operand type" + with pytest.raises(TypeError, match=msg): now + ts - with pytest.raises(TypeError): + with pytest.raises(TypeError, match=msg): ts + now # TODO: This came from series.test.test_operators, needs cleanup @@ -816,7 +832,8 @@ def test_datetime64_with_index(self): result = ser - ser.index tm.assert_series_equal(result, expected) - with pytest.raises(TypeError): + msg = "cannot subtract period" + with pytest.raises(TypeError, match=msg): # GH#18850 result = ser - ser.index.to_period() diff --git a/pandas/tests/arithmetic/test_object.py b/pandas/tests/arithmetic/test_object.py index c0d3c9d4977bd..579cede8b8480 100644 --- a/pandas/tests/arithmetic/test_object.py +++ b/pandas/tests/arithmetic/test_object.py @@ -155,9 +155,10 @@ def test_objarr_add_invalid(self, op, box_with_array): obj_ser.name = "objects" obj_ser = tm.box_expected(obj_ser, box) - with pytest.raises(Exception): + msg = "can only concatenate str|unsupported operand type|must be str" + with pytest.raises(Exception, match=msg): op(obj_ser, 1) - with pytest.raises(Exception): + with pytest.raises(Exception, match=msg): op(obj_ser, np.array(1, dtype=np.int64)) # TODO: Moved from tests.series.test_operators; needs cleanup @@ -281,13 +282,15 @@ def test_add(self): def test_sub_fail(self): index = tm.makeStringIndex(100) - with pytest.raises(TypeError): + + msg = "unsupported operand type|Cannot broadcast" + with pytest.raises(TypeError, match=msg): index - "a" - with pytest.raises(TypeError): + with pytest.raises(TypeError, match=msg): index - index - with pytest.raises(TypeError): + with pytest.raises(TypeError, match=msg): index - index.tolist() - with pytest.raises(TypeError): + with pytest.raises(TypeError, match=msg): index.tolist() - index def test_sub_object(self): @@ -301,10 +304,11 @@ def test_sub_object(self): result = index - pd.Index([Decimal(1), Decimal(1)]) tm.assert_index_equal(result, expected) - with pytest.raises(TypeError): + msg = "unsupported operand type" + with pytest.raises(TypeError, match=msg): index - "foo" - with pytest.raises(TypeError): + with pytest.raises(TypeError, match=msg): index - np.array([2, "foo"]) def test_rsub_object(self): @@ -318,8 +322,9 @@ def test_rsub_object(self): result = np.array([Decimal(2), Decimal(2)]) - index tm.assert_index_equal(result, expected) - with pytest.raises(TypeError): + msg = "unsupported operand type" + with pytest.raises(TypeError, match=msg): "foo" - index - with pytest.raises(TypeError): + with pytest.raises(TypeError, match=msg): np.array([True, pd.Timestamp.now()]) - index diff --git a/pandas/tests/arithmetic/test_timedelta64.py b/pandas/tests/arithmetic/test_timedelta64.py index 158da37aa7239..abdeb1b30b626 100644 --- a/pandas/tests/arithmetic/test_timedelta64.py +++ b/pandas/tests/arithmetic/test_timedelta64.py @@ -48,7 +48,8 @@ def test_compare_timedelta64_zerodim(self, box_with_array): expected = tm.box_expected(expected, xbox) tm.assert_equal(res, expected) - with pytest.raises(TypeError): + msg = "Invalid comparison between dtype" + with pytest.raises(TypeError, match=msg): # zero-dim of wrong dtype should still raise tdi >= np.array(4) @@ -442,7 +443,8 @@ def test_addition_ops(self): tdi[0:1] + dti # random indexes - with pytest.raises(TypeError): + msg = "Addition/subtraction of integers and integer-arrays" + with pytest.raises(TypeError, match=msg): tdi + pd.Int64Index([1, 2, 3]) # this is a union! @@ -604,6 +606,7 @@ def test_tdi_add_timestamp_nat_masking(self): def test_tdi_add_overflow(self): # See GH#14068 # preliminary test scalar analogue of vectorized tests below + # TODO: Make raised error message more informative and test with pytest.raises(OutOfBoundsDatetime): pd.to_timedelta(106580, "D") + Timestamp("2000") with pytest.raises(OutOfBoundsDatetime): @@ -700,13 +703,14 @@ def test_timedelta_ops_with_missing_values(self): actual = -timedelta_NaT + s1 tm.assert_series_equal(actual, sn) - with pytest.raises(TypeError): + msg = "unsupported operand type" + with pytest.raises(TypeError, match=msg): s1 + np.nan - with pytest.raises(TypeError): + with pytest.raises(TypeError, match=msg): np.nan + s1 - with pytest.raises(TypeError): + with pytest.raises(TypeError, match=msg): s1 - np.nan - with pytest.raises(TypeError): + with pytest.raises(TypeError, match=msg): -np.nan + s1 actual = s1 + pd.NaT @@ -738,9 +742,10 @@ def test_timedelta_ops_with_missing_values(self): actual = df1 - timedelta_NaT tm.assert_frame_equal(actual, dfn) - with pytest.raises(TypeError): + msg = "cannot subtract a datelike from|unsupported operand type" + with pytest.raises(TypeError, match=msg): df1 + np.nan - with pytest.raises(TypeError): + with pytest.raises(TypeError, match=msg): df1 - np.nan actual = df1 + pd.NaT # NaT is datetime, not timedelta @@ -957,7 +962,8 @@ def test_td64arr_add_sub_datetimelike_scalar(self, ts, box_with_array): tm.assert_equal(ts - tdarr, expected2) tm.assert_equal(ts + (-tdarr), expected2) - with pytest.raises(TypeError): + msg = "cannot subtract a datelike" + with pytest.raises(TypeError, match=msg): tdarr - ts def test_tdi_sub_dt64_array(self, box_with_array): @@ -969,7 +975,8 @@ def test_tdi_sub_dt64_array(self, box_with_array): tdi = tm.box_expected(tdi, box_with_array) expected = tm.box_expected(expected, box_with_array) - with pytest.raises(TypeError): + msg = "cannot subtract a datelike from" + with pytest.raises(TypeError, match=msg): tdi - dtarr # TimedeltaIndex.__rsub__ @@ -1025,7 +1032,8 @@ def test_td64arr_sub_periodlike(self, box_with_array, tdi_freq, pi_freq): # TODO: parametrize over box for pi? tdi = tm.box_expected(tdi, box_with_array) - with pytest.raises(TypeError): + msg = "cannot subtract|unsupported operand type" + with pytest.raises(TypeError, match=msg): tdi - pi # FIXME: don't leave commented-out @@ -1034,9 +1042,9 @@ def test_td64arr_sub_periodlike(self, box_with_array, tdi_freq, pi_freq): # pi - tdi # GH#13078 subtraction of Period scalar not supported - with pytest.raises(TypeError): + with pytest.raises(TypeError, match=msg): tdi - pi[0] - with pytest.raises(TypeError): + with pytest.raises(TypeError, match=msg): pi[0] - tdi @pytest.mark.parametrize( @@ -1499,16 +1507,17 @@ def test_td64arr_addsub_anchored_offset_arraylike(self, obox, box_with_array): # addition/subtraction ops with anchored offsets should issue # a PerformanceWarning and _then_ raise a TypeError. - with pytest.raises(TypeError): + msg = "has incorrect type|cannot add the type MonthEnd" + with pytest.raises(TypeError, match=msg): with tm.assert_produces_warning(PerformanceWarning): tdi + anchored - with pytest.raises(TypeError): + with pytest.raises(TypeError, match=msg): with tm.assert_produces_warning(PerformanceWarning): anchored + tdi - with pytest.raises(TypeError): + with pytest.raises(TypeError, match=msg): with tm.assert_produces_warning(PerformanceWarning): tdi - anchored - with pytest.raises(TypeError): + with pytest.raises(TypeError, match=msg): with tm.assert_produces_warning(PerformanceWarning): anchored - tdi @@ -1533,7 +1542,8 @@ def test_td64arr_add_sub_object_array(self, box_with_array): expected = tm.box_expected(expected, box_with_array) tm.assert_equal(result, expected) - with pytest.raises(TypeError): + msg = "unsupported operand type|cannot subtract a datelike" + with pytest.raises(TypeError, match=msg): with tm.assert_produces_warning(warn): tdarr - other @@ -1588,7 +1598,8 @@ def test_td64arr_mul_int(self, box_with_array): def test_td64arr_mul_tdlike_scalar_raises(self, two_hours, box_with_array): rng = timedelta_range("1 days", "10 days", name="foo") rng = tm.box_expected(rng, box_with_array) - with pytest.raises(TypeError): + msg = "argument must be an integer|cannot use operands with types dtype" + with pytest.raises(TypeError, match=msg): rng * two_hours def test_tdi_mul_int_array_zerodim(self, box_with_array): @@ -1777,12 +1788,13 @@ def test_tdarr_div_length_mismatch(self, box_with_array): mismatched = [1, 2, 3, 4] rng = tm.box_expected(rng, box_with_array) + msg = "Cannot divide vectors|Unable to coerce to Series" for obj in [mismatched, mismatched[:2]]: # one shorter, one longer for other in [obj, np.array(obj), pd.Index(obj)]: - with pytest.raises(ValueError): + with pytest.raises(ValueError, match=msg): rng / other - with pytest.raises(ValueError): + with pytest.raises(ValueError, match=msg): other / rng # ------------------------------------------------------------------ @@ -1908,7 +1920,8 @@ def test_td64arr_mod_int(self, box_with_array): result = tdarr % 2 tm.assert_equal(result, expected) - with pytest.raises(TypeError): + msg = "Cannot divide int by" + with pytest.raises(TypeError, match=msg): 2 % tdarr if box_with_array is pd.DataFrame: @@ -1957,15 +1970,21 @@ def test_td64arr_mul_tdscalar_invalid(self, box_with_array, scalar_td): def test_td64arr_mul_too_short_raises(self, box_with_array): idx = TimedeltaIndex(np.arange(5, dtype="int64")) idx = tm.box_expected(idx, box_with_array) - with pytest.raises(TypeError): + msg = ( + "cannot use operands with types dtype|" + "Cannot multiply with unequal lengths|" + "Unable to coerce to Series" + ) + with pytest.raises(TypeError, match=msg): idx * idx[:3] - with pytest.raises(ValueError): + with pytest.raises(ValueError, match=msg): idx * np.array([1, 2]) def test_td64arr_mul_td64arr_raises(self, box_with_array): idx = TimedeltaIndex(np.arange(5, dtype="int64")) idx = tm.box_expected(idx, box_with_array) - with pytest.raises(TypeError): + msg = "cannot use operands with types dtype" + with pytest.raises(TypeError, match=msg): idx * idx # ------------------------------------------------------------------ diff --git a/pandas/tests/arrays/interval/test_interval.py b/pandas/tests/arrays/interval/test_interval.py index e046d87780bb4..35eda4a0ec5bc 100644 --- a/pandas/tests/arrays/interval/test_interval.py +++ b/pandas/tests/arrays/interval/test_interval.py @@ -152,7 +152,7 @@ def test_arrow_array(): assert result.equals(expected) # unsupported conversions - with pytest.raises(TypeError): + with pytest.raises(TypeError, match="Not supported to convert IntervalArray"): pa.array(intervals, type="float64") with pytest.raises(TypeError, match="different 'subtype'"):