diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 6033bda99e8c8..73ac14f1ed5ce 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -272,13 +272,6 @@ repos: language: python types: [rst] files: ^doc/source/(development|reference)/ - - id: unwanted-patterns-bare-pytest-raises - name: Check for use of bare pytest raises - language: python - entry: python scripts/validate_unwanted_patterns.py --validation-type="bare_pytest_raises" - types: [python] - files: ^pandas/tests/ - exclude: ^pandas/tests/extension/ - id: unwanted-patterns-private-function-across-module name: Check for use of private functions across modules language: python diff --git a/pandas/conftest.py b/pandas/conftest.py index 4a3fb5c2916c6..16b437b9a4723 100644 --- a/pandas/conftest.py +++ b/pandas/conftest.py @@ -1971,6 +1971,6 @@ def warsaw(request) -> str: return request.param -@pytest.fixture() +@pytest.fixture def arrow_string_storage(): return ("pyarrow", "pyarrow_numpy") diff --git a/pandas/tests/arithmetic/test_datetime64.py b/pandas/tests/arithmetic/test_datetime64.py index b4e8d09c18163..75259cb7e2f05 100644 --- a/pandas/tests/arithmetic/test_datetime64.py +++ b/pandas/tests/arithmetic/test_datetime64.py @@ -1385,7 +1385,6 @@ def test_dt64arr_add_sub_relativedelta_offsets(self, box_with_array, unit): "SemiMonthBegin", "Week", ("Week", {"weekday": 3}), - "Week", ("Week", {"weekday": 6}), "BusinessDay", "BDay", diff --git a/pandas/tests/arrays/categorical/test_api.py b/pandas/tests/arrays/categorical/test_api.py index 41d9db7335957..cff8afaa17516 100644 --- a/pandas/tests/arrays/categorical/test_api.py +++ b/pandas/tests/arrays/categorical/test_api.py @@ -291,12 +291,12 @@ def test_set_categories(self): (["a", "b", "c"], ["a", "b"], ["a", "b"]), (["a", "b", "c"], ["a", "b"], ["b", "a"]), (["b", "a", "c"], ["a", "b"], ["a", "b"]), - (["b", "a", "c"], ["a", "b"], ["a", "b"]), + (["b", "a", "c"], ["a", "b"], ["b", "a"]), # Introduce NaNs (["a", "b", "c"], ["a", "b"], ["a"]), (["a", "b", "c"], ["a", "b"], ["b"]), (["b", "a", "c"], ["a", "b"], ["a"]), - (["b", "a", "c"], ["a", "b"], ["a"]), + (["b", "a", "c"], ["a", "b"], ["b"]), # No overlap (["a", "b", "c"], ["a", "b"], ["d", "e"]), ], diff --git a/pandas/tests/arrays/categorical/test_dtypes.py b/pandas/tests/arrays/categorical/test_dtypes.py index f2f2851c22794..ec1d501ddba16 100644 --- a/pandas/tests/arrays/categorical/test_dtypes.py +++ b/pandas/tests/arrays/categorical/test_dtypes.py @@ -73,12 +73,12 @@ def test_set_dtype_new_categories(self): (["a", "b", "c"], ["a", "b"], ["a", "b"]), (["a", "b", "c"], ["a", "b"], ["b", "a"]), (["b", "a", "c"], ["a", "b"], ["a", "b"]), - (["b", "a", "c"], ["a", "b"], ["a", "b"]), + (["b", "a", "c"], ["a", "b"], ["b", "a"]), # Introduce NaNs (["a", "b", "c"], ["a", "b"], ["a"]), (["a", "b", "c"], ["a", "b"], ["b"]), (["b", "a", "c"], ["a", "b"], ["a"]), - (["b", "a", "c"], ["a", "b"], ["a"]), + (["b", "a", "c"], ["a", "b"], ["b"]), # No overlap (["a", "b", "c"], ["a", "b"], ["d", "e"]), ], diff --git a/pandas/tests/arrays/masked/test_function.py b/pandas/tests/arrays/masked/test_function.py index 4c7bd6e293ef4..d5ea60ecb754d 100644 --- a/pandas/tests/arrays/masked/test_function.py +++ b/pandas/tests/arrays/masked/test_function.py @@ -21,7 +21,7 @@ def data(request): return request.param -@pytest.fixture() +@pytest.fixture def numpy_dtype(data): """ Fixture returning numpy dtype from 'data' input array. diff --git a/pandas/tests/arrays/sparse/test_arithmetics.py b/pandas/tests/arrays/sparse/test_arithmetics.py index ffc93b4e4f176..f84d03e851621 100644 --- a/pandas/tests/arrays/sparse/test_arithmetics.py +++ b/pandas/tests/arrays/sparse/test_arithmetics.py @@ -433,9 +433,6 @@ def test_ufuncs(ufunc, arr): [ (SparseArray([0, 0, 0]), np.array([0, 1, 2])), (SparseArray([0, 0, 0], fill_value=1), np.array([0, 1, 2])), - (SparseArray([0, 0, 0], fill_value=1), np.array([0, 1, 2])), - (SparseArray([0, 0, 0], fill_value=1), np.array([0, 1, 2])), - (SparseArray([0, 0, 0], fill_value=1), np.array([0, 1, 2])), ], ) @pytest.mark.parametrize("ufunc", [np.add, np.greater]) diff --git a/pandas/tests/arrays/string_/test_string_arrow.py b/pandas/tests/arrays/string_/test_string_arrow.py index d7811b6fed883..405c1c217b04d 100644 --- a/pandas/tests/arrays/string_/test_string_arrow.py +++ b/pandas/tests/arrays/string_/test_string_arrow.py @@ -220,22 +220,22 @@ def test_setitem_invalid_indexer_raises(): arr = ArrowStringArray(pa.array(list("abcde"))) - with pytest.raises(IndexError, match=None): + with tm.external_error_raised(IndexError): arr[5] = "foo" - with pytest.raises(IndexError, match=None): + with tm.external_error_raised(IndexError): arr[-6] = "foo" - with pytest.raises(IndexError, match=None): + with tm.external_error_raised(IndexError): arr[[0, 5]] = "foo" - with pytest.raises(IndexError, match=None): + with tm.external_error_raised(IndexError): arr[[0, -6]] = "foo" - with pytest.raises(IndexError, match=None): + with tm.external_error_raised(IndexError): arr[[True, True, False]] = "foo" - with pytest.raises(ValueError, match=None): + with tm.external_error_raised(ValueError): arr[[0, 1]] = ["foo", "bar", "baz"] diff --git a/pandas/tests/arrays/test_array.py b/pandas/tests/arrays/test_array.py index 96263f498935b..a84fefebf044c 100644 --- a/pandas/tests/arrays/test_array.py +++ b/pandas/tests/arrays/test_array.py @@ -29,7 +29,7 @@ ) -@pytest.mark.parametrize("dtype_unit", ["M8[h]", "M8[m]", "m8[h]", "M8[m]"]) +@pytest.mark.parametrize("dtype_unit", ["M8[h]", "M8[m]", "m8[h]"]) def test_dt64_array(dtype_unit): # PR 53817 dtype_var = np.dtype(dtype_unit) diff --git a/pandas/tests/copy_view/test_internals.py b/pandas/tests/copy_view/test_internals.py index 615b024bd06bf..400fb8e03c18c 100644 --- a/pandas/tests/copy_view/test_internals.py +++ b/pandas/tests/copy_view/test_internals.py @@ -83,7 +83,6 @@ def test_switch_options(): ([0, 1, 2], np.array([[-1, -2, -3], [-4, -5, -6], [-4, -5, -6]]).T), ([1, 2], np.array([[-1, -2, -3], [-4, -5, -6]]).T), ([1, 3], np.array([[-1, -2, -3], [-4, -5, -6]]).T), - ([1, 3], np.array([[-1, -2, -3], [-4, -5, -6]]).T), ], ) def test_iset_splits_blocks_inplace(using_copy_on_write, locs, arr, dtype): diff --git a/pandas/tests/dtypes/test_missing.py b/pandas/tests/dtypes/test_missing.py index 7105755df6f88..c205f35b0ced8 100644 --- a/pandas/tests/dtypes/test_missing.py +++ b/pandas/tests/dtypes/test_missing.py @@ -531,7 +531,6 @@ def test_array_equivalent_different_dtype_but_equal(): (fix_now, fix_utcnow), (fix_now.to_datetime64(), fix_utcnow), (fix_now.to_pydatetime(), fix_utcnow), - (fix_now, fix_utcnow), (fix_now.to_datetime64(), fix_utcnow.to_pydatetime()), (fix_now.to_pydatetime(), fix_utcnow.to_pydatetime()), ], diff --git a/pandas/tests/extension/base/dim2.py b/pandas/tests/extension/base/dim2.py index 132cda5a94ed0..4da9fe8917d55 100644 --- a/pandas/tests/extension/base/dim2.py +++ b/pandas/tests/extension/base/dim2.py @@ -90,9 +90,9 @@ def test_reshape(self, data): assert arr2d.shape == (data.size, 1) assert len(arr2d) == len(data) - with pytest.raises(ValueError): + with tm.external_error_raised(ValueError): data.reshape((data.size, 2)) - with pytest.raises(ValueError): + with tm.external_error_raised(ValueError): data.reshape(data.size, 2) def test_getitem_2d(self, data): diff --git a/pandas/tests/extension/base/getitem.py b/pandas/tests/extension/base/getitem.py index 5f0c1b960a475..1f89c7ad9d4e4 100644 --- a/pandas/tests/extension/base/getitem.py +++ b/pandas/tests/extension/base/getitem.py @@ -394,7 +394,7 @@ def test_take_non_na_fill_value(self, data_missing): tm.assert_extension_array_equal(result, expected) def test_take_pandas_style_negative_raises(self, data, na_value): - with pytest.raises(ValueError, match=""): + with tm.external_error_raised(ValueError): data.take([0, -2], fill_value=na_value, allow_fill=True) @pytest.mark.parametrize("allow_fill", [True, False]) diff --git a/pandas/tests/extension/base/setitem.py b/pandas/tests/extension/base/setitem.py index 4a2942776b25e..ba756b471eb8b 100644 --- a/pandas/tests/extension/base/setitem.py +++ b/pandas/tests/extension/base/setitem.py @@ -209,7 +209,8 @@ def test_setitem_integer_array(self, data, idx, box_in_series): [0, 1, 2, pd.NA], True, marks=pytest.mark.xfail(reason="GH-31948") ), (pd.array([0, 1, 2, pd.NA], dtype="Int64"), False), - (pd.array([0, 1, 2, pd.NA], dtype="Int64"), False), + # TODO: change False to True? + (pd.array([0, 1, 2, pd.NA], dtype="Int64"), False), # noqa: PT014 ], ids=["list-False", "list-True", "integer-array-False", "integer-array-True"], ) @@ -332,7 +333,7 @@ def test_setitem_loc_iloc_slice(self, data): def test_setitem_slice_mismatch_length_raises(self, data): arr = data[:5] - with pytest.raises(ValueError): + with tm.external_error_raised(ValueError): arr[:1] = arr[:2] def test_setitem_slice_array(self, data): @@ -342,7 +343,7 @@ def test_setitem_slice_array(self, data): def test_setitem_scalar_key_sequence_raise(self, data): arr = data[:5].copy() - with pytest.raises(ValueError): + with tm.external_error_raised(ValueError): arr[0] = arr[[0, 1]] def test_setitem_preserves_views(self, data): diff --git a/pandas/tests/extension/json/test_json.py b/pandas/tests/extension/json/test_json.py index 9de4f17a27333..50f2fe03cfa13 100644 --- a/pandas/tests/extension/json/test_json.py +++ b/pandas/tests/extension/json/test_json.py @@ -355,7 +355,7 @@ def test_setitem_integer_array(self, data, idx, box_in_series, request): [0, 1, 2, pd.NA], True, marks=pytest.mark.xfail(reason="GH-31948") ), (pd.array([0, 1, 2, pd.NA], dtype="Int64"), False), - (pd.array([0, 1, 2, pd.NA], dtype="Int64"), False), + (pd.array([0, 1, 2, pd.NA], dtype="Int64"), True), ], ids=["list-False", "list-True", "integer-array-False", "integer-array-True"], ) diff --git a/pandas/tests/extension/test_numpy.py b/pandas/tests/extension/test_numpy.py index 9a0cb67a87f30..0893c6231197e 100644 --- a/pandas/tests/extension/test_numpy.py +++ b/pandas/tests/extension/test_numpy.py @@ -373,19 +373,6 @@ def test_setitem_mask(self, data, mask, box_in_series): def test_setitem_integer_array(self, data, idx, box_in_series): super().test_setitem_integer_array(data, idx, box_in_series) - @pytest.mark.parametrize( - "idx, box_in_series", - [ - ([0, 1, 2, pd.NA], False), - pytest.param([0, 1, 2, pd.NA], True, marks=pytest.mark.xfail), - (pd.array([0, 1, 2, pd.NA], dtype="Int64"), False), - (pd.array([0, 1, 2, pd.NA], dtype="Int64"), False), - ], - ids=["list-False", "list-True", "integer-array-False", "integer-array-True"], - ) - def test_setitem_integer_with_missing_raises(self, data, idx, box_in_series): - super().test_setitem_integer_with_missing_raises(data, idx, box_in_series) - @skip_nested def test_setitem_slice(self, data, box_in_series): super().test_setitem_slice(data, box_in_series) diff --git a/pandas/tests/extension/test_sparse.py b/pandas/tests/extension/test_sparse.py index 03f179fdd261e..2efcc192aa15b 100644 --- a/pandas/tests/extension/test_sparse.py +++ b/pandas/tests/extension/test_sparse.py @@ -70,7 +70,7 @@ def gen(count): for _ in range(count): yield SparseArray(make_data(request.param), fill_value=request.param) - yield gen + return gen @pytest.fixture(params=[0, np.nan]) diff --git a/pandas/tests/frame/methods/test_astype.py b/pandas/tests/frame/methods/test_astype.py index eab8dbd2787f7..e7f2c410bf4ac 100644 --- a/pandas/tests/frame/methods/test_astype.py +++ b/pandas/tests/frame/methods/test_astype.py @@ -867,7 +867,7 @@ class IntegerArrayNoCopy(pd.core.arrays.IntegerArray): # GH 42501 def copy(self): - assert False + raise NotImplementedError class Int16DtypeNoCopy(pd.Int16Dtype): diff --git a/pandas/tests/frame/methods/test_explode.py b/pandas/tests/frame/methods/test_explode.py index 5cd54db62d783..ca9764c023244 100644 --- a/pandas/tests/frame/methods/test_explode.py +++ b/pandas/tests/frame/methods/test_explode.py @@ -38,10 +38,6 @@ def test_error(): [], "column must be nonempty", ), - ( - list("AC"), - "columns must have matching element counts", - ), ], ) def test_error_multi_columns(input_subset, error_message): diff --git a/pandas/tests/frame/methods/test_filter.py b/pandas/tests/frame/methods/test_filter.py index 9d5e6876bb08c..382615aaef627 100644 --- a/pandas/tests/frame/methods/test_filter.py +++ b/pandas/tests/frame/methods/test_filter.py @@ -100,7 +100,6 @@ def test_filter_regex_search(self, float_frame): @pytest.mark.parametrize( "name,expected", [ - ("a", DataFrame({"a": [1, 2]})), ("a", DataFrame({"a": [1, 2]})), ("あ", DataFrame({"あ": [3, 4]})), ], @@ -112,9 +111,9 @@ def test_filter_unicode(self, name, expected): tm.assert_frame_equal(df.filter(like=name), expected) tm.assert_frame_equal(df.filter(regex=name), expected) - @pytest.mark.parametrize("name", ["a", "a"]) - def test_filter_bytestring(self, name): + def test_filter_bytestring(self): # GH13101 + name = "a" df = DataFrame({b"a": [1, 2], b"b": [3, 4]}) expected = DataFrame({b"a": [1, 2]}) diff --git a/pandas/tests/frame/methods/test_reindex.py b/pandas/tests/frame/methods/test_reindex.py index d2ec84bc9371f..2a889efe79064 100644 --- a/pandas/tests/frame/methods/test_reindex.py +++ b/pandas/tests/frame/methods/test_reindex.py @@ -452,19 +452,16 @@ def f(val): ("mid",), ("mid", "btm"), ("mid", "btm", "top"), - ("mid",), ("mid", "top"), ("mid", "top", "btm"), ("btm",), ("btm", "mid"), ("btm", "mid", "top"), - ("btm",), ("btm", "top"), ("btm", "top", "mid"), ("top",), ("top", "mid"), ("top", "mid", "btm"), - ("top",), ("top", "btm"), ("top", "btm", "mid"), ], diff --git a/pandas/tests/frame/methods/test_reset_index.py b/pandas/tests/frame/methods/test_reset_index.py index 9d07b8ab2288f..a77e063b5f353 100644 --- a/pandas/tests/frame/methods/test_reset_index.py +++ b/pandas/tests/frame/methods/test_reset_index.py @@ -27,7 +27,7 @@ import pandas._testing as tm -@pytest.fixture() +@pytest.fixture def multiindex_df(): levels = [["A", ""], ["B", "b"]] return DataFrame([[0, 2], [1, 3]], columns=MultiIndex.from_tuples(levels)) diff --git a/pandas/tests/frame/test_constructors.py b/pandas/tests/frame/test_constructors.py index aefb0377d1bf4..d44de380d243a 100644 --- a/pandas/tests/frame/test_constructors.py +++ b/pandas/tests/frame/test_constructors.py @@ -1555,7 +1555,7 @@ def test_constructor_mixed_type_rows(self): "tuples,lists", [ ((), []), - ((()), []), + (((),), [[]]), (((), ()), [(), ()]), (((), ()), [[], []]), (([], []), [[], []]), diff --git a/pandas/tests/frame/test_query_eval.py b/pandas/tests/frame/test_query_eval.py index a498296e09c52..0a869d8f94f47 100644 --- a/pandas/tests/frame/test_query_eval.py +++ b/pandas/tests/frame/test_query_eval.py @@ -1187,7 +1187,7 @@ def df(self): by backticks. The last two columns cannot be escaped by backticks and should raise a ValueError. """ - yield DataFrame( + return DataFrame( { "A": [1, 2, 3], "B B": [3, 2, 1], diff --git a/pandas/tests/frame/test_reductions.py b/pandas/tests/frame/test_reductions.py index 5aaa11b848be4..fa233619ad3a3 100644 --- a/pandas/tests/frame/test_reductions.py +++ b/pandas/tests/frame/test_reductions.py @@ -1866,7 +1866,6 @@ def test_df_empty_min_count_1(self, opname, dtype, exp_dtype): [ ("sum", "Int8", 0, ("Int32" if is_windows_np2_or_is32 else "Int64")), ("prod", "Int8", 1, ("Int32" if is_windows_np2_or_is32 else "Int64")), - ("prod", "Int8", 1, ("Int32" if is_windows_np2_or_is32 else "Int64")), ("sum", "Int64", 0, "Int64"), ("prod", "Int64", 1, "Int64"), ("sum", "UInt8", 0, ("UInt32" if is_windows_np2_or_is32 else "UInt64")), diff --git a/pandas/tests/groupby/conftest.py b/pandas/tests/groupby/conftest.py index 331dbd85e0f36..2745f7c2b8d0f 100644 --- a/pandas/tests/groupby/conftest.py +++ b/pandas/tests/groupby/conftest.py @@ -92,7 +92,7 @@ def three_group(): ) -@pytest.fixture() +@pytest.fixture def slice_test_df(): data = [ [0, "a", "a0_at_0"], @@ -108,7 +108,7 @@ def slice_test_df(): return df.set_index("Index") -@pytest.fixture() +@pytest.fixture def slice_test_grouped(slice_test_df): return slice_test_df.groupby("Group", as_index=False) diff --git a/pandas/tests/groupby/test_categorical.py b/pandas/tests/groupby/test_categorical.py index a2cc7fd782396..3e1a244a8a72e 100644 --- a/pandas/tests/groupby/test_categorical.py +++ b/pandas/tests/groupby/test_categorical.py @@ -647,7 +647,7 @@ def test_dataframe_categorical_ordered_observed_sort(ordered, observed, sort): f"for (ordered={ordered}, observed={observed}, sort={sort})\n" f"Result:\n{result}" ) - assert False, msg + pytest.fail(msg) def test_datetime(): diff --git a/pandas/tests/groupby/test_groupby_dropna.py b/pandas/tests/groupby/test_groupby_dropna.py index ca097bc2be8bb..768ab2db5cea5 100644 --- a/pandas/tests/groupby/test_groupby_dropna.py +++ b/pandas/tests/groupby/test_groupby_dropna.py @@ -410,7 +410,6 @@ def test_groupby_drop_nan_with_multi_index(): "UInt64", "Int64", "Float32", - "Int64", "Float64", "category", "string", diff --git a/pandas/tests/indexes/datetimelike_/test_sort_values.py b/pandas/tests/indexes/datetimelike_/test_sort_values.py index a2c349c8b0ef6..bfef0faebeebf 100644 --- a/pandas/tests/indexes/datetimelike_/test_sort_values.py +++ b/pandas/tests/indexes/datetimelike_/test_sort_values.py @@ -185,10 +185,6 @@ def test_sort_values_without_freq_timedeltaindex(self): @pytest.mark.parametrize( "index_dates,expected_dates", [ - ( - ["2011-01-01", "2011-01-03", "2011-01-05", "2011-01-02", "2011-01-01"], - ["2011-01-01", "2011-01-01", "2011-01-02", "2011-01-03", "2011-01-05"], - ), ( ["2011-01-01", "2011-01-03", "2011-01-05", "2011-01-02", "2011-01-01"], ["2011-01-01", "2011-01-01", "2011-01-02", "2011-01-03", "2011-01-05"], diff --git a/pandas/tests/indexes/multi/test_constructors.py b/pandas/tests/indexes/multi/test_constructors.py index 8456e6a7acba5..38e0920b7004e 100644 --- a/pandas/tests/indexes/multi/test_constructors.py +++ b/pandas/tests/indexes/multi/test_constructors.py @@ -304,7 +304,6 @@ def test_from_arrays_empty(): (1, 2), ([1], 2), (1, [2]), - "a", ("a",), ("a", "b"), (["a"], "b"), diff --git a/pandas/tests/internals/test_internals.py b/pandas/tests/internals/test_internals.py index c9708bfea7106..7e93a02a03663 100644 --- a/pandas/tests/internals/test_internals.py +++ b/pandas/tests/internals/test_internals.py @@ -1158,7 +1158,6 @@ def test_array_to_slice_conversion(self, arr, slc): [-1], [-1, -2, -3], [-10], - [-1], [-1, 0, 1, 2], [-2, 0, 2, 4], [1, 0, -1], diff --git a/pandas/tests/io/formats/test_css.py b/pandas/tests/io/formats/test_css.py index db436d8283b99..8bf9aa4ac04d3 100644 --- a/pandas/tests/io/formats/test_css.py +++ b/pandas/tests/io/formats/test_css.py @@ -243,7 +243,6 @@ def test_css_none_absent(style, equiv): ("02.54cm", "72pt"), ("25.4mm", "72pt"), ("101.6q", "72pt"), - ("101.6q", "72pt"), ], ) @pytest.mark.parametrize("relative_to", [None, "16pt"]) # invariant to inherited size diff --git a/pandas/tests/io/formats/test_to_latex.py b/pandas/tests/io/formats/test_to_latex.py index 98f1e0245b353..4c8cd4b6a2b8e 100644 --- a/pandas/tests/io/formats/test_to_latex.py +++ b/pandas/tests/io/formats/test_to_latex.py @@ -771,7 +771,7 @@ def df_with_symbols(self): """Dataframe with special characters for testing chars escaping.""" a = "a" b = "b" - yield DataFrame({"co$e^x$": {a: "a", b: "b"}, "co^l1": {a: "a", b: "b"}}) + return DataFrame({"co$e^x$": {a: "a", b: "b"}, "co^l1": {a: "a", b: "b"}}) def test_to_latex_escape_false(self, df_with_symbols): result = df_with_symbols.to_latex(escape=False) @@ -1010,7 +1010,7 @@ class TestToLatexMultiindex: @pytest.fixture def multiindex_frame(self): """Multiindex dataframe for testing multirow LaTeX macros.""" - yield DataFrame.from_dict( + return DataFrame.from_dict( { ("c1", 0): Series({x: x for x in range(4)}), ("c1", 1): Series({x: x + 4 for x in range(4)}), @@ -1023,7 +1023,7 @@ def multiindex_frame(self): @pytest.fixture def multicolumn_frame(self): """Multicolumn dataframe for testing multicolumn LaTeX macros.""" - yield DataFrame( + return DataFrame( { ("c1", 0): {x: x for x in range(5)}, ("c1", 1): {x: x + 5 for x in range(5)}, diff --git a/pandas/tests/io/json/test_json_table_schema.py b/pandas/tests/io/json/test_json_table_schema.py index cc101bb9c8b6d..d5ea470af79d6 100644 --- a/pandas/tests/io/json/test_json_table_schema.py +++ b/pandas/tests/io/json/test_json_table_schema.py @@ -179,7 +179,6 @@ def test_as_json_table_type_string_data(self, str_data): pd.Categorical([1]), pd.Series(pd.Categorical([1])), pd.CategoricalIndex([1]), - pd.Categorical([1]), ], ) def test_as_json_table_type_categorical_data(self, cat_data): diff --git a/pandas/tests/io/parser/common/test_file_buffer_url.py b/pandas/tests/io/parser/common/test_file_buffer_url.py index a7a8d031da215..5e31b4c6b644d 100644 --- a/pandas/tests/io/parser/common/test_file_buffer_url.py +++ b/pandas/tests/io/parser/common/test_file_buffer_url.py @@ -425,7 +425,7 @@ def test_context_manager(all_parsers, datapath): try: with reader: next(reader) - assert False + raise AssertionError except AssertionError: assert reader.handles.handle.closed @@ -446,7 +446,7 @@ def test_context_manageri_user_provided(all_parsers, datapath): try: with reader: next(reader) - assert False + raise AssertionError except AssertionError: assert not reader.handles.handle.closed diff --git a/pandas/tests/io/parser/usecols/test_strings.py b/pandas/tests/io/parser/usecols/test_strings.py index d4ade41d38465..0d51c2cb3cdb4 100644 --- a/pandas/tests/io/parser/usecols/test_strings.py +++ b/pandas/tests/io/parser/usecols/test_strings.py @@ -74,8 +74,7 @@ def test_usecols_with_mixed_encoding_strings(all_parsers, usecols): parser.read_csv(StringIO(data), usecols=usecols) -@pytest.mark.parametrize("usecols", [["あああ", "いい"], ["あああ", "いい"]]) -def test_usecols_with_multi_byte_characters(all_parsers, usecols): +def test_usecols_with_multi_byte_characters(all_parsers): data = """あああ,いい,ううう,ええええ 0.056674973,8,True,a 2.613230982,2,False,b @@ -92,5 +91,5 @@ def test_usecols_with_multi_byte_characters(all_parsers, usecols): } expected = DataFrame(exp_data) - result = parser.read_csv(StringIO(data), usecols=usecols) + result = parser.read_csv(StringIO(data), usecols=["あああ", "いい"]) tm.assert_frame_equal(result, expected) diff --git a/pandas/tests/io/pytables/test_compat.py b/pandas/tests/io/pytables/test_compat.py index b07fb3ddd3ac8..b78a503a2b8a3 100644 --- a/pandas/tests/io/pytables/test_compat.py +++ b/pandas/tests/io/pytables/test_compat.py @@ -36,7 +36,7 @@ def pytables_hdf5_file(tmp_path): t.row[key] = value t.row.append() - yield path, objname, pd.DataFrame(testsamples) + return path, objname, pd.DataFrame(testsamples) class TestReadPyTablesHDF5: diff --git a/pandas/tests/io/test_parquet.py b/pandas/tests/io/test_parquet.py index 8fc02cc7799ed..a6967732cf702 100644 --- a/pandas/tests/io/test_parquet.py +++ b/pandas/tests/io/test_parquet.py @@ -1327,7 +1327,7 @@ def test_use_nullable_dtypes_not_supported(self, fp): def test_close_file_handle_on_read_error(self): with tm.ensure_clean("test.parquet") as path: pathlib.Path(path).write_bytes(b"breakit") - with pytest.raises(Exception, match=""): # Not important which exception + with tm.external_error_raised(Exception): # Not important which exception read_parquet(path, engine="fastparquet") # The next line raises an error on Windows if the file is still open pathlib.Path(path).unlink(missing_ok=False) diff --git a/pandas/tests/io/test_sql.py b/pandas/tests/io/test_sql.py index 6645aefd4f0a7..2ddbbaa1bf17c 100644 --- a/pandas/tests/io/test_sql.py +++ b/pandas/tests/io/test_sql.py @@ -620,13 +620,13 @@ def mysql_pymysql_engine(): def mysql_pymysql_engine_iris(mysql_pymysql_engine, iris_path): create_and_load_iris(mysql_pymysql_engine, iris_path) create_and_load_iris_view(mysql_pymysql_engine) - yield mysql_pymysql_engine + return mysql_pymysql_engine @pytest.fixture def mysql_pymysql_engine_types(mysql_pymysql_engine, types_data): create_and_load_types(mysql_pymysql_engine, types_data, "mysql") - yield mysql_pymysql_engine + return mysql_pymysql_engine @pytest.fixture @@ -667,13 +667,13 @@ def postgresql_psycopg2_engine(): def postgresql_psycopg2_engine_iris(postgresql_psycopg2_engine, iris_path): create_and_load_iris(postgresql_psycopg2_engine, iris_path) create_and_load_iris_view(postgresql_psycopg2_engine) - yield postgresql_psycopg2_engine + return postgresql_psycopg2_engine @pytest.fixture def postgresql_psycopg2_engine_types(postgresql_psycopg2_engine, types_data): create_and_load_types(postgresql_psycopg2_engine, types_data, "postgres") - yield postgresql_psycopg2_engine + return postgresql_psycopg2_engine @pytest.fixture @@ -713,7 +713,7 @@ def postgresql_adbc_iris(postgresql_adbc_conn, iris_path): except mgr.ProgrammingError: # note arrow-adbc issue 1022 conn.rollback() create_and_load_iris_view(conn) - yield conn + return conn @pytest.fixture @@ -730,7 +730,7 @@ def postgresql_adbc_types(postgresql_adbc_conn, types_data): create_and_load_types_postgresql(conn, new_data) - yield conn + return conn @pytest.fixture @@ -784,7 +784,7 @@ def sqlite_str_iris(sqlite_str, iris_path): def sqlite_engine_iris(sqlite_engine, iris_path): create_and_load_iris(sqlite_engine, iris_path) create_and_load_iris_view(sqlite_engine) - yield sqlite_engine + return sqlite_engine @pytest.fixture @@ -805,7 +805,7 @@ def sqlite_str_types(sqlite_str, types_data): @pytest.fixture def sqlite_engine_types(sqlite_engine, types_data): create_and_load_types(sqlite_engine, types_data, "sqlite") - yield sqlite_engine + return sqlite_engine @pytest.fixture @@ -845,7 +845,7 @@ def sqlite_adbc_iris(sqlite_adbc_conn, iris_path): except mgr.ProgrammingError: conn.rollback() create_and_load_iris_view(conn) - yield conn + return conn @pytest.fixture @@ -867,7 +867,7 @@ def sqlite_adbc_types(sqlite_adbc_conn, types_data): create_and_load_types_sqlite3(conn, new_data) conn.commit() - yield conn + return conn @pytest.fixture @@ -881,14 +881,14 @@ def sqlite_buildin(): def sqlite_buildin_iris(sqlite_buildin, iris_path): create_and_load_iris_sqlite3(sqlite_buildin, iris_path) create_and_load_iris_view(sqlite_buildin) - yield sqlite_buildin + return sqlite_buildin @pytest.fixture def sqlite_buildin_types(sqlite_buildin, types_data): types_data = [tuple(entry.values()) for entry in types_data] create_and_load_types_sqlite3(sqlite_buildin, types_data) - yield sqlite_buildin + return sqlite_buildin mysql_connectable = [ diff --git a/pandas/tests/reductions/test_reductions.py b/pandas/tests/reductions/test_reductions.py index 4cdd50d70d078..f370d32d0caa9 100644 --- a/pandas/tests/reductions/test_reductions.py +++ b/pandas/tests/reductions/test_reductions.py @@ -801,7 +801,7 @@ def test_var_masked_array(self, ddof, exp): assert result == result_numpy_dtype assert result == exp - @pytest.mark.parametrize("dtype", ("m8[ns]", "m8[ns]", "M8[ns]", "M8[ns, UTC]")) + @pytest.mark.parametrize("dtype", ("m8[ns]", "M8[ns]", "M8[ns, UTC]")) def test_empty_timeseries_reductions_return_nat(self, dtype, skipna): # covers GH#11245 assert Series([], dtype=dtype).min(skipna=skipna) is NaT diff --git a/pandas/tests/reshape/merge/test_merge.py b/pandas/tests/reshape/merge/test_merge.py index 3b37ffa7baa82..72e6457e65e3c 100644 --- a/pandas/tests/reshape/merge/test_merge.py +++ b/pandas/tests/reshape/merge/test_merge.py @@ -1632,7 +1632,6 @@ def test_merge_incompat_dtypes_are_ok(self, df1_vals, df2_vals): (Series([1, 2], dtype="int32"), ["a", "b", "c"]), ([0, 1, 2], ["0", "1", "2"]), ([0.0, 1.0, 2.0], ["0", "1", "2"]), - ([0, 1, 2], ["0", "1", "2"]), ( pd.date_range("1/1/2011", periods=2, freq="D"), ["2011-01-01", "2011-01-02"], diff --git a/pandas/tests/scalar/test_nat.py b/pandas/tests/scalar/test_nat.py index cb046e0133245..e352e2601cef3 100644 --- a/pandas/tests/scalar/test_nat.py +++ b/pandas/tests/scalar/test_nat.py @@ -146,7 +146,6 @@ def test_round_nat(klass, method, freq): "utcnow", "utcoffset", "utctimetuple", - "timestamp", ], ) def test_nat_methods_raise(method): diff --git a/pandas/tests/series/methods/test_size.py b/pandas/tests/series/methods/test_size.py index 20a454996fa44..043e4b66dbf16 100644 --- a/pandas/tests/series/methods/test_size.py +++ b/pandas/tests/series/methods/test_size.py @@ -10,8 +10,6 @@ ({"a": 1, "b": 2, "c": 3}, None, 3), ([1, 2, 3], ["x", "y", "z"], 3), ([1, 2, 3, 4, 5], ["x", "y", "z", "w", "n"], 5), - ([1, 2, 3], None, 3), - ([1, 2, 3], ["x", "y", "z"], 3), ([1, 2, 3, 4], ["x", "y", "z", "w"], 4), ], ) diff --git a/pandas/tests/strings/test_extract.py b/pandas/tests/strings/test_extract.py index 77d008c650264..7ebcbdc7a8533 100644 --- a/pandas/tests/strings/test_extract.py +++ b/pandas/tests/strings/test_extract.py @@ -548,7 +548,6 @@ def test_extractall_single_group_with_quantifier(any_string_dtype): (["a3", "b3", "d4c2"], (None,)), (["a3", "b3", "d4c2"], ("i1", "i2")), (["a3", "b3", "d4c2"], (None, "i2")), - (["a3", "b3", "d4c2"], ("i1", "i2")), ], ) def test_extractall_no_matches(data, names, any_string_dtype): diff --git a/pandas/tests/test_nanops.py b/pandas/tests/test_nanops.py index 95d0953301a42..ed125ece349a9 100644 --- a/pandas/tests/test_nanops.py +++ b/pandas/tests/test_nanops.py @@ -748,7 +748,6 @@ def test_nancov(self): ("arr_bool", False), ("arr_str", False), ("arr_utf", False), - ("arr_complex", False), ("arr_complex_nan", False), ("arr_nan_nanj", False), ("arr_nan_infj", True), diff --git a/pandas/tests/tools/test_to_datetime.py b/pandas/tests/tools/test_to_datetime.py index 806a498b98853..f36a67b0775b8 100644 --- a/pandas/tests/tools/test_to_datetime.py +++ b/pandas/tests/tools/test_to_datetime.py @@ -3043,7 +3043,6 @@ def test_day_not_in_month_raise_value(self, cache, arg, format, msg): [ ["2015-02-29", None], ["2015-02-29", "%Y-%m-%d"], - ["2015-02-29", "%Y-%m-%d"], ["2015-04-31", "%Y-%m-%d"], ], ) diff --git a/pandas/tests/tseries/frequencies/test_inference.py b/pandas/tests/tseries/frequencies/test_inference.py index 0d37273e89092..edfc1973a2bd9 100644 --- a/pandas/tests/tseries/frequencies/test_inference.py +++ b/pandas/tests/tseries/frequencies/test_inference.py @@ -499,7 +499,6 @@ def test_series_datetime_index(freq): "YE@OCT", "YE@NOV", "YE@DEC", - "YE@JAN", "WOM@1MON", "WOM@2MON", "WOM@3MON", diff --git a/pandas/tests/tslibs/test_to_offset.py b/pandas/tests/tslibs/test_to_offset.py index ef68408305232..204775347e47a 100644 --- a/pandas/tests/tslibs/test_to_offset.py +++ b/pandas/tests/tslibs/test_to_offset.py @@ -24,7 +24,6 @@ ("15ms500us", offsets.Micro(15500)), ("10s75ms", offsets.Milli(10075)), ("1s0.25ms", offsets.Micro(1000250)), - ("1s0.25ms", offsets.Micro(1000250)), ("2800ns", offsets.Nano(2800)), ("2SME", offsets.SemiMonthEnd(2)), ("2SME-16", offsets.SemiMonthEnd(2, day_of_month=16)), diff --git a/pyproject.toml b/pyproject.toml index f693048adb60c..ebdf9deb034b5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -212,6 +212,8 @@ select = [ "INT", # pylint "PL", + # flake8-pytest-style + "PT", # misc lints "PIE", # flake8-pyi @@ -304,6 +306,24 @@ ignore = [ "PERF102", # try-except-in-loop, becomes useless in Python 3.11 "PERF203", + # pytest-missing-fixture-name-underscore + "PT004", + # pytest-incorrect-fixture-name-underscore + "PT005", + # pytest-parametrize-names-wrong-type + "PT006", + # pytest-parametrize-values-wrong-type + "PT007", + # pytest-patch-with-lambda + "PT008", + # pytest-raises-with-multiple-statements + "PT012", + # pytest-assert-in-except + "PT017", + # pytest-composite-assertion + "PT018", + # pytest-fixture-param-without-value + "PT019", # The following rules may cause conflicts when used with the formatter: "ISC001", @@ -351,6 +371,10 @@ exclude = [ # Keep this one enabled "pandas/_typing.py" = ["TCH"] +[tool.ruff.lint.flake8-pytest-style] +fixture-parentheses = false +mark-parentheses = false + [tool.pylint.messages_control] max-line-length = 88 disable = [ diff --git a/scripts/tests/test_validate_unwanted_patterns.py b/scripts/tests/test_validate_unwanted_patterns.py index bef9d369a0a3c..4c433d03aff4d 100644 --- a/scripts/tests/test_validate_unwanted_patterns.py +++ b/scripts/tests/test_validate_unwanted_patterns.py @@ -5,154 +5,6 @@ from scripts import validate_unwanted_patterns -class TestBarePytestRaises: - @pytest.mark.parametrize( - "data", - [ - ( - """ - with pytest.raises(ValueError, match="foo"): - pass - """ - ), - ( - """ - # with pytest.raises(ValueError, match="foo"): - # pass - """ - ), - ( - """ - # with pytest.raises(ValueError): - # pass - """ - ), - ( - """ - with pytest.raises( - ValueError, - match="foo" - ): - pass - """ - ), - ], - ) - def test_pytest_raises(self, data) -> None: - fd = io.StringIO(data.strip()) - result = list(validate_unwanted_patterns.bare_pytest_raises(fd)) - assert result == [] - - @pytest.mark.parametrize( - "data, expected", - [ - ( - ( - """ - with pytest.raises(ValueError): - pass - """ - ), - [ - ( - 1, - ( - "Bare pytests raise have been found. " - "Please pass in the argument 'match' " - "as well the exception." - ), - ), - ], - ), - ( - ( - """ - with pytest.raises(ValueError, match="foo"): - with pytest.raises(ValueError): - pass - pass - """ - ), - [ - ( - 2, - ( - "Bare pytests raise have been found. " - "Please pass in the argument 'match' " - "as well the exception." - ), - ), - ], - ), - ( - ( - """ - with pytest.raises(ValueError): - with pytest.raises(ValueError, match="foo"): - pass - pass - """ - ), - [ - ( - 1, - ( - "Bare pytests raise have been found. " - "Please pass in the argument 'match' " - "as well the exception." - ), - ), - ], - ), - ( - ( - """ - with pytest.raises( - ValueError - ): - pass - """ - ), - [ - ( - 1, - ( - "Bare pytests raise have been found. " - "Please pass in the argument 'match' " - "as well the exception." - ), - ), - ], - ), - ( - ( - """ - with pytest.raises( - ValueError, - # match = "foo" - ): - pass - """ - ), - [ - ( - 1, - ( - "Bare pytests raise have been found. " - "Please pass in the argument 'match' " - "as well the exception." - ), - ), - ], - ), - ], - ) - def test_pytest_raises_raises(self, data, expected) -> None: - fd = io.StringIO(data.strip()) - result = list(validate_unwanted_patterns.bare_pytest_raises(fd)) - assert result == expected - - class TestStringsWithWrongPlacedWhitespace: @pytest.mark.parametrize( "data", diff --git a/scripts/validate_unwanted_patterns.py b/scripts/validate_unwanted_patterns.py index 0d724779abfda..ee7f9226a7090 100755 --- a/scripts/validate_unwanted_patterns.py +++ b/scripts/validate_unwanted_patterns.py @@ -95,65 +95,6 @@ def _get_literal_string_prefix_len(token_string: str) -> int: return 0 -def bare_pytest_raises(file_obj: IO[str]) -> Iterable[tuple[int, str]]: - """ - Test Case for bare pytest raises. - - For example, this is wrong: - - >>> with pytest.raise(ValueError): - ... # Some code that raises ValueError - - And this is what we want instead: - - >>> with pytest.raise(ValueError, match="foo"): - ... # Some code that raises ValueError - - Parameters - ---------- - file_obj : IO - File-like object containing the Python code to validate. - - Yields - ------ - line_number : int - Line number of unconcatenated string. - msg : str - Explanation of the error. - - Notes - ----- - GH #23922 - """ - contents = file_obj.read() - tree = ast.parse(contents) - - for node in ast.walk(tree): - if not isinstance(node, ast.Call): - continue - - try: - if not (node.func.value.id == "pytest" and node.func.attr == "raises"): - continue - except AttributeError: - continue - - if not node.keywords: - yield ( - node.lineno, - "Bare pytests raise have been found. " - "Please pass in the argument 'match' as well the exception.", - ) - # Means that there are arguments that are being passed in, - # now we validate that `match` is one of the passed in arguments - elif not any(keyword.arg == "match" for keyword in node.keywords): - yield ( - node.lineno, - "Bare pytests raise have been found. " - "Please pass in the argument 'match' as well the exception.", - ) - - PRIVATE_FUNCTIONS_ALLOWED = {"sys._getframe"} # no known alternative @@ -457,7 +398,6 @@ def main( if __name__ == "__main__": available_validation_types: list[str] = [ - "bare_pytest_raises", "private_function_across_module", "private_import_across_module", "strings_with_wrong_placed_whitespace", diff --git a/web/tests/test_pandas_web.py b/web/tests/test_pandas_web.py index a5f76875dfe23..aacdfbcd6d26e 100644 --- a/web/tests/test_pandas_web.py +++ b/web/tests/test_pandas_web.py @@ -30,7 +30,7 @@ def context() -> dict: } -@pytest.fixture(scope="function") +@pytest.fixture def mock_response(monkeypatch, request) -> None: def mocked_resp(*args, **kwargs): status_code, response = request.param