Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DEPR: non-keyword arguments in any #44896

Merged
merged 42 commits into from
Apr 10, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
59bd617
tighten return type in any
yadav-sachin Dec 15, 2021
389cb03
correct overload definitions
yadav-sachin Dec 15, 2021
076efc0
add overload def for NDFrame input
yadav-sachin Dec 15, 2021
7f643d6
remove overload defs and define function any in sub-classes
yadav-sachin Dec 16, 2021
d6df993
Merge branch 'master' of github.com:pandas-dev/pandas into any_return…
yadav-sachin Dec 16, 2021
d2653da
add overload defs for level
yadav-sachin Dec 17, 2021
0f15b62
correct default val in overload defs
yadav-sachin Dec 17, 2021
831481c
deprecate non-keyword args
yadav-sachin Dec 18, 2021
284efd3
add whatsnew note
yadav-sachin Dec 21, 2021
e002897
modify return types and add tests
yadav-sachin Dec 21, 2021
912b040
Merge branch 'master' of github.com:pandas-dev/pandas into any_return…
yadav-sachin Dec 21, 2021
b229a3b
move non-keyword deprecation to generic
yadav-sachin Dec 24, 2021
0c3ebd7
correct deprecation decorators
yadav-sachin Dec 24, 2021
799e12b
Merge remote branch 'main' into any_return_type
yadav-sachin Feb 28, 2022
3441523
Merge remote-tracking branch 'upstream/main' into any_return_type
yadav-sachin Mar 3, 2022
cdb96f7
remove imports in test assertions
yadav-sachin Apr 1, 2022
49a1b0b
Merge remote-tracking branch 'upstream/main' into any_return_type
yadav-sachin Apr 1, 2022
76003ed
place deprecate_nonkeyword at correct place
yadav-sachin Apr 4, 2022
787616d
remove changes from frame.py, series.py
yadav-sachin Apr 4, 2022
0375347
readd changes in frame, series without actual implementations
yadav-sachin Apr 4, 2022
5573d34
Merge remote-tracking branch 'upstream/main' into any_return_type
yadav-sachin Apr 4, 2022
a13ee6f
place deprecate_nonkeyword at other place
yadav-sachin Apr 4, 2022
6e5b3ac
add name argument to deprecate_non_keyword_args decorator
yadav-sachin Apr 4, 2022
63ae9c1
add test for name in deprecate_nonkeyword_args
yadav-sachin Apr 4, 2022
1010e1e
remove changes from frame.py, series.py
yadav-sachin Apr 4, 2022
424b213
correct stacklevel in warning
yadav-sachin Apr 4, 2022
8007cf1
correct stacklevel
MarcoGorelli Apr 4, 2022
a361637
set stacklevel to default
yadav-sachin Apr 4, 2022
ea19d40
merge upstream/any_return_type into any_return_type
yadav-sachin Apr 5, 2022
2678298
move deprecation message to whatsnew v1.5.0.rst
yadav-sachin Apr 5, 2022
96de045
add name parameter in deprecate_non_keyword_args docstring
yadav-sachin Apr 5, 2022
86ad6ba
correct whitespace in deprecate_nonkeyword_args docstring
yadav-sachin Apr 5, 2022
7dec331
Merge remote-tracking branch 'upstream/main' into any_return_type
yadav-sachin Apr 5, 2022
b4b3a1f
update any non-keyword args in other tests
yadav-sachin Apr 7, 2022
11917aa
update any in doc
yadav-sachin Apr 7, 2022
35c71b6
update remaining any() calls in pandas/core
yadav-sachin Apr 7, 2022
0e6d5eb
correct docstring of isocalendar in pandas/core/indexes/accessors.py
yadav-sachin Apr 8, 2022
025c493
Merge remote-tracking branch 'upstream/main' into any_return_type
yadav-sachin Apr 8, 2022
59ac830
Merge branch 'main' into any_return_type
MarcoGorelli Apr 8, 2022
d9d14e9
Merge remote-tracking branch 'upstream/main' into any_return_type
yadav-sachin Apr 9, 2022
15bbc86
Merge branch 'any_return_type' of github.com:yadav-sachin/pandas into…
yadav-sachin Apr 9, 2022
a8dd741
Merge remote-tracking branch 'upstream/main' into any_return_type
yadav-sachin Apr 10, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion doc/source/whatsnew/v0.13.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -664,7 +664,7 @@ Enhancements
other = pd.DataFrame({'A': [1, 3, 3, 7], 'B': ['e', 'f', 'f', 'e']})
mask = dfi.isin(other)
mask
dfi[mask.any(1)]
dfi[mask.any(axis=1)]

