From 0345df07b28a4df7fda543b4855b60940962890a Mon Sep 17 00:00:00 2001 From: Marco Gorelli Date: Sun, 16 May 2021 15:11:30 +0100 Subject: [PATCH 1/3] deprecate non-keyword args for clip --- doc/source/whatsnew/v1.3.0.rst | 1 + pandas/core/generic.py | 4 ++++ pandas/tests/frame/methods/test_clip.py | 10 ++++++++++ pandas/tests/series/methods/test_clip.py | 10 ++++++++++ 4 files changed, 25 insertions(+) diff --git a/doc/source/whatsnew/v1.3.0.rst b/doc/source/whatsnew/v1.3.0.rst index 622029adf357f..3f3ccf15e4b15 100644 --- a/doc/source/whatsnew/v1.3.0.rst +++ b/doc/source/whatsnew/v1.3.0.rst @@ -647,6 +647,7 @@ Deprecations - Deprecated setting :attr:`Categorical._codes`, create a new :class:`Categorical` with the desired codes instead (:issue:`40606`) - Deprecated behavior of :meth:`DatetimeIndex.union` with mixed timezones; in a future version both will be cast to UTC instead of object dtype (:issue:`39328`) - Deprecated using ``usecols`` with out of bounds indices for ``read_csv`` with ``engine="c"`` (:issue:`25623`) +- Deprecated passing arguments as positional in :meth:`DataFrame.clip` and :meth:`Series.clip` (:issue:`41485`) .. --------------------------------------------------------------------------- diff --git a/pandas/core/generic.py b/pandas/core/generic.py index a09cc0a6324c0..a980f777b5875 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -61,6 +61,7 @@ InvalidIndexError, ) from pandas.util._decorators import ( + deprecate_nonkeyword_arguments, doc, rewrite_axis_style_signature, ) @@ -7469,6 +7470,9 @@ def clip( ) -> FrameOrSeries | None: ... + @deprecate_nonkeyword_arguments( + version="2.0", allowed_args=["self", "lower", "upper"] + ) @final def clip( self: FrameOrSeries, diff --git a/pandas/tests/frame/methods/test_clip.py b/pandas/tests/frame/methods/test_clip.py index 6525109da4394..d7ce3b2ad1ffa 100644 --- a/pandas/tests/frame/methods/test_clip.py +++ b/pandas/tests/frame/methods/test_clip.py @@ -166,3 +166,13 @@ def test_clip_with_na_args(self, float_frame): result = df.clip(lower=t, axis=0) expected = DataFrame({"col_0": [9, -3, 0, 6, 5], "col_1": [2, -4, 6, 8, 3]}) tm.assert_frame_equal(result, expected) + + def test_clip_pos_args_deprecation(self): + # https://github.com/pandas-dev/pandas/issues/41485 + df = DataFrame({"a": [1, 2, 3]}) + msg = ( + r"Starting with Pandas version 2\.0 all arguments of clip except " + r"for the arguments 'self', 'lower' and 'upper' will be keyword-only" + ) + with tm.assert_produces_warning(FutureWarning, match=msg): + df.clip(0, 1, 0) diff --git a/pandas/tests/series/methods/test_clip.py b/pandas/tests/series/methods/test_clip.py index 6185fe6c54fa4..b5ca5194809e8 100644 --- a/pandas/tests/series/methods/test_clip.py +++ b/pandas/tests/series/methods/test_clip.py @@ -127,3 +127,13 @@ def test_clip_with_datetimes(self): ] ) tm.assert_series_equal(result, expected) + + def test_clip_pos_args_deprecation(self): + # https://github.com/pandas-dev/pandas/issues/41485 + ser = Series([1, 2, 3]) + msg = ( + r"Starting with Pandas version 2\.0 all arguments of clip except " + r"for the arguments 'self', 'lower' and 'upper' will be keyword-only" + ) + with tm.assert_produces_warning(FutureWarning, match=msg): + ser.clip(0, 1, 0) From 37faa101406f796e4922463a655ca39108b13e33 Mon Sep 17 00:00:00 2001 From: Marco Gorelli Date: Tue, 18 May 2021 21:23:51 +0100 Subject: [PATCH 2/3] adjust after merge --- pandas/core/frame.py | 15 +++++++++++++++ pandas/core/generic.py | 5 ----- pandas/core/series.py | 15 +++++++++++++++ pandas/tests/frame/methods/test_clip.py | 8 +++++--- pandas/tests/series/methods/test_clip.py | 8 +++++--- 5 files changed, 40 insertions(+), 11 deletions(-) diff --git a/pandas/core/frame.py b/pandas/core/frame.py index efefeb23445af..6bccd96e9cb90 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -77,6 +77,7 @@ Appender, Substitution, deprecate_kwarg, + deprecate_nonkeyword_arguments, doc, rewrite_axis_style_signature, ) @@ -10621,6 +10622,20 @@ def values(self) -> np.ndarray: self._consolidate_inplace() return self._mgr.as_array(transpose=True) + @deprecate_nonkeyword_arguments( + version=None, allowed_args=["self", "lower", "upper"] + ) + def clip( + self: DataFrame, + lower=None, + upper=None, + axis: Axis | None = None, + inplace: bool = False, + *args, + **kwargs, + ) -> DataFrame | None: + return super().clip(lower, upper, axis, inplace, *args, **kwargs) + @property def _values(self) -> np.ndarray: """internal implementation""" diff --git a/pandas/core/generic.py b/pandas/core/generic.py index a980f777b5875..dd02bd20a5eef 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -61,7 +61,6 @@ InvalidIndexError, ) from pandas.util._decorators import ( - deprecate_nonkeyword_arguments, doc, rewrite_axis_style_signature, ) @@ -7470,10 +7469,6 @@ def clip( ) -> FrameOrSeries | None: ... - @deprecate_nonkeyword_arguments( - version="2.0", allowed_args=["self", "lower", "upper"] - ) - @final def clip( self: FrameOrSeries, lower=None, diff --git a/pandas/core/series.py b/pandas/core/series.py index d0ff50cca5355..ef9f84230759a 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -51,6 +51,7 @@ from pandas.util._decorators import ( Appender, Substitution, + deprecate_nonkeyword_arguments, doc, ) from pandas.util._validators import ( @@ -5256,6 +5257,20 @@ def to_period(self, freq=None, copy=True) -> Series: self, method="to_period" ) + @deprecate_nonkeyword_arguments( + version=None, allowed_args=["self", "lower", "upper"] + ) + def clip( + self: Series, + lower=None, + upper=None, + axis: Axis | None = None, + inplace: bool = False, + *args, + **kwargs, + ) -> Series | None: + return super().clip(lower, upper, axis, inplace, *args, **kwargs) + # ---------------------------------------------------------------------- # Add index _AXIS_ORDERS = ["index"] diff --git a/pandas/tests/frame/methods/test_clip.py b/pandas/tests/frame/methods/test_clip.py index d7ce3b2ad1ffa..09b33831ed5ec 100644 --- a/pandas/tests/frame/methods/test_clip.py +++ b/pandas/tests/frame/methods/test_clip.py @@ -171,8 +171,10 @@ def test_clip_pos_args_deprecation(self): # https://github.com/pandas-dev/pandas/issues/41485 df = DataFrame({"a": [1, 2, 3]}) msg = ( - r"Starting with Pandas version 2\.0 all arguments of clip except " - r"for the arguments 'self', 'lower' and 'upper' will be keyword-only" + r"In a future version of pandas all arguments of DataFrame.clip except " + r"for the arguments 'lower' and 'upper' will be keyword-only" ) with tm.assert_produces_warning(FutureWarning, match=msg): - df.clip(0, 1, 0) + result = df.clip(0, 1, 0) + expected = DataFrame({"a": [1, 1, 1]}) + tm.assert_frame_equal(result, expected) diff --git a/pandas/tests/series/methods/test_clip.py b/pandas/tests/series/methods/test_clip.py index b5ca5194809e8..7dbc194669a62 100644 --- a/pandas/tests/series/methods/test_clip.py +++ b/pandas/tests/series/methods/test_clip.py @@ -132,8 +132,10 @@ def test_clip_pos_args_deprecation(self): # https://github.com/pandas-dev/pandas/issues/41485 ser = Series([1, 2, 3]) msg = ( - r"Starting with Pandas version 2\.0 all arguments of clip except " - r"for the arguments 'self', 'lower' and 'upper' will be keyword-only" + r"In a future version of pandas all arguments of Series.clip except " + r"for the arguments 'lower' and 'upper' will be keyword-only" ) with tm.assert_produces_warning(FutureWarning, match=msg): - ser.clip(0, 1, 0) + result = ser.clip(0, 1, 0) + expected = Series([1, 1, 1]) + tm.assert_series_equal(result, expected) From 43b7b4cc9071f1d3cf7f76a4d960a7bd11a9c86f Mon Sep 17 00:00:00 2001 From: Marco Gorelli Date: Sun, 23 May 2021 21:31:49 +0100 Subject: [PATCH 3/3] remove overloads --- pandas/core/generic.py | 108 ----------------------------------------- 1 file changed, 108 deletions(-) diff --git a/pandas/core/generic.py b/pandas/core/generic.py index fd47b6f2c708e..0cf31f9aa7586 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -7365,114 +7365,6 @@ def _clip_with_one_bound(self, threshold, method, axis, inplace): # GH 40420 return self.where(subset, threshold, axis=axis, inplace=inplace) - @overload - def clip( - self: FrameOrSeries, - lower=..., - upper=..., - axis: Axis | None = ..., - inplace: Literal[False] = ..., - *args, - **kwargs, - ) -> FrameOrSeries: - ... - - @overload - def clip( - self: FrameOrSeries, - lower, - *, - axis: Axis | None, - inplace: Literal[True], - **kwargs, - ) -> None: - ... - - @overload - def clip( - self: FrameOrSeries, - lower, - *, - inplace: Literal[True], - **kwargs, - ) -> None: - ... - - @overload - def clip( - self: FrameOrSeries, - *, - upper, - axis: Axis | None, - inplace: Literal[True], - **kwargs, - ) -> None: - ... - - @overload - def clip( - self: FrameOrSeries, - *, - upper, - inplace: Literal[True], - **kwargs, - ) -> None: - ... - - @overload - def clip( - self: FrameOrSeries, - *, - axis: Axis | None, - inplace: Literal[True], - **kwargs, - ) -> None: - ... - - @overload - def clip( - self: FrameOrSeries, - lower, - upper, - axis: Axis | None, - inplace: Literal[True], - *args, - **kwargs, - ) -> None: - ... - - @overload - def clip( - self: FrameOrSeries, - lower, - upper, - *, - inplace: Literal[True], - **kwargs, - ) -> None: - ... - - @overload - def clip( - self: FrameOrSeries, - *, - inplace: Literal[True], - **kwargs, - ) -> None: - ... - - @overload - def clip( - self: FrameOrSeries, - lower=..., - upper=..., - axis: Axis | None = ..., - inplace: bool_t = ..., - *args, - **kwargs, - ) -> FrameOrSeries | None: - ... - def clip( self: FrameOrSeries, lower=None,