diff --git a/pandas/core/dtypes/common.py b/pandas/core/dtypes/common.py index f5997a13e785d..b4b7fb36ee4d0 100644 --- a/pandas/core/dtypes/common.py +++ b/pandas/core/dtypes/common.py @@ -188,7 +188,9 @@ def ensure_python_int(value: Union[int, np.integer]) -> int: TypeError: if the value isn't an int or can't be converted to one. """ if not is_scalar(value): - raise TypeError(f"Value needs to be a scalar value, was type {type(value)}") + raise TypeError( + f"Value needs to be a scalar value, was type {type(value).__name__}" + ) try: new_value = int(value) assert new_value == value diff --git a/pandas/tests/groupby/test_groupby.py b/pandas/tests/groupby/test_groupby.py index 5662d41e19885..b8d8f56512a69 100644 --- a/pandas/tests/groupby/test_groupby.py +++ b/pandas/tests/groupby/test_groupby.py @@ -1765,7 +1765,7 @@ def test_tuple_as_grouping(): } ) - with pytest.raises(KeyError): + with pytest.raises(KeyError, match=r"('a', 'b')"): df[["a", "b", "c"]].groupby(("a", "b")) result = df.groupby(("a", "b"))["c"].sum() diff --git a/pandas/tests/groupby/test_timegrouper.py b/pandas/tests/groupby/test_timegrouper.py index 6b8bd9e805a0c..7cac13efb71f3 100644 --- a/pandas/tests/groupby/test_timegrouper.py +++ b/pandas/tests/groupby/test_timegrouper.py @@ -214,7 +214,7 @@ def test_timegrouper_with_reg_groups(self): result = df.groupby([pd.Grouper(freq="1M", level=0), "Buyer"]).sum() tm.assert_frame_equal(result, expected) - with pytest.raises(ValueError): + with pytest.raises(ValueError, match="The level foo is not valid"): df.groupby([pd.Grouper(freq="1M", level="foo"), "Buyer"]).sum() # multi names @@ -235,7 +235,8 @@ def test_timegrouper_with_reg_groups(self): tm.assert_frame_equal(result, expected) # error as we have both a level and a name! - with pytest.raises(ValueError): + msg = "The Grouper cannot specify both a key and a level!" + with pytest.raises(ValueError, match=msg): df.groupby( [pd.Grouper(freq="1M", key="Date", level="Date"), "Buyer"] ).sum() diff --git a/pandas/tests/indexes/datetimes/test_to_period.py b/pandas/tests/indexes/datetimes/test_to_period.py index ddbb43787abb4..7b75e676a2c12 100644 --- a/pandas/tests/indexes/datetimes/test_to_period.py +++ b/pandas/tests/indexes/datetimes/test_to_period.py @@ -147,7 +147,8 @@ def test_to_period_tz_utc_offset_consistency(self, tz): def test_to_period_nofreq(self): idx = DatetimeIndex(["2000-01-01", "2000-01-02", "2000-01-04"]) - with pytest.raises(ValueError): + msg = "You must pass a freq argument as current index has none." + with pytest.raises(ValueError, match=msg): idx.to_period() idx = DatetimeIndex(["2000-01-01", "2000-01-02", "2000-01-03"], freq="infer") diff --git a/pandas/tests/indexes/multi/test_compat.py b/pandas/tests/indexes/multi/test_compat.py index ef549beccda5d..9273de9c20412 100644 --- a/pandas/tests/indexes/multi/test_compat.py +++ b/pandas/tests/indexes/multi/test_compat.py @@ -37,7 +37,11 @@ def test_logical_compat(idx, method): def test_boolean_context_compat(idx): - with pytest.raises(ValueError): + msg = ( + "The truth value of a MultiIndex is ambiguous. " + r"Use a.empty, a.bool\(\), a.item\(\), a.any\(\) or a.all\(\)." + ) + with pytest.raises(ValueError, match=msg): bool(idx) diff --git a/pandas/tests/indexes/multi/test_duplicates.py b/pandas/tests/indexes/multi/test_duplicates.py index 433b631ab9472..e48731b9c8099 100644 --- a/pandas/tests/indexes/multi/test_duplicates.py +++ b/pandas/tests/indexes/multi/test_duplicates.py @@ -83,12 +83,14 @@ def test_get_unique_index(idx, dropna): def test_duplicate_multiindex_codes(): # GH 17464 # Make sure that a MultiIndex with duplicate levels throws a ValueError - with pytest.raises(ValueError): + msg = r"Level values must be unique: \[[A', ]+\] on level 0" + with pytest.raises(ValueError, match=msg): mi = MultiIndex([["A"] * 10, range(10)], [[0] * 10, range(10)]) # And that using set_levels with duplicate levels fails mi = MultiIndex.from_arrays([["A", "A", "B", "B", "B"], [1, 2, 1, 2, 3]]) - with pytest.raises(ValueError): + msg = r"Level values must be unique: \[[AB', ]+\] on level 0" + with pytest.raises(ValueError, match=msg): mi.set_levels([["A", "B", "A", "A", "B"], [2, 1, 3, -2, 5]], inplace=True) diff --git a/pandas/tests/indexes/multi/test_format.py b/pandas/tests/indexes/multi/test_format.py index 75499bd79cca0..792dcf4c535e3 100644 --- a/pandas/tests/indexes/multi/test_format.py +++ b/pandas/tests/indexes/multi/test_format.py @@ -58,7 +58,8 @@ def test_repr_with_unicode_data(): def test_repr_roundtrip_raises(): mi = MultiIndex.from_product([list("ab"), range(3)], names=["first", "second"]) - with pytest.raises(TypeError): + msg = "Must pass both levels and codes" + with pytest.raises(TypeError, match=msg): eval(repr(mi)) diff --git a/pandas/tests/indexes/multi/test_setops.py b/pandas/tests/indexes/multi/test_setops.py index b24f56afee376..c97704e8a2066 100644 --- a/pandas/tests/indexes/multi/test_setops.py +++ b/pandas/tests/indexes/multi/test_setops.py @@ -209,7 +209,8 @@ def test_difference_sort_incomparable(): # sort=None, the default # MultiIndex.difference deviates here from other difference # implementations in not catching the TypeError - with pytest.raises(TypeError): + msg = "'<' not supported between instances of 'Timestamp' and 'int'" + with pytest.raises(TypeError, match=msg): result = idx.difference(other) # sort=False diff --git a/pandas/tests/indexes/period/test_shift.py b/pandas/tests/indexes/period/test_shift.py index b4c9810f3a554..278bb7f07c679 100644 --- a/pandas/tests/indexes/period/test_shift.py +++ b/pandas/tests/indexes/period/test_shift.py @@ -63,7 +63,8 @@ def test_shift_corner_cases(self): # GH#9903 idx = PeriodIndex([], name="xxx", freq="H") - with pytest.raises(TypeError): + msg = "`freq` argument is not supported for PeriodArray._time_shift" + with pytest.raises(TypeError, match=msg): # period shift doesn't accept freq idx.shift(1, freq="H") diff --git a/pandas/tests/indexes/ranges/test_constructors.py b/pandas/tests/indexes/ranges/test_constructors.py index ba1de6d551d6b..426341a53a5d1 100644 --- a/pandas/tests/indexes/ranges/test_constructors.py +++ b/pandas/tests/indexes/ranges/test_constructors.py @@ -37,28 +37,36 @@ def test_constructor_invalid_args(self): with pytest.raises(TypeError, match=msg): RangeIndex(name="Foo") - # invalid args - for i in [ + # we don't allow on a bare Index + msg = ( + r"Index\(\.\.\.\) must be called with a collection of some " + r"kind, 0 was passed" + ) + with pytest.raises(TypeError, match=msg): + Index(0, 1000) + + @pytest.mark.parametrize( + "args", + [ Index(["a", "b"]), Series(["a", "b"]), np.array(["a", "b"]), [], - "foo", - datetime(2000, 1, 1, 0, 0), np.arange(0, 10), np.array([1]), [1], - ]: - with pytest.raises(TypeError): - RangeIndex(i) + ], + ) + def test_constructor_additional_invalid_args(self, args): + msg = f"Value needs to be a scalar value, was type {type(args).__name__}" + with pytest.raises(TypeError, match=msg): + RangeIndex(args) - # we don't allow on a bare Index - msg = ( - r"Index\(\.\.\.\) must be called with a collection of some " - r"kind, 0 was passed" - ) + @pytest.mark.parametrize("args", ["foo", datetime(2000, 1, 1, 0, 0)]) + def test_constructor_invalid_args_wrong_type(self, args): + msg = f"Wrong type {type(args)} for value {args}" with pytest.raises(TypeError, match=msg): - Index(0, 1000) + RangeIndex(args) def test_constructor_same(self): @@ -81,7 +89,7 @@ def test_constructor_same(self): def test_constructor_range(self): - msg = "Value needs to be a scalar value, was type " + msg = "Value needs to be a scalar value, was type range" with pytest.raises(TypeError, match=msg): result = RangeIndex(range(1, 5, 2)) diff --git a/pandas/tests/indexes/ranges/test_range.py b/pandas/tests/indexes/ranges/test_range.py index 61ac937f5fda0..430004e2a10b9 100644 --- a/pandas/tests/indexes/ranges/test_range.py +++ b/pandas/tests/indexes/ranges/test_range.py @@ -304,14 +304,19 @@ def test_nbytes(self): i2 = RangeIndex(0, 10) assert i.nbytes == i2.nbytes - def test_cant_or_shouldnt_cast(self): - # can't - with pytest.raises(TypeError): - RangeIndex("foo", "bar", "baz") - - # shouldn't - with pytest.raises(TypeError): - RangeIndex("0", "1", "2") + @pytest.mark.parametrize( + "start,stop,step", + [ + # can't + ("foo", "bar", "baz"), + # shouldn't + ("0", "1", "2"), + ], + ) + def test_cant_or_shouldnt_cast(self, start, stop, step): + msg = f"Wrong type {type(start)} for value {start}" + with pytest.raises(TypeError, match=msg): + RangeIndex(start, stop, step) def test_view_index(self): index = self.create_index() @@ -350,7 +355,8 @@ def test_take_fill_value(self): with pytest.raises(ValueError, match=msg): idx.take(np.array([1, 0, -5]), fill_value=True) - with pytest.raises(IndexError): + msg = "index -5 is out of bounds for (axis 0 with )?size 3" + with pytest.raises(IndexError, match=msg): idx.take(np.array([1, -5])) def test_print_unicode_columns(self): diff --git a/pandas/tests/indexes/test_base.py b/pandas/tests/indexes/test_base.py index 5bdbc18769ce5..facf6d21caea7 100644 --- a/pandas/tests/indexes/test_base.py +++ b/pandas/tests/indexes/test_base.py @@ -2263,7 +2263,8 @@ def test_contains_method_removed(self, indices): if isinstance(indices, pd.IntervalIndex): indices.contains(1) else: - with pytest.raises(AttributeError): + msg = f"'{type(indices).__name__}' object has no attribute 'contains'" + with pytest.raises(AttributeError, match=msg): indices.contains(1) diff --git a/pandas/tests/indexes/test_frozen.py b/pandas/tests/indexes/test_frozen.py index 2e53e29c3fab1..cde3fc00eaaaa 100644 --- a/pandas/tests/indexes/test_frozen.py +++ b/pandas/tests/indexes/test_frozen.py @@ -17,7 +17,8 @@ def check_mutable_error(self, *args, **kwargs): # Pass whatever function you normally would to pytest.raises # (after the Exception kind). mutable_regex = re.compile("does not support mutable operations") - with pytest.raises(TypeError): + msg = "'(_s)?re.(SRE_)?Pattern' object is not callable" + with pytest.raises(TypeError, match=msg): mutable_regex(*args, **kwargs) def test_no_mutable_funcs(self): diff --git a/pandas/tests/indexes/test_numeric.py b/pandas/tests/indexes/test_numeric.py index 23877c2c7607a..ecc96562bd0c0 100644 --- a/pandas/tests/indexes/test_numeric.py +++ b/pandas/tests/indexes/test_numeric.py @@ -506,7 +506,8 @@ def test_take_fill_value(self): with pytest.raises(ValueError, match=msg): idx.take(np.array([1, 0, -5]), fill_value=True) - with pytest.raises(IndexError): + msg = "index -5 is out of bounds for (axis 0 with )?size 3" + with pytest.raises(IndexError, match=msg): idx.take(np.array([1, -5])) @@ -645,7 +646,8 @@ def test_take_fill_value(self): with pytest.raises(ValueError, match=msg): idx.take(np.array([1, 0, -5]), fill_value=True) - with pytest.raises(IndexError): + msg = "index -5 is out of bounds for (axis 0 with )?size 3" + with pytest.raises(IndexError, match=msg): idx.take(np.array([1, -5])) def test_slice_keep_name(self): diff --git a/pandas/tests/indexes/timedeltas/test_constructors.py b/pandas/tests/indexes/timedeltas/test_constructors.py index 8e54561df1624..623b0d80a73dc 100644 --- a/pandas/tests/indexes/timedeltas/test_constructors.py +++ b/pandas/tests/indexes/timedeltas/test_constructors.py @@ -168,7 +168,11 @@ def test_constructor_coverage(self): with pytest.raises(TypeError, match=msg): timedelta_range(start="1 days", periods="foo", freq="D") - with pytest.raises(TypeError): + msg = ( + r"TimedeltaIndex\(\) must be called with a collection of some kind," + " '1 days' was passed" + ) + with pytest.raises(TypeError, match=msg): TimedeltaIndex("1 days") # generator expression @@ -220,5 +224,6 @@ def test_constructor_no_precision_raises(self): pd.Index(["2000"], dtype="timedelta64") def test_constructor_wrong_precision_raises(self): - with pytest.raises(ValueError): + msg = r"dtype timedelta64\[us\] cannot be converted to timedelta64\[ns\]" + with pytest.raises(ValueError, match=msg): pd.TimedeltaIndex(["2000"], dtype="timedelta64[us]") diff --git a/pandas/tests/indexes/timedeltas/test_indexing.py b/pandas/tests/indexes/timedeltas/test_indexing.py index 5dec799832291..e6fa90b535ac3 100644 --- a/pandas/tests/indexes/timedeltas/test_indexing.py +++ b/pandas/tests/indexes/timedeltas/test_indexing.py @@ -184,7 +184,8 @@ def test_take_fill_value(self): with pytest.raises(ValueError, match=msg): idx.take(np.array([1, 0, -5]), fill_value=True) - with pytest.raises(IndexError): + msg = "index -5 is out of bounds for (axis 0 with )?size 3" + with pytest.raises(IndexError, match=msg): idx.take(np.array([1, -5])) diff --git a/pandas/tests/indexes/timedeltas/test_shift.py b/pandas/tests/indexes/timedeltas/test_shift.py index 98933ff0423ab..c02aa71d97aac 100644 --- a/pandas/tests/indexes/timedeltas/test_shift.py +++ b/pandas/tests/indexes/timedeltas/test_shift.py @@ -71,5 +71,5 @@ def test_tdi_shift_nonstandard_freq(self): def test_shift_no_freq(self): # GH#19147 tdi = TimedeltaIndex(["1 days 01:00:00", "2 days 01:00:00"], freq=None) - with pytest.raises(NullFrequencyError): + with pytest.raises(NullFrequencyError, match="Cannot shift with no freq"): tdi.shift(2) diff --git a/pandas/tests/indexing/multiindex/test_setitem.py b/pandas/tests/indexing/multiindex/test_setitem.py index 1e641760f7e8d..1f19244cf76d3 100644 --- a/pandas/tests/indexing/multiindex/test_setitem.py +++ b/pandas/tests/indexing/multiindex/test_setitem.py @@ -137,7 +137,8 @@ def test_multiindex_setitem(self): tm.assert_frame_equal(df.loc[["bar"]], expected) # raise because these have differing levels - with pytest.raises(TypeError): + msg = "cannot align on a multi-index with out specifying the join levels" + with pytest.raises(TypeError, match=msg): df.loc["bar"] *= 2 # from SO @@ -203,10 +204,14 @@ def test_multiindex_assignment(self): tm.assert_series_equal(df.loc[4, "c"], exp) # invalid assignments - with pytest.raises(ValueError): + msg = ( + "cannot set using a multi-index selection indexer " + "with a different length than the value" + ) + with pytest.raises(ValueError, match=msg): df.loc[4, "c"] = [0, 1, 2, 3] - with pytest.raises(ValueError): + with pytest.raises(ValueError, match=msg): df.loc[4, "c"] = [0] # groupby example diff --git a/pandas/tests/indexing/multiindex/test_slice.py b/pandas/tests/indexing/multiindex/test_slice.py index 6fa9d3bd2cdbb..f367a92d0b006 100644 --- a/pandas/tests/indexing/multiindex/test_slice.py +++ b/pandas/tests/indexing/multiindex/test_slice.py @@ -111,7 +111,11 @@ def test_per_axis_per_level_getitem(self): expected = df.iloc[[2, 3]] tm.assert_frame_equal(result, expected) - with pytest.raises(ValueError): + msg = ( + "cannot index with a boolean indexer " + "that is not the same length as the index" + ) + with pytest.raises(ValueError, match=msg): df.loc[(slice(None), np.array([True, False])), :] # ambiguous notation @@ -411,7 +415,11 @@ def test_per_axis_per_level_doc_examples(self): tm.assert_frame_equal(result, expected) # not sorted - with pytest.raises(UnsortedIndexError): + msg = ( + "MultiIndex slicing requires the index to be lexsorted: " + r"slicing on levels \[1\], lexsort depth 1" + ) + with pytest.raises(UnsortedIndexError, match=msg): df.loc["A1", ("a", slice("foo"))] # GH 16734: not sorted, but no real slicing @@ -480,14 +488,10 @@ def test_loc_axis_arguments(self): tm.assert_frame_equal(result, expected) # invalid axis - with pytest.raises(ValueError): - df.loc(axis=-1)[:, :, ["C1", "C3"]] - - with pytest.raises(ValueError): - df.loc(axis=2)[:, :, ["C1", "C3"]] - - with pytest.raises(ValueError): - df.loc(axis="foo")[:, :, ["C1", "C3"]] + for i in [-1, 2, "foo"]: + msg = f"No axis named {i} for object type DataFrame" + with pytest.raises(ValueError, match=msg): + df.loc(axis=i)[:, :, ["C1", "C3"]] def test_loc_axis_single_level_multi_col_indexing_multiindex_col_df(self): @@ -628,12 +632,14 @@ def test_per_axis_per_level_setitem(self): # not enough values df = df_orig.copy() - with pytest.raises(ValueError): + msg = "setting an array element with a sequence." + with pytest.raises(ValueError, match=msg): df.loc[(slice(None), 1), (slice(None), ["foo"])] = np.array( [[100], [100, 100]], dtype="int64" ) - with pytest.raises(ValueError): + msg = "Must have equal len keys and value when setting with an iterable" + with pytest.raises(ValueError, match=msg): df.loc[(slice(None), 1), (slice(None), ["foo"])] = np.array( [100, 100, 100, 100], dtype="int64" ) diff --git a/pandas/tests/indexing/test_coercion.py b/pandas/tests/indexing/test_coercion.py index bea8eae9bb850..c390347236ad3 100644 --- a/pandas/tests/indexing/test_coercion.py +++ b/pandas/tests/indexing/test_coercion.py @@ -297,7 +297,8 @@ def test_setitem_index_object(self, val, exp_dtype): if exp_dtype is IndexError: temp = obj.copy() - with pytest.raises(exp_dtype): + msg = "index 5 is out of bounds for axis 0 with size 4" + with pytest.raises(exp_dtype, match=msg): temp[5] = 5 else: exp_index = pd.Index(list("abcd") + [val])