From e16c3ebb438fbf16e268983bd389f81632e44a56 Mon Sep 17 00:00:00 2001 From: Stijn de Gooijer Date: Mon, 13 Feb 2023 19:40:06 +0100 Subject: [PATCH] refactor(python): Deprecate non-keyword args for some functions (#6851) --- py-polars/polars/internals/dataframe/frame.py | 15 +++++++++++++-- py-polars/polars/internals/expr/expr.py | 9 ++++++++- py-polars/polars/internals/lazy_functions.py | 6 ++++++ py-polars/polars/internals/lazyframe/frame.py | 10 +++++++++- py-polars/polars/internals/series/series.py | 12 ++++++++++++ py-polars/polars/utils.py | 2 +- py-polars/tests/unit/test_utils.py | 2 +- 7 files changed, 50 insertions(+), 6 deletions(-) diff --git a/py-polars/polars/internals/dataframe/frame.py b/py-polars/polars/internals/dataframe/frame.py index 8d8ec9584510..2e1fcc7b20f4 100644 --- a/py-polars/polars/internals/dataframe/frame.py +++ b/py-polars/polars/internals/dataframe/frame.py @@ -4105,6 +4105,7 @@ def upsample( self._df.upsample(by, time_column, every, offset, maintain_order) ) + @deprecate_nonkeyword_arguments() def join_asof( self, other: DataFrame, @@ -4255,7 +4256,7 @@ def join_asof( @deprecate_nonkeyword_arguments( message=( "All arguments of DataFrame.join except for 'other', 'on', and 'how' will be keyword-only in the next breaking release." - " Use keyword arguments to silence this message." + " Use keyword arguments to silence this warning." ) ) def join( @@ -4388,6 +4389,7 @@ def join( .collect(no_optimization=True) ) + @deprecate_nonkeyword_arguments(allowed_args=["self", "f", "return_dtype"]) def apply( self, f: Callable[[tuple[Any, ...]], Any], @@ -5029,6 +5031,9 @@ def explode( """ return self.lazy().explode(columns).collect(no_optimization=True) + @deprecate_nonkeyword_arguments( + allowed_args=["self", "values", "index", "columns", "aggregate_fn"] + ) def pivot( self, values: Sequence[str] | str, @@ -6390,7 +6395,7 @@ def quantile( return self._from_pydf(self._df.quantile(quantile, interpolation)) def to_dummies( - self, *, columns: Sequence[str] | None = None, separator: str = "_" + self, columns: Sequence[str] | None = None, *, separator: str = "_" ) -> Self: """ Get one hot encoded dummy variables. @@ -6428,6 +6433,12 @@ def to_dummies( columns = [columns] return self._from_pydf(self._df.to_dummies(columns, separator)) + @deprecate_nonkeyword_arguments( + message=( + "All arguments of DataFrame.unique except for 'subset' will be keyword-only in the next breaking release." + " Use keyword arguments to silence this warning." + ) + ) def unique( self, maintain_order: bool = True, diff --git a/py-polars/polars/internals/expr/expr.py b/py-polars/polars/internals/expr/expr.py index 858fb8dde96e..a58aa3d1a25a 100644 --- a/py-polars/polars/internals/expr/expr.py +++ b/py-polars/polars/internals/expr/expr.py @@ -26,7 +26,11 @@ from polars.internals.expr.string import ExprStringNameSpace from polars.internals.expr.struct import ExprStructNameSpace from polars.internals.type_aliases import PolarsExprType, PythonLiteral -from polars.utils import _timedelta_to_pl_duration, sphinx_accessor +from polars.utils import ( + _timedelta_to_pl_duration, + deprecate_nonkeyword_arguments, + sphinx_accessor, +) try: from polars.polars import PyExpr @@ -1804,6 +1808,7 @@ def top_k(self, k: int = 5, reverse: bool = False) -> Expr: """ return wrap_expr(self._pyexpr.top_k(k, reverse)) + @deprecate_nonkeyword_arguments() def arg_sort(self, reverse: bool = False, nulls_last: bool = False) -> Expr: """ Get the index values that would sort this column. @@ -2980,6 +2985,7 @@ def where(self, predicate: Expr) -> Expr: """ return self.filter(predicate) + @deprecate_nonkeyword_arguments(allowed_args=["self", "f", "return_dtype"]) def map( self, f: Callable[[pli.Series], pli.Series | Any], @@ -3029,6 +3035,7 @@ def map( return_dtype = py_type_to_dtype(return_dtype) return wrap_expr(self._pyexpr.map(f, return_dtype, agg_list)) + @deprecate_nonkeyword_arguments(allowed_args=["self", "f", "return_dtype"]) def apply( self, f: Callable[[pli.Series], pli.Series] | Callable[[Any], Any], diff --git a/py-polars/polars/internals/lazy_functions.py b/py-polars/polars/internals/lazy_functions.py index 847462373617..2e06f46343b6 100644 --- a/py-polars/polars/internals/lazy_functions.py +++ b/py-polars/polars/internals/lazy_functions.py @@ -29,6 +29,7 @@ _datetime_to_pl_timestamp, _time_to_pl_time, _timedelta_to_pl_timedelta, + deprecate_nonkeyword_arguments, ) try: @@ -1413,6 +1414,7 @@ def map( ) +@deprecate_nonkeyword_arguments(allowed_args=["exprs", "f", "return_dtype"]) def apply( exprs: Sequence[str | pli.Expr], f: Callable[[Sequence[pli.Series]], pli.Series | Any], @@ -1516,6 +1518,7 @@ def reduce( return pli.wrap_expr(pyreduce(f, exprs)) +@deprecate_nonkeyword_arguments() def cumfold( acc: IntoExpr, f: Callable[[pli.Series, pli.Series], pli.Series], @@ -1835,6 +1838,7 @@ def arange( ) +@deprecate_nonkeyword_arguments() def arg_sort_by( exprs: pli.Expr | str | Sequence[pli.Expr | str], reverse: Sequence[bool] | bool = False, @@ -2060,6 +2064,7 @@ def _date( return _datetime(year, month, day).cast(Date).alias("date") +@deprecate_nonkeyword_arguments() def concat_str(exprs: Sequence[pli.Expr | str] | pli.Expr, sep: str = "") -> pli.Expr: """ Horizontally concat Utf8 Series in linear time. Non-Utf8 columns are cast to Utf8. @@ -2357,6 +2362,7 @@ def struct( ... +@deprecate_nonkeyword_arguments() def struct( exprs: Sequence[pli.Expr | str | pli.Series] | pli.Expr | pli.Series, eager: bool = False, diff --git a/py-polars/polars/internals/lazyframe/frame.py b/py-polars/polars/internals/lazyframe/frame.py index d32c9843655a..4707c48d393d 100644 --- a/py-polars/polars/internals/lazyframe/frame.py +++ b/py-polars/polars/internals/lazyframe/frame.py @@ -2155,6 +2155,7 @@ def groupby_dynamic( ) return LazyGroupBy(lgb, lazyframe_class=self.__class__) + @deprecate_nonkeyword_arguments() def join_asof( self, other: LazyFrame, @@ -2329,7 +2330,7 @@ def join_asof( @deprecate_nonkeyword_arguments( message=( "All arguments of LazyFrame.join except for 'other', 'on', and 'how' will be keyword-only in the next breaking release." - " Use keyword arguments to silence this message." + " Use keyword arguments to silence this warning." ) ) def join( @@ -3590,6 +3591,12 @@ def explode( columns = pli.selection_to_pyexpr_list(columns) return self._from_pyldf(self._ldf.explode(columns)) + @deprecate_nonkeyword_arguments( + message=( + "All arguments of LazyFrame.unique except for 'subset' will be keyword-only in the next breaking release." + " Use keyword arguments to silence this warning." + ) + ) def unique( self, maintain_order: bool = True, @@ -3808,6 +3815,7 @@ def melt( self._ldf.melt(id_vars, value_vars, value_name, variable_name) ) + @deprecate_nonkeyword_arguments() def map( self, f: Callable[[pli.DataFrame], pli.DataFrame], diff --git a/py-polars/polars/internals/series/series.py b/py-polars/polars/internals/series/series.py index a6f8f2e4afeb..2d110bd8c95d 100644 --- a/py-polars/polars/internals/series/series.py +++ b/py-polars/polars/internals/series/series.py @@ -75,6 +75,7 @@ _datetime_to_pl_timestamp, _is_generator, _time_to_pl_time, + deprecate_nonkeyword_arguments, deprecated_alias, is_int_sequence, range_to_series, @@ -1370,6 +1371,7 @@ def quantile( """ return self._s.quantile(quantile, interpolation) + @deprecate_nonkeyword_arguments() def to_dummies(self, separator: str = "_") -> pli.DataFrame: """ Get dummy variables. @@ -1965,6 +1967,7 @@ def top_k(self, k: int = 5, reverse: bool = False) -> Series: """ + @deprecate_nonkeyword_arguments() def arg_sort(self, reverse: bool = False, nulls_last: bool = False) -> Series: """ Get the index values that would sort this Series. @@ -1991,6 +1994,14 @@ def arg_sort(self, reverse: bool = False, nulls_last: bool = False) -> Series: ] """ + return ( + pli.wrap_s(self._s) + .to_frame() + .select( + pli.col(self._s.name()).arg_sort(reverse=reverse, nulls_last=nulls_last) + ) + .to_series() + ) def argsort(self, reverse: bool = False, nulls_last: bool = False) -> Series: """ @@ -3536,6 +3547,7 @@ def tanh(self) -> Series: """ + @deprecate_nonkeyword_arguments(allowed_args=["self", "func", "return_dtype"]) def apply( self, func: Callable[[Any], Any], diff --git a/py-polars/polars/utils.py b/py-polars/polars/utils.py index e20ee5e1e5ff..bfcd046e20c9 100644 --- a/py-polars/polars/utils.py +++ b/py-polars/polars/utils.py @@ -503,7 +503,7 @@ def decorate(fn: Callable[P, T]) -> Callable[P, T]: if message is None: msg_format = ( f"All arguments of {fn.__qualname__}{{except_args}} will be keyword-only in the next breaking release." - " Use keyword arguments to silence this message." + " Use keyword arguments to silence this warning." ) msg = msg_format.format(except_args=_format_argument_list(allow_args)) else: diff --git a/py-polars/tests/unit/test_utils.py b/py-polars/tests/unit/test_utils.py index ec29308d3865..35811f24c3cb 100644 --- a/py-polars/tests/unit/test_utils.py +++ b/py-polars/tests/unit/test_utils.py @@ -93,7 +93,7 @@ def test_deprecate_nonkeyword_arguments_method_signature() -> None: def test_deprecate_nonkeyword_arguments_method_warning() -> None: msg = ( r"All arguments of Foo\.bar except for \'baz\' will be keyword-only in the next breaking release." - r" Use keyword arguments to silence this message." + r" Use keyword arguments to silence this warning." ) with pytest.deprecated_call(match=msg): Foo().bar("qux", "quox")