Skip to content

Commit 3220658

Browse files
committed
TYP: rename (TypeVar approach)
1 parent d2aa44f commit 3220658

File tree

6 files changed

+135
-24
lines changed

6 files changed

+135
-24
lines changed

pandas/_typing.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,10 @@
141141
]
142142

143143
# For functions like rename that convert one label to another
144-
Renamer = Union[Mapping[Hashable, Any], Callable[[Hashable], Hashable]]
144+
HashableT = TypeVar("HashableT", bound=Hashable)
145+
HashableTa = TypeVar("HashableTa", bound=Hashable)
146+
HashableTb = TypeVar("HashableTb", bound=Hashable)
147+
Renamer = Union[Mapping[HashableT, Hashable], Callable[[HashableT], Hashable]]
145148

146149
# to maintain type information across generic functions and parametrization
147150
T = TypeVar("T")

pandas/core/frame.py

Lines changed: 52 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,9 @@
5858
FloatFormatType,
5959
FormattersType,
6060
Frequency,
61+
HashableT,
62+
HashableTa,
63+
HashableTb,
6164
IgnoreRaise,
6265
IndexKeyFunc,
6366
IndexLabel,
@@ -5030,17 +5033,62 @@ def drop( # type: ignore[override]
50305033
errors=errors,
50315034
)
50325035

5036+
@overload
5037+
def rename(
5038+
self,
5039+
mapper: Renamer[HashableT] | None = ...,
5040+
*,
5041+
index: Renamer[HashableTa] | None = ...,
5042+
columns: Renamer[HashableTb] | None = ...,
5043+
axis: Axis | None = ...,
5044+
copy: bool = ...,
5045+
inplace: Literal[True],
5046+
level: Level | None = ...,
5047+
errors: IgnoreRaise = ...,
5048+
) -> None:
5049+
...
5050+
5051+
@overload
5052+
def rename(
5053+
self,
5054+
mapper: Renamer[HashableT] | None = ...,
5055+
*,
5056+
index: Renamer[HashableTa] | None = ...,
5057+
columns: Renamer[HashableTb] | None = ...,
5058+
axis: Axis | None = ...,
5059+
copy: bool = ...,
5060+
inplace: Literal[False] = ...,
5061+
level: Level | None = ...,
5062+
errors: IgnoreRaise = ...,
5063+
) -> DataFrame:
5064+
...
5065+
5066+
@overload
50335067
def rename(
50345068
self,
5035-
mapper: Renamer | None = None,
5069+
mapper: Renamer[HashableT] | None = ...,
50365070
*,
5037-
index: Renamer | None = None,
5038-
columns: Renamer | None = None,
5071+
index: Renamer[HashableTa] | None = ...,
5072+
columns: Renamer[HashableTb] | None = ...,
5073+
axis: Axis | None = ...,
5074+
copy: bool = ...,
5075+
inplace: bool = ...,
5076+
level: Level | None = ...,
5077+
errors: IgnoreRaise = ...,
5078+
) -> DataFrame | None:
5079+
...
5080+
5081+
def rename(
5082+
self,
5083+
mapper: Renamer[HashableT] | None = None,
5084+
*,
5085+
index: Renamer[HashableTa] | None = None,
5086+
columns: Renamer[HashableTb] | None = None,
50395087
axis: Axis | None = None,
50405088
copy: bool = True,
50415089
inplace: bool = False,
50425090
level: Level | None = None,
5043-
errors: str = "ignore",
5091+
errors: IgnoreRaise = "ignore",
50445092
) -> DataFrame | None:
50455093
"""
50465094
Alter axes labels.

pandas/core/generic.py

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@
4444
DtypeArg,
4545
DtypeObj,
4646
FilePath,
47+
HashableT,
48+
HashableTa,
49+
HashableTb,
4750
IgnoreRaise,
4851
IndexKeyFunc,
4952
IndexLabel,
@@ -974,10 +977,10 @@ def squeeze(self, axis=None):
974977

975978
def _rename(
976979
self: NDFrameT,
977-
mapper: Renamer | None = None,
980+
mapper: Renamer[HashableT] | None = None,
978981
*,
979-
index: Renamer | None = None,
980-
columns: Renamer | None = None,
982+
index: Renamer[HashableTa] | None = None,
983+
columns: Renamer[HashableTb] | None = None,
981984
axis: Axis | None = None,
982985
copy: bool_t = True,
983986
inplace: bool_t = False,
@@ -1110,9 +1113,19 @@ def _rename(
11101113
else:
11111114
# use the mapper argument
11121115
if axis and self._get_axis_number(axis) == 1:
1113-
columns = mapper
1116+
# error: Incompatible types in assignment (expression has type
1117+
# "Optional[Union[Mapping[HashableT, Hashable], Callable[
1118+
# [HashableT], Hashable]]]", variable has type "Optional[Union[
1119+
# Mapping[HashableTb, Hashable], Callable[[HashableTb], Hashable
1120+
# ]]]")
1121+
columns = mapper # type: ignore[assignment]
11141122
else:
1115-
index = mapper
1123+
# error: Incompatible types in assignment (expression has type
1124+
# "Optional[Union[Mapping[HashableT, Hashable], Callable[[
1125+
# HashableT], Hashable]]]", variable has type "Optional[Union[
1126+
# Mapping[HashableTa, Hashable], Callable[[HashableTa], Hashable
1127+
# ]]]")
1128+
index = mapper # type: ignore[assignment]
11161129

11171130
self._check_inplace_and_allows_duplicate_labels(inplace)
11181131
result = self if inplace else self.copy(deep=copy)

pandas/core/groupby/groupby.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2204,8 +2204,7 @@ def size(self) -> DataFrame | Series:
22042204
result = self._obj_1d_constructor(result)
22052205

22062206
if not self.as_index:
2207-
# Item "None" of "Optional[Series]" has no attribute "reset_index"
2208-
result = result.rename("size").reset_index() # type: ignore[union-attr]
2207+
result = result.rename("size").reset_index()
22092208

22102209
return self._reindex_output(result, fill_value=0)
22112210

pandas/core/series.py

Lines changed: 56 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,12 @@
3838
Dtype,
3939
DtypeObj,
4040
FillnaOptions,
41+
HashableT,
4142
IgnoreRaise,
4243
IndexKeyFunc,
4344
Level,
4445
NaPosition,
46+
Renamer,
4547
SingleManager,
4648
SortKind,
4749
StorageOptions,
@@ -4617,15 +4619,54 @@ def align(
46174619
broadcast_axis=broadcast_axis,
46184620
)
46194621

4622+
@overload
46204623
def rename(
46214624
self,
4622-
index=None,
4625+
index: Renamer[HashableT] | Hashable | None = ...,
46234626
*,
4624-
axis=None,
4625-
copy=True,
4626-
inplace=False,
4627-
level=None,
4628-
errors="ignore",
4627+
axis: Axis | None = ...,
4628+
copy: bool = ...,
4629+
inplace: Literal[True],
4630+
level: Level | None = ...,
4631+
errors: IgnoreRaise = ...,
4632+
) -> None:
4633+
...
4634+
4635+
@overload
4636+
def rename(
4637+
self,
4638+
index: Renamer[HashableT] | Hashable | None = ...,
4639+
*,
4640+
axis: Axis | None = ...,
4641+
copy: bool = ...,
4642+
inplace: Literal[False] = ...,
4643+
level: Level | None = ...,
4644+
errors: IgnoreRaise = ...,
4645+
) -> Series:
4646+
...
4647+
4648+
@overload
4649+
def rename(
4650+
self,
4651+
index: Renamer[HashableT] | Hashable | None = ...,
4652+
*,
4653+
axis: Axis | None = ...,
4654+
copy: bool = ...,
4655+
inplace: bool = ...,
4656+
level: Level | None = ...,
4657+
errors: IgnoreRaise = ...,
4658+
) -> Series | None:
4659+
...
4660+
4661+
def rename(
4662+
self,
4663+
index: Renamer[HashableT] | Hashable | None = None,
4664+
*,
4665+
axis: Axis | None = None,
4666+
copy: bool = True,
4667+
inplace: bool = False,
4668+
level: Level | None = None,
4669+
errors: IgnoreRaise = "ignore",
46294670
) -> Series | None:
46304671
"""
46314672
Alter Series index labels or name.
@@ -4691,8 +4732,16 @@ def rename(
46914732
axis = self._get_axis_number(axis)
46924733

46934734
if callable(index) or is_dict_like(index):
4735+
# error: Argument 1 to "_rename" of "NDFrame" has incompatible type
4736+
# "Union[Union[Mapping[Hashable, Any], Callable[[Hashable], Hashable]],
4737+
# Hashable, None]"; expected "Union[Mapping[Hashable, Any],
4738+
# Callable[[Hashable], Hashable], None]"
46944739
return super()._rename(
4695-
index, copy=copy, inplace=inplace, level=level, errors=errors
4740+
index, # type: ignore[arg-type]
4741+
copy=copy,
4742+
inplace=inplace,
4743+
level=level,
4744+
errors=errors,
46964745
)
46974746
else:
46984747
return self._set_name(index, inplace=inplace)

pandas/io/json/_normalize.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@
99
import copy
1010
from typing import (
1111
Any,
12+
Callable,
1213
DefaultDict,
14+
Hashable,
1315
Iterable,
1416
)
1517

@@ -520,11 +522,8 @@ def _recursive_extract(data, path, seen_meta, level=0):
520522
result = DataFrame(records)
521523

522524
if record_prefix is not None:
523-
# Incompatible types in assignment (expression has type "Optional[DataFrame]",
524-
# variable has type "DataFrame")
525-
result = result.rename( # type: ignore[assignment]
526-
columns=lambda x: f"{record_prefix}{x}"
527-
)
525+
rename_fun: Callable[[Hashable], str] = lambda x: f"{record_prefix}{x}"
526+
result = result.rename(columns=rename_fun)
528527

529528
# Data types, a problem
530529
for k, v in meta_vals.items():

0 commit comments

Comments
 (0)