From 42b6539fb199059eca867ed45cc81bc49590acbe Mon Sep 17 00:00:00 2001 From: Matthew Roeschke <10647082+mroeschke@users.noreply.github.com> Date: Thu, 1 Feb 2024 12:08:00 -0800 Subject: [PATCH 01/10] Enable B006 --- pandas/io/formats/style_render.py | 8 ++++---- pandas/tests/copy_view/index/test_index.py | 4 ++-- pandas/tests/io/test_feather.py | 4 +++- pandas/tests/plotting/common.py | 4 +++- pandas/tests/reshape/test_pivot.py | 8 ++++++-- pyproject.toml | 6 ------ 6 files changed, 18 insertions(+), 16 deletions(-) diff --git a/pandas/io/formats/style_render.py b/pandas/io/formats/style_render.py index 26c13e95fa280..d07f030405aa6 100644 --- a/pandas/io/formats/style_render.py +++ b/pandas/io/formats/style_render.py @@ -51,7 +51,7 @@ BaseFormatter = Union[str, Callable] ExtFormatter = Union[BaseFormatter, dict[Any, Optional[BaseFormatter]]] CSSPair = tuple[str, Union[str, float]] -CSSList = list[CSSPair] +CSSList = list[CSSPair] | tuple[CSSPair, ...] CSSProperties = Union[str, CSSList] @@ -1996,19 +1996,19 @@ class Tooltips: def __init__( self, - css_props: CSSProperties = [ + css_props: CSSProperties = ( ("visibility", "hidden"), ("position", "absolute"), ("z-index", 1), ("background-color", "black"), ("color", "white"), ("transform", "translate(-20px, -20px)"), - ], + ), css_name: str = "pd-t", tooltips: DataFrame = DataFrame(), ) -> None: self.class_name = css_name - self.class_properties = css_props + self.class_properties = list(css_props) self.tt_data = tooltips self.table_styles: CSSStyles = [] diff --git a/pandas/tests/copy_view/index/test_index.py b/pandas/tests/copy_view/index/test_index.py index 49d756cf32d34..596379a3266fb 100644 --- a/pandas/tests/copy_view/index/test_index.py +++ b/pandas/tests/copy_view/index/test_index.py @@ -10,7 +10,7 @@ from pandas.tests.copy_view.util import get_array -def index_view(index_data=[1, 2]): +def index_view(index_data): df = DataFrame({"a": index_data, "b": 1.5}) view = df[:] df = df.set_index("a", drop=True) @@ -142,7 +142,7 @@ def test_index_from_index(using_copy_on_write, warn_copy_on_write): ], ) def test_index_ops(using_copy_on_write, func, request): - idx, view_ = index_view() + idx, view_ = index_view([1, 2]) expected = idx.copy(deep=True) if "astype" in request.node.callspec.id: expected = expected.astype("Int64") diff --git a/pandas/tests/io/test_feather.py b/pandas/tests/io/test_feather.py index f012fcadc5592..c8b5b690ae118 100644 --- a/pandas/tests/io/test_feather.py +++ b/pandas/tests/io/test_feather.py @@ -36,7 +36,9 @@ def check_external_error_on_write(self, df): with tm.ensure_clean() as path: to_feather(df, path) - def check_round_trip(self, df, expected=None, write_kwargs={}, **read_kwargs): + def check_round_trip(self, df, expected=None, write_kwargs=None, **read_kwargs): + if write_kwargs is None: + write_kwargs = {} if expected is None: expected = df.copy() diff --git a/pandas/tests/plotting/common.py b/pandas/tests/plotting/common.py index 69120160699c2..5a46cdcb051b6 100644 --- a/pandas/tests/plotting/common.py +++ b/pandas/tests/plotting/common.py @@ -433,7 +433,7 @@ def _check_box_return_type( raise AssertionError -def _check_grid_settings(obj, kinds, kws={}): +def _check_grid_settings(obj, kinds, kws=None): # Make sure plot defaults to rcParams['axes.grid'] setting, GH 9792 import matplotlib as mpl @@ -446,6 +446,8 @@ def is_grid_on(): return not (xoff and yoff) + if kws is None: + kws = {} spndx = 1 for kind in kinds: mpl.pyplot.subplot(1, 4 * len(kinds), spndx) diff --git a/pandas/tests/reshape/test_pivot.py b/pandas/tests/reshape/test_pivot.py index fbc3d2b8a7c35..f020fd45c87d9 100644 --- a/pandas/tests/reshape/test_pivot.py +++ b/pandas/tests/reshape/test_pivot.py @@ -890,10 +890,14 @@ def _check_output( result, values_col, data, - index=["A", "B"], - columns=["C"], + index=None, + columns=None, margins_col="All", ): + if index is None: + index = ["A", "B"] + if columns is None: + columns = ["C"] col_margins = result.loc[result.index[:-1], margins_col] expected_col_margins = data.groupby(index)[values_col].mean() tm.assert_series_equal(col_margins, expected_col_margins, check_names=False) diff --git a/pyproject.toml b/pyproject.toml index 96e8ea90afa59..b9b816ece56af 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -249,12 +249,6 @@ ignore = [ "E402", # do not assign a lambda expression, use a def "E731", - # line break before binary operator - # "W503", # not yet implemented - # line break after binary operator - # "W504", # not yet implemented - # controversial - "B006", # controversial "B007", # controversial From 9998e77778042fd5f66b00666eccaa0805bb88c9 Mon Sep 17 00:00:00 2001 From: Matthew Roeschke <10647082+mroeschke@users.noreply.github.com> Date: Thu, 1 Feb 2024 12:10:24 -0800 Subject: [PATCH 02/10] Enable B011 --- pyproject.toml | 2 -- 1 file changed, 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index b9b816ece56af..1d5b64f32c386 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -257,8 +257,6 @@ ignore = [ "B009", # getattr is used to side-step mypy "B010", - # tests use assert False - "B011", # tests use comparisons but not their returned value "B015", # false positives From 37ab5f2e95e41e503dadb5f7f8183f4c8ffac244 Mon Sep 17 00:00:00 2001 From: Matthew Roeschke <10647082+mroeschke@users.noreply.github.com> Date: Thu, 1 Feb 2024 12:15:09 -0800 Subject: [PATCH 03/10] Enable B019 --- pyproject.toml | 2 -- 1 file changed, 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 1d5b64f32c386..c7f4b169ceb5b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -259,8 +259,6 @@ ignore = [ "B010", # tests use comparisons but not their returned value "B015", - # false positives - "B019", # Loop control variable overrides iterable it iterates "B020", # Function definition does not bind loop variable From 21f970db0f00dfcac4401339b86dab56d7ce8dec Mon Sep 17 00:00:00 2001 From: Matthew Roeschke <10647082+mroeschke@users.noreply.github.com> Date: Thu, 1 Feb 2024 12:21:22 -0800 Subject: [PATCH 04/10] Enable B020 --- pandas/io/json/_normalize.py | 4 ++-- pandas/tests/arrays/masked/test_arithmetic.py | 12 ++++++------ pandas/tests/frame/test_query_eval.py | 8 ++++---- pandas/tests/window/test_expanding.py | 8 ++++---- pandas/tests/window/test_rolling.py | 18 ++++++++++-------- pyproject.toml | 4 ++-- 6 files changed, 28 insertions(+), 26 deletions(-) diff --git a/pandas/io/json/_normalize.py b/pandas/io/json/_normalize.py index de4033d5767e6..39fbce0b6901c 100644 --- a/pandas/io/json/_normalize.py +++ b/pandas/io/json/_normalize.py @@ -537,8 +537,8 @@ def _recursive_extract(data, path, seen_meta, level: int = 0) -> None: if values.ndim > 1: # GH 37782 values = np.empty((len(v),), dtype=object) - for i, v in enumerate(v): - values[i] = v + for i, val in enumerate(v): + values[i] = val result[k] = values.repeat(lengths) return result diff --git a/pandas/tests/arrays/masked/test_arithmetic.py b/pandas/tests/arrays/masked/test_arithmetic.py index f4b571ca627b3..ea018d2da4d26 100644 --- a/pandas/tests/arrays/masked/test_arithmetic.py +++ b/pandas/tests/arrays/masked/test_arithmetic.py @@ -55,15 +55,15 @@ def test_array_scalar_like_equivalence(data, all_arithmetic_operators): scalar_array = pd.array([scalar] * len(data), dtype=data.dtype) # TODO also add len-1 array (np.array([scalar], dtype=data.dtype.numpy_dtype)) - for scalar in [scalar, data.dtype.type(scalar)]: + for val in [scalar, data.dtype.type(scalar)]: if is_bool_not_implemented(data, all_arithmetic_operators): msg = "operator '.*' not implemented for bool dtypes" with pytest.raises(NotImplementedError, match=msg): - op(data, scalar) + op(data, val) with pytest.raises(NotImplementedError, match=msg): op(data, scalar_array) else: - result = op(data, scalar) + result = op(data, val) expected = op(data, scalar_array) tm.assert_extension_array_equal(result, expected) @@ -214,13 +214,13 @@ def test_error_len_mismatch(data, all_arithmetic_operators): msg = "operator '.*' not implemented for bool dtypes" err = NotImplementedError - for other in [other, np.array(other)]: + for val in [other, np.array(other)]: with pytest.raises(err, match=msg): - op(data, other) + op(data, val) s = pd.Series(data) with pytest.raises(err, match=msg): - op(s, other) + op(s, val) @pytest.mark.parametrize("op", ["__neg__", "__abs__", "__invert__"]) diff --git a/pandas/tests/frame/test_query_eval.py b/pandas/tests/frame/test_query_eval.py index 0a869d8f94f47..0e29db3ca85df 100644 --- a/pandas/tests/frame/test_query_eval.py +++ b/pandas/tests/frame/test_query_eval.py @@ -949,8 +949,8 @@ def test_str_query_method(self, parser, engine): ops = 2 * ([eq] + [ne]) msg = r"'(Not)?In' nodes are not implemented" - for lhs, op, rhs in zip(lhs, ops, rhs): - ex = f"{lhs} {op} {rhs}" + for lh, op_, rh in zip(lhs, ops, rhs): + ex = f"{lh} {op_} {rh}" with pytest.raises(NotImplementedError, match=msg): df.query( ex, @@ -990,8 +990,8 @@ def test_str_list_query_method(self, parser, engine): ops = 2 * ([eq] + [ne]) msg = r"'(Not)?In' nodes are not implemented" - for lhs, op, rhs in zip(lhs, ops, rhs): - ex = f"{lhs} {op} {rhs}" + for lh, ops_, rh in zip(lhs, ops, rhs): + ex = f"{lh} {ops_} {rh}" with pytest.raises(NotImplementedError, match=msg): df.query(ex, engine=engine, parser=parser) else: diff --git a/pandas/tests/window/test_expanding.py b/pandas/tests/window/test_expanding.py index 6d452b27f3654..ad59f9e52514e 100644 --- a/pandas/tests/window/test_expanding.py +++ b/pandas/tests/window/test_expanding.py @@ -178,9 +178,9 @@ def test_expanding_count_with_min_periods_exceeding_series_length(frame_or_serie def test_iter_expanding_dataframe(df, expected, min_periods): # GH 11704 df = DataFrame(df) - expected = [DataFrame(values, index=index) for (values, index) in expected] + expecteds = [DataFrame(values, index=index) for (values, index) in expected] - for expected, actual in zip(expected, df.expanding(min_periods)): + for expected, actual in zip(expecteds, df.expanding(min_periods)): tm.assert_frame_equal(actual, expected) @@ -197,9 +197,9 @@ def test_iter_expanding_dataframe(df, expected, min_periods): ) def test_iter_expanding_series(ser, expected, min_periods): # GH 11704 - expected = [Series(values, index=index) for (values, index) in expected] + expecteds = [Series(values, index=index) for (values, index) in expected] - for expected, actual in zip(expected, ser.expanding(min_periods)): + for expected, actual in zip(expecteds, ser.expanding(min_periods)): tm.assert_series_equal(actual, expected) diff --git a/pandas/tests/window/test_rolling.py b/pandas/tests/window/test_rolling.py index fda631987255a..85821ed2cfb6f 100644 --- a/pandas/tests/window/test_rolling.py +++ b/pandas/tests/window/test_rolling.py @@ -760,9 +760,9 @@ def test_rolling_count_default_min_periods_with_null_values(frame_or_series): def test_iter_rolling_dataframe(df, expected, window, min_periods): # GH 11704 df = DataFrame(df) - expected = [DataFrame(values, index=index) for (values, index) in expected] + expecteds = [DataFrame(values, index=index) for (values, index) in expected] - for expected, actual in zip(expected, df.rolling(window, min_periods=min_periods)): + for expected, actual in zip(expecteds, df.rolling(window, min_periods=min_periods)): tm.assert_frame_equal(actual, expected) @@ -805,10 +805,10 @@ def test_iter_rolling_on_dataframe(expected, window): } ) - expected = [ + expecteds = [ DataFrame(values, index=df.loc[index, "C"]) for (values, index) in expected ] - for expected, actual in zip(expected, df.rolling(window, on="C")): + for expected, actual in zip(expecteds, df.rolling(window, on="C")): tm.assert_frame_equal(actual, expected) @@ -856,9 +856,11 @@ def test_iter_rolling_on_dataframe_unordered(): ) def test_iter_rolling_series(ser, expected, window, min_periods): # GH 11704 - expected = [Series(values, index=index) for (values, index) in expected] + expecteds = [Series(values, index=index) for (values, index) in expected] - for expected, actual in zip(expected, ser.rolling(window, min_periods=min_periods)): + for expected, actual in zip( + expecteds, ser.rolling(window, min_periods=min_periods) + ): tm.assert_series_equal(actual, expected) @@ -904,11 +906,11 @@ def test_iter_rolling_datetime(expected, expected_index, window): # GH 11704 ser = Series(range(5), index=date_range(start="2020-01-01", periods=5, freq="D")) - expected = [ + expecteds = [ Series(values, index=idx) for (values, idx) in zip(expected, expected_index) ] - for expected, actual in zip(expected, ser.rolling(window)): + for expected, actual in zip(expecteds, ser.rolling(window)): tm.assert_series_equal(actual, expected) diff --git a/pyproject.toml b/pyproject.toml index c7f4b169ceb5b..9801c40f4fc83 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -259,8 +259,8 @@ ignore = [ "B010", # tests use comparisons but not their returned value "B015", - # Loop control variable overrides iterable it iterates - "B020", + # # Loop control variable overrides iterable it iterates + # "B020", # Function definition does not bind loop variable "B023", # Functions defined inside a loop must not use variables redefined in the loop From c653d0225ecdefb4f7e7da8078107f3b0e2379a0 Mon Sep 17 00:00:00 2001 From: Matthew Roeschke <10647082+mroeschke@users.noreply.github.com> Date: Thu, 1 Feb 2024 12:21:57 -0800 Subject: [PATCH 05/10] Enable B020 --- pyproject.toml | 2 -- 1 file changed, 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 9801c40f4fc83..5a1934f8132aa 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -259,8 +259,6 @@ ignore = [ "B010", # tests use comparisons but not their returned value "B015", - # # Loop control variable overrides iterable it iterates - # "B020", # Function definition does not bind loop variable "B023", # Functions defined inside a loop must not use variables redefined in the loop From b65fd63a63260debbaaee7dbe0e1daf5f8374ccd Mon Sep 17 00:00:00 2001 From: Matthew Roeschke <10647082+mroeschke@users.noreply.github.com> Date: Thu, 1 Feb 2024 12:26:51 -0800 Subject: [PATCH 06/10] Enable PYI and othe rule --- pandas/_libs/tslibs/vectorized.pyi | 6 ++---- pyproject.toml | 4 ---- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/pandas/_libs/tslibs/vectorized.pyi b/pandas/_libs/tslibs/vectorized.pyi index de19f592da62b..f377c2e26ab81 100644 --- a/pandas/_libs/tslibs/vectorized.pyi +++ b/pandas/_libs/tslibs/vectorized.pyi @@ -1,7 +1,5 @@ -""" -For cython types that cannot be represented precisely, closest-available -python equivalents are used, and the precise types kept as adjacent comments. -""" +# For cython types that cannot be represented precisely, closest-available +# python equivalents are used, and the precise types kept as adjacent comments. from datetime import tzinfo import numpy as np diff --git a/pyproject.toml b/pyproject.toml index 5a1934f8132aa..5a17b9e3746bb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -261,8 +261,6 @@ ignore = [ "B015", # Function definition does not bind loop variable "B023", - # Functions defined inside a loop must not use variables redefined in the loop - # "B301", # not yet implemented # Only works with python >=3.10 "B905", # Too many arguments to function call @@ -277,8 +275,6 @@ ignore = [ "PLW2901", # Global statements are discouraged "PLW0603", - # Docstrings should not be included in stubs - "PYI021", # Use `typing.NamedTuple` instead of `collections.namedtuple` "PYI024", # No builtin `eval()` allowed From 838aa49595ba08968ae98f25653a6f7048a85479 Mon Sep 17 00:00:00 2001 From: Matthew Roeschke <10647082+mroeschke@users.noreply.github.com> Date: Thu, 1 Feb 2024 12:28:04 -0800 Subject: [PATCH 07/10] Enable PLC1901 --- pyproject.toml | 2 -- 1 file changed, 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 5a17b9e3746bb..eef5aeb6ea6fa 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -279,8 +279,6 @@ ignore = [ "PYI024", # No builtin `eval()` allowed "PGH001", - # compare-to-empty-string - "PLC1901", # while int | float can be shortened to float, the former is more explicit "PYI041", # incorrect-dict-iterator, flags valid Series.items usage From 9a459b130a5fb0afdbedb625488286e8896c3678 Mon Sep 17 00:00:00 2001 From: Matthew Roeschke <10647082+mroeschke@users.noreply.github.com> Date: Thu, 1 Feb 2024 12:33:46 -0800 Subject: [PATCH 08/10] Use values instead of items --- pandas/core/indexers/objects.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/core/indexers/objects.py b/pandas/core/indexers/objects.py index f2db4886a5590..5119089bac977 100644 --- a/pandas/core/indexers/objects.py +++ b/pandas/core/indexers/objects.py @@ -399,7 +399,7 @@ def get_window_bounds( start_arrays = [] end_arrays = [] window_indices_start = 0 - for key, indices in self.groupby_indices.items(): + for indices in self.groupby_indices.values(): index_array: np.ndarray | None if self.index_array is not None: From 40ba6a0512f4dcdbbeeb2b0a58b71b3edcdac24e Mon Sep 17 00:00:00 2001 From: Matthew Roeschke <10647082+mroeschke@users.noreply.github.com> Date: Thu, 1 Feb 2024 13:18:28 -0800 Subject: [PATCH 09/10] Use union --- pandas/io/formats/style_render.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/io/formats/style_render.py b/pandas/io/formats/style_render.py index d07f030405aa6..76e235a40c625 100644 --- a/pandas/io/formats/style_render.py +++ b/pandas/io/formats/style_render.py @@ -51,7 +51,7 @@ BaseFormatter = Union[str, Callable] ExtFormatter = Union[BaseFormatter, dict[Any, Optional[BaseFormatter]]] CSSPair = tuple[str, Union[str, float]] -CSSList = list[CSSPair] | tuple[CSSPair, ...] +CSSList = Union[list[CSSPair], tuple[CSSPair, ...]] CSSProperties = Union[str, CSSList] From 8e497e7f83755d7090672a8d512609675c10f5ec Mon Sep 17 00:00:00 2001 From: Matthew Roeschke <10647082+mroeschke@users.noreply.github.com> Date: Thu, 1 Feb 2024 14:52:57 -0800 Subject: [PATCH 10/10] Ignore one case --- pandas/io/formats/style_render.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pandas/io/formats/style_render.py b/pandas/io/formats/style_render.py index 76e235a40c625..80df46bf2336a 100644 --- a/pandas/io/formats/style_render.py +++ b/pandas/io/formats/style_render.py @@ -51,7 +51,7 @@ BaseFormatter = Union[str, Callable] ExtFormatter = Union[BaseFormatter, dict[Any, Optional[BaseFormatter]]] CSSPair = tuple[str, Union[str, float]] -CSSList = Union[list[CSSPair], tuple[CSSPair, ...]] +CSSList = list[CSSPair] CSSProperties = Union[str, CSSList] @@ -1996,19 +1996,19 @@ class Tooltips: def __init__( self, - css_props: CSSProperties = ( + css_props: CSSProperties = [ # noqa: B006 ("visibility", "hidden"), ("position", "absolute"), ("z-index", 1), ("background-color", "black"), ("color", "white"), ("transform", "translate(-20px, -20px)"), - ), + ], css_name: str = "pd-t", tooltips: DataFrame = DataFrame(), ) -> None: self.class_name = css_name - self.class_properties = list(css_props) + self.class_properties = css_props self.tt_data = tooltips self.table_styles: CSSStyles = []