Skip to content

REF: Avoid kwargs in rename_axis #51072

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

Merged
merged 12 commits into from
Feb 2, 2023
74 changes: 19 additions & 55 deletions pandas/core/generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,10 +90,7 @@
SettingWithCopyError,
SettingWithCopyWarning,
)
from pandas.util._decorators import (
doc,
rewrite_axis_style_signature,
)
from pandas.util._decorators import doc
from pandas.util._exceptions import find_stack_level
from pandas.util._validators import (
validate_ascending,
Expand Down Expand Up @@ -509,38 +506,6 @@ def _construct_axes_dict(self, axes: Sequence[Axis] | None = None, **kwargs):
d.update(kwargs) # type: ignore[arg-type]
return d

@final
@classmethod
def _construct_axes_from_arguments(
cls, args, kwargs, require_all: bool_t = False, sentinel=None
):
"""
Construct and returns axes if supplied in args/kwargs.

If require_all, raise if all axis arguments are not supplied
return a tuple of (axes, kwargs).

sentinel specifies the default parameter when an axis is not
supplied; useful to distinguish when a user explicitly passes None
in scenarios where None has special meaning.
"""
# construct the args
args = list(args)
for a in cls._AXIS_ORDERS:

# look for a argument by position
if a not in kwargs:
try:
kwargs[a] = args.pop(0)
except IndexError as err:
if require_all:
raise TypeError(
"not enough/duplicate arguments specified!"
) from err

axes = {a: kwargs.pop(a, sentinel) for a in cls._AXIS_ORDERS}
return axes, kwargs

@final
@classmethod
def _get_axis_number(cls, axis: Axis) -> AxisInt:
Expand Down Expand Up @@ -1078,39 +1043,50 @@ def _rename(
def rename_axis(
self: NDFrameT,
mapper: IndexLabel | lib.NoDefault = ...,
index=...,
columns=...,
axis: Axis = ...,
copy: bool_t = ...,
Copy link
Member

Choose a reason for hiding this comment

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

can these be keyword-only?

Copy link
Member Author

Choose a reason for hiding this comment

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

We could deprecate and make them keyword only in a follow up, but as is they cannot be yet.

Copy link
Member

Choose a reason for hiding this comment

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

I'm confused - why can't they be made keyword-only?

These arguments (e.g. index) already can't be passed positionally, so which behaviour which currently works would break?

Copy link
Member Author

Choose a reason for hiding this comment

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

Ah shoot I misread the previous signature. Yeah these should be able to be keyword only

*,
inplace: Literal[False] = ...,
**kwargs,
) -> NDFrameT:
...

@overload
def rename_axis(
self,
mapper: IndexLabel | lib.NoDefault = ...,
index=...,
columns=...,
axis: Axis = ...,
copy: bool_t = ...,
*,
inplace: Literal[True],
**kwargs,
) -> None:
...

@overload
def rename_axis(
self: NDFrameT,
mapper: IndexLabel | lib.NoDefault = ...,
index=...,
columns=...,
axis: Axis = ...,
copy: bool_t = ...,
*,
inplace: bool_t = ...,
**kwargs,
) -> NDFrameT | None:
...

@rewrite_axis_style_signature("mapper", [("copy", True)])
def rename_axis(
self: NDFrameT,
mapper: IndexLabel | lib.NoDefault = lib.no_default,
index=lib.no_default,
columns=lib.no_default,
axis: Axis = 0,
copy: bool_t = True,
*,
inplace: bool_t = False,
**kwargs,
) -> NDFrameT | None:
"""
Set the name of the axis for the index or columns.
Expand Down Expand Up @@ -1235,23 +1211,11 @@ class name
cat 4 0
monkey 2 2
"""
kwargs["inplace"] = inplace
axes, kwargs = self._construct_axes_from_arguments(
(), kwargs, sentinel=lib.no_default
)
copy: bool_t | None = kwargs.pop("copy", None)
axes = {"index": index, "columns": columns}

inplace = kwargs.pop("inplace", False)
axis = kwargs.pop("axis", 0)
if axis is not None:
axis = self._get_axis_number(axis)

if kwargs:
raise TypeError(
"rename_axis() got an unexpected keyword "
f'argument "{list(kwargs.keys())[0]}"'
)

inplace = validate_bool_kwarg(inplace, "inplace")

if mapper is not lib.no_default:
Expand Down Expand Up @@ -4532,7 +4496,7 @@ def drop(
axis_name = self._get_axis_name(axis)
axes = {axis_name: labels}
elif index is not None or columns is not None:
axes, _ = self._construct_axes_from_arguments((index, columns), {})
axes = {"index": index, "columns": columns}
else:
raise ValueError(
"Need to specify at least one of 'labels', 'index' or 'columns'"
Expand Down
31 changes: 0 additions & 31 deletions pandas/util/_decorators.py
Original file line number Diff line number Diff line change
Expand Up @@ -337,36 +337,6 @@ def wrapper(*args, **kwargs):
return decorate


def rewrite_axis_style_signature(
name: str, extra_params: list[tuple[str, Any]]
) -> Callable[[F], F]:
def decorate(func: F) -> F:
@wraps(func)
def wrapper(*args, **kwargs) -> Callable[..., Any]:
return func(*args, **kwargs)

kind = inspect.Parameter.POSITIONAL_OR_KEYWORD
params = [
inspect.Parameter("self", kind),
inspect.Parameter(name, kind, default=None),
inspect.Parameter("index", kind, default=None),
inspect.Parameter("columns", kind, default=None),
inspect.Parameter("axis", kind, default=None),
]

for pname, default in extra_params:
params.append(inspect.Parameter(pname, kind, default=default))

sig = inspect.Signature(params)

# https://github.com/python/typing/issues/598
# error: "F" has no attribute "__signature__"
func.__signature__ = sig # type: ignore[attr-defined]
return cast(F, wrapper)

return decorate


def doc(*docstrings: None | str | Callable, **params) -> Callable[[F], F]:
"""
A decorator take docstring templates, concatenate them and perform string
Expand Down Expand Up @@ -531,6 +501,5 @@ def indent(text: str | None, indents: int = 1) -> str:
"deprecate_nonkeyword_arguments",
"doc",
"future_version_msg",
"rewrite_axis_style_signature",
"Substitution",
]