- ``Series`` now supports a ``to_frame`` method to convert it to a single-column DataFrame (:issue:`5164`)

Expand Down
1 change: 1 addition & 0 deletions doc/source/whatsnew/v1.5.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -429,6 +429,7 @@ Other Deprecations
- Deprecated behavior of method :meth:`DataFrame.quantile`, attribute ``numeric_only`` will default False. Including datetime/timedelta columns in the result (:issue:`7308`).
- Deprecated :attr:`Timedelta.freq` and :attr:`Timedelta.is_populated` (:issue:`46430`)
- Deprecated :attr:`Timedelta.delta` (:issue:`46476`)
- Deprecated passing arguments as positional in :meth:`DataFrame.any` and :meth:`Series.any` (:issue:`44802`)
- Deprecated the ``closed`` argument in :meth:`interval_range` in favor of ``inclusive`` argument; In a future version passing ``closed`` will raise (:issue:`40245`)
- Deprecated the methods :meth:`DataFrame.mad`, :meth:`Series.mad`, and the corresponding groupby methods (:issue:`11787`)

Expand Down
10 changes: 8 additions & 2 deletions pandas/core/generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -7224,7 +7224,7 @@ def asof(self, where, subset=None):
if not isinstance(where, Index):
where = Index(where) if is_list else Index([where])

nulls = self.isna() if is_series else self[subset].isna().any(1)
nulls = self.isna() if is_series else self[subset].isna().any(axis=1)
if nulls.all():
if is_series:
self = cast("Series", self)
Expand Down Expand Up @@ -10517,7 +10517,7 @@ def any(
skipna: bool_t = True,
level: Level | None = None,
**kwargs,
) -> Series | bool_t:
) -> DataFrame | Series | bool_t:
return self._logical_func(
"any", nanops.nanany, axis, bool_only, skipna, level, **kwargs
)
Expand Down Expand Up @@ -10941,6 +10941,12 @@ def _add_numeric_operations(cls):
"""
axis_descr, name1, name2 = _doc_params(cls)

@deprecate_nonkeyword_arguments(
version=None,
allowed_args=["self"],
stacklevel=find_stack_level() - 1,
Copy link
Contributor Author

@yadav-sachin yadav-sachin Apr 4, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removing the stacklevel from args in decorator (default value of 2) also works here 🤔

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

its not correct to evaluate this at compile time. what should happen is that the deprecater can call find_stack_level

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jreback I don't understand what you mean, how should this be?

Just setting stacklevel=find_stack_level() doesn't work because any is inside _add_numeric_operations and is set via setattr(cls, "any", any)

pandas/pandas/core/generic.py

Lines 10928 to 10948 in 073b353

@classmethod
def _add_numeric_operations(cls):
"""
Add the operations to the cls; evaluate the doc strings again
"""
axis_descr, name1, name2 = _doc_params(cls)
@doc(
_bool_doc,
desc=_any_desc,
name1=name1,
name2=name2,
axis_descr=axis_descr,
see_also=_any_see_also,
examples=_any_examples,
empty_value=False,
)
def any(self, axis=0, bool_only=None, skipna=True, level=None, **kwargs):
return NDFrame.any(self, axis, bool_only, skipna, level, **kwargs)
setattr(cls, "any", any)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i mean this needs to be handled in the decorator itself not here.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's done in the decorator in other places though

@deprecate_nonkeyword_arguments(
version=None, allowed_args=["filepath_or_buffer"], stacklevel=3
)

I've made an issue to handle this in the decorator itself #46687 , is it OK to keep that separate from this PR?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok i c, yeah we out to fix this but ok for here

name="DataFrame.any and Series.any",
)
@doc(
_bool_doc,
desc=_any_desc,
Expand Down
2 changes: 1 addition & 1 deletion pandas/core/missing.py
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ def find_valid_index(values, *, how: str) -> int | None:
is_valid = ~isna(values)

if values.ndim == 2:
is_valid = is_valid.any(1) # reduce axis 1
is_valid = is_valid.any(axis=1) # reduce axis 1

if how == "first":
idxpos = is_valid[::].argmax()
Expand Down
6 changes: 3 additions & 3 deletions pandas/tests/frame/test_reductions.py
Original file line number Diff line number Diff line change
Expand Up @@ -1066,11 +1066,11 @@ def test_any_all_extra(self):
},
index=["a", "b", "c"],
)
result = df[["A", "B"]].any(1)
result = df[["A", "B"]].any(axis=1)
expected = Series([True, True, False], index=["a", "b", "c"])
tm.assert_series_equal(result, expected)

result = df[["A", "B"]].any(1, bool_only=True)
result = df[["A", "B"]].any(axis=1, bool_only=True)
tm.assert_series_equal(result, expected)

result = df.all(1)
Expand Down Expand Up @@ -1119,7 +1119,7 @@ def test_any_datetime(self):
]
df = DataFrame({"A": float_data, "B": datetime_data})

result = df.any(1)
result = df.any(axis=1)
expected = Series([True, True, True, False])
tm.assert_series_equal(result, expected)

Expand Down
22 changes: 22 additions & 0 deletions pandas/tests/groupby/test_any_all.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,28 @@ def test_any():
tm.assert_frame_equal(result, expected)


def test_any_non_keyword_deprecation():
df = DataFrame({"A": [1, 2], "B": [0, 2], "C": [0, 0]})
msg = (
"In a future version of pandas all arguments of "
"DataFrame.any and Series.any will be keyword-only."
)
with tm.assert_produces_warning(FutureWarning, match=msg):
MarcoGorelli marked this conversation as resolved.
Show resolved Hide resolved
result = df.any("index", None)
expected = Series({"A": True, "B": True, "C": False})
tm.assert_series_equal(result, expected)

s = Series([False, False, False])
msg = (
"In a future version of pandas all arguments of "
"DataFrame.any and Series.any will be keyword-only."
)
with tm.assert_produces_warning(FutureWarning, match=msg):
result = s.any("index")
expected = False
tm.assert_equal(result, expected)


@pytest.mark.parametrize("bool_agg_func", ["any", "all"])
def test_bool_aggs_dup_column_labels(bool_agg_func):
# 21668
Expand Down
17 changes: 16 additions & 1 deletion pandas/tests/util/test_deprecate_nonkeyword_arguments.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@
import pandas._testing as tm


@deprecate_nonkeyword_arguments(version="1.1", allowed_args=["a", "b"])
@deprecate_nonkeyword_arguments(
version="1.1", allowed_args=["a", "b"], name="f_add_inputs"
)
def f(a, b=0, c=0, d=0):
return a + b + c + d

Expand Down Expand Up @@ -44,6 +46,19 @@ def test_four_arguments():
assert f(1, 2, 3, 4) == 10


def test_three_arguments_with_name_in_warning():
with warnings.catch_warnings(record=True) as w:
warnings.simplefilter("always")
assert f(6, 3, 3) == 12
assert len(w) == 1
for actual_warning in w:
assert actual_warning.category == FutureWarning
assert str(actual_warning.message) == (
"Starting with pandas version 1.1 all arguments of f_add_inputs "
twoertwein marked this conversation as resolved.
Show resolved Hide resolved
"except for the arguments 'a' and 'b' will be keyword-only."
)


@deprecate_nonkeyword_arguments(version="1.1")
def g(a, b=0, c=0, d=0):
with tm.assert_produces_warning(None):
Expand Down
8 changes: 7 additions & 1 deletion pandas/util/_decorators.py
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,7 @@ def deprecate_nonkeyword_arguments(
version: str | None,
allowed_args: list[str] | None = None,
stacklevel: int = 2,
name: str | None = None,
) -> Callable[[F], F]:
"""
Decorator to deprecate a use of non-keyword arguments of a function.
Expand All @@ -281,6 +282,11 @@ def deprecate_nonkeyword_arguments(

stacklevel : int, default=2
The stack level for warnings.warn

name : str, optional
The specific name of the function to show in the warning
message. If None, then the Qualified name of the function
is used.
"""

def decorate(func):
Expand All @@ -296,7 +302,7 @@ def decorate(func):
num_allow_args = len(allow_args)
msg = (
f"{future_version_msg(version)} all arguments of "
f"{func.__qualname__}{{arguments}} will be keyword-only."
f"{name or func.__qualname__}{{arguments}} will be keyword-only."
)

@wraps(func)
Expand Down