From 2a0270e29d9231bb390d8e1fa8c9cce6228d4676 Mon Sep 17 00:00:00 2001 From: Marco Gorelli Date: Sun, 16 May 2021 13:24:02 +0100 Subject: [PATCH 1/2] deprecate passing args as positional in sort_values --- doc/source/whatsnew/v1.3.0.rst | 1 + pandas/core/frame.py | 2 ++ pandas/core/series.py | 2 ++ .../tests/frame/methods/test_sort_values.py | 10 ++++++++++ .../tests/series/methods/test_sort_values.py | 20 ++++++++++++++----- 5 files changed, 30 insertions(+), 5 deletions(-) diff --git a/doc/source/whatsnew/v1.3.0.rst b/doc/source/whatsnew/v1.3.0.rst index 622029adf357f..257e506872ea5 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 (except for ``by``) in :meth:`DataFrame.sort_values` and :meth:`Series.sort_values` (:issue:`41485`) .. --------------------------------------------------------------------------- diff --git a/pandas/core/frame.py b/pandas/core/frame.py index 2941b6ac01904..e0c5dbda7894f 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, ) @@ -6188,6 +6189,7 @@ def f(vals) -> tuple[np.ndarray, int]: # ---------------------------------------------------------------------- # Sorting # TODO: Just move the sort_values doc here. + @deprecate_nonkeyword_arguments(version="2.0", allowed_args=["self", "by"]) @Substitution(**_shared_doc_kwargs) @Appender(NDFrame.sort_values.__doc__) # error: Signature of "sort_values" incompatible with supertype "NDFrame" diff --git a/pandas/core/series.py b/pandas/core/series.py index c8e9898f9462a..ca1b5e0c997f6 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 ( @@ -3224,6 +3225,7 @@ def update(self, other) -> None: # ---------------------------------------------------------------------- # Reindexing, sorting + @deprecate_nonkeyword_arguments(version="2.0", allowed_args=["self"]) def sort_values( self, axis=0, diff --git a/pandas/tests/frame/methods/test_sort_values.py b/pandas/tests/frame/methods/test_sort_values.py index 2ca5f6aa72241..eed2699b05be8 100644 --- a/pandas/tests/frame/methods/test_sort_values.py +++ b/pandas/tests/frame/methods/test_sort_values.py @@ -856,3 +856,13 @@ def test_sort_column_level_and_index_label( tm.assert_frame_equal(result, expected) else: tm.assert_frame_equal(result, expected) + + def test_sort_values_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 sort_values except " + r"for the arguments 'self' and 'by' will be keyword-only" + ) + with tm.assert_produces_warning(FutureWarning, match=msg): + df.sort_values("a", 0) diff --git a/pandas/tests/series/methods/test_sort_values.py b/pandas/tests/series/methods/test_sort_values.py index fe2046401f657..121a9fb0d2762 100644 --- a/pandas/tests/series/methods/test_sort_values.py +++ b/pandas/tests/series/methods/test_sort_values.py @@ -187,30 +187,40 @@ def test_sort_values_ignore_index( tm.assert_series_equal(result_ser, expected) tm.assert_series_equal(ser, Series(original_list)) + def test_sort_values_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 sort_values except " + r"for the argument 'self' will be keyword-only" + ) + with tm.assert_produces_warning(FutureWarning, match=msg): + ser.sort_values(0) + class TestSeriesSortingKey: def test_sort_values_key(self): series = Series(np.array(["Hello", "goodbye"])) - result = series.sort_values(0) + result = series.sort_values(axis=0) expected = series tm.assert_series_equal(result, expected) - result = series.sort_values(0, key=lambda x: x.str.lower()) + result = series.sort_values(axis=0, key=lambda x: x.str.lower()) expected = series[::-1] tm.assert_series_equal(result, expected) def test_sort_values_key_nan(self): series = Series(np.array([0, 5, np.nan, 3, 2, np.nan])) - result = series.sort_values(0) + result = series.sort_values(axis=0) expected = series.iloc[[0, 4, 3, 1, 2, 5]] tm.assert_series_equal(result, expected) - result = series.sort_values(0, key=lambda x: x + 5) + result = series.sort_values(axis=0, key=lambda x: x + 5) expected = series.iloc[[0, 4, 3, 1, 2, 5]] tm.assert_series_equal(result, expected) - result = series.sort_values(0, key=lambda x: -x, ascending=False) + result = series.sort_values(axis=0, key=lambda x: -x, ascending=False) expected = series.iloc[[0, 4, 3, 1, 2, 5]] tm.assert_series_equal(result, expected) From fee32112e713d59cb3c0ea6e09060b7fa1c04c34 Mon Sep 17 00:00:00 2001 From: Marco Gorelli Date: Tue, 18 May 2021 22:02:15 +0100 Subject: [PATCH 2/2] fixup post merge --- doc/source/whatsnew/v1.3.0.rst | 2 +- pandas/core/frame.py | 2 +- pandas/core/series.py | 2 +- pandas/tests/frame/methods/test_sort_values.py | 8 +++++--- pandas/tests/series/methods/test_sort_values.py | 8 +++++--- 5 files changed, 13 insertions(+), 9 deletions(-) diff --git a/doc/source/whatsnew/v1.3.0.rst b/doc/source/whatsnew/v1.3.0.rst index 123a9ff0ae258..5eaba825be1fe 100644 --- a/doc/source/whatsnew/v1.3.0.rst +++ b/doc/source/whatsnew/v1.3.0.rst @@ -648,7 +648,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 (except for ``by``) in :meth:`DataFrame.sort_values` and :meth:`Series.sort_values` (:issue:`41485`) +- Deprecated passing arguments as positional in :meth:`DataFrame.sort_values` (except for ``by``) and :meth:`Series.sort_values` (:issue:`41485`) .. --------------------------------------------------------------------------- diff --git a/pandas/core/frame.py b/pandas/core/frame.py index ac49adb1da9bb..23871ba7d726f 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -6227,7 +6227,7 @@ def f(vals) -> tuple[np.ndarray, int]: # ---------------------------------------------------------------------- # Sorting # TODO: Just move the sort_values doc here. - @deprecate_nonkeyword_arguments(version="2.0", allowed_args=["self", "by"]) + @deprecate_nonkeyword_arguments(version=None, allowed_args=["self", "by"]) @Substitution(**_shared_doc_kwargs) @Appender(NDFrame.sort_values.__doc__) # error: Signature of "sort_values" incompatible with supertype "NDFrame" diff --git a/pandas/core/series.py b/pandas/core/series.py index eeb7310a3bc23..f6177cf970c94 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -3225,7 +3225,7 @@ def update(self, other) -> None: # ---------------------------------------------------------------------- # Reindexing, sorting - @deprecate_nonkeyword_arguments(version="2.0", allowed_args=["self"]) + @deprecate_nonkeyword_arguments(version=None, allowed_args=["self"]) def sort_values( self, axis=0, diff --git a/pandas/tests/frame/methods/test_sort_values.py b/pandas/tests/frame/methods/test_sort_values.py index eed2699b05be8..d46796bcd978b 100644 --- a/pandas/tests/frame/methods/test_sort_values.py +++ b/pandas/tests/frame/methods/test_sort_values.py @@ -861,8 +861,10 @@ def test_sort_values_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 sort_values except " - r"for the arguments 'self' and 'by' will be keyword-only" + r"In a future version of pandas all arguments of DataFrame\.sort_values " + r"except for the argument 'by' will be keyword-only" ) with tm.assert_produces_warning(FutureWarning, match=msg): - df.sort_values("a", 0) + result = df.sort_values("a", 0) + expected = DataFrame({"a": [1, 2, 3]}) + tm.assert_frame_equal(result, expected) diff --git a/pandas/tests/series/methods/test_sort_values.py b/pandas/tests/series/methods/test_sort_values.py index 121a9fb0d2762..28332a94207fe 100644 --- a/pandas/tests/series/methods/test_sort_values.py +++ b/pandas/tests/series/methods/test_sort_values.py @@ -191,11 +191,13 @@ def test_sort_values_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 sort_values except " - r"for the argument 'self' will be keyword-only" + r"In a future version of pandas all arguments of Series\.sort_values " + r"will be keyword-only" ) with tm.assert_produces_warning(FutureWarning, match=msg): - ser.sort_values(0) + result = ser.sort_values(0) + expected = Series([1, 2, 3]) + tm.assert_series_equal(result, expected) class TestSeriesSortingKey: