From 64575f60351ff1eb6cd683bfc8af4f8d7c73b27f Mon Sep 17 00:00:00 2001 From: Loic Diridollou Date: Sun, 2 Mar 2025 11:39:46 -0500 Subject: [PATCH 1/8] GH1139 Series.rename inplace --- pandas-stubs/core/indexes/base.pyi | 2 +- pandas-stubs/core/series.pyi | 17 ++++++++++++--- tests/test_series.py | 35 +++++++++++++++++++++++------- 3 files changed, 42 insertions(+), 12 deletions(-) diff --git a/pandas-stubs/core/indexes/base.pyi b/pandas-stubs/core/indexes/base.pyi index 5ebdcd224..a28ec8c1b 100644 --- a/pandas-stubs/core/indexes/base.pyi +++ b/pandas-stubs/core/indexes/base.pyi @@ -67,7 +67,7 @@ class Index(IndexOpsMixin[S1]): __hash__: ClassVar[None] # type: ignore[assignment] # overloads with additional dtypes @overload - def __new__( + def __new__( # pyright: ignore[reportOverlappingOverload] cls, data: Sequence[int | np.integer] | IndexOpsMixin[int] | np_ndarray_anyint, *, diff --git a/pandas-stubs/core/series.pyi b/pandas-stubs/core/series.pyi index 2ade583c7..b8e925a94 100644 --- a/pandas-stubs/core/series.pyi +++ b/pandas-stubs/core/series.pyi @@ -249,7 +249,7 @@ class Series(IndexOpsMixin[S1], NDFrame): copy: bool = ..., ) -> Series[float]: ... @overload - def __new__( # type: ignore[overload-overlap] + def __new__( # type: ignore[overload-overlap] # pyright: ignore[reportOverlappingOverload] cls, data: Sequence[Never], index: Axes | None = ..., @@ -1041,9 +1041,20 @@ class Series(IndexOpsMixin[S1], NDFrame): broadcast_axis: AxisIndex | None = ..., ) -> tuple[Series, Series]: ... @overload - def rename( + def rename( # pyright: ignore[reportOverlappingOverload] self, - index: Renamer | Hashable | None = ..., + index: Hashable = ..., + *, + axis: Axis | None = ..., + copy: bool = ..., + inplace: Literal[True], + level: Level | None = ..., + errors: IgnoreRaise = ..., + ) -> Self: ... + @overload + def rename( # type: ignore[overload-cannot-match] + self, + index: Renamer | None = ..., *, axis: Axis | None = ..., copy: bool = ..., diff --git a/tests/test_series.py b/tests/test_series.py index 0c700fcbd..b391c6106 100644 --- a/tests/test_series.py +++ b/tests/test_series.py @@ -70,6 +70,7 @@ TimedeltaSeries: TypeAlias = pd.Series TimestampSeries: TypeAlias = pd.Series OffsetSeries: TypeAlias = pd.Series + ExtensionArray: TypeAlias = np.ndarray if TYPE_CHECKING: from pandas._typing import ( @@ -1137,7 +1138,6 @@ def test_types_set_flags() -> None: def test_types_getitem() -> None: s = pd.Series({"key": [0, 1, 2, 3]}) - key: list[int] = s["key"] s2 = pd.Series([0, 1, 2, 3]) check(assert_type(s2[0], int), np.integer) check(assert_type(s[:2], pd.Series), pd.Series) @@ -1180,12 +1180,28 @@ def test_types_rename_axis() -> None: def test_types_values() -> None: - n1: np.ndarray | ExtensionArray = pd.Series([1, 2, 3]).values - n2: np.ndarray | ExtensionArray = pd.Series(list("aabc")).values - n3: np.ndarray | ExtensionArray = pd.Series(list("aabc")).astype("category").values - n4: np.ndarray | ExtensionArray = pd.Series( - pd.date_range("20130101", periods=3, tz="US/Eastern") - ).values + check( + assert_type(pd.Series([1, 2, 3]).values, "np.ndarray | ExtensionArray"), + np.ndarray, + ) + check( + assert_type(pd.Series(list("aabc")).values, " np.ndarray | ExtensionArray "), + np.ndarray, + ) + check( + assert_type( + pd.Series(list("aabc")).astype("category").values, + "np.ndarray | ExtensionArray", + ), + pd.Categorical, + ) + check( + assert_type( + pd.Series(pd.date_range("20130101", periods=3, tz="US/Eastern")).values, + "np.ndarray | ExtensionArray", + ), + np.ndarray, + ) def test_types_rename() -> None: @@ -1212,7 +1228,10 @@ def add1(x: int) -> int: check(assert_type(s5, "pd.Series[int]"), pd.Series, np.integer) # inplace # TODO fix issue with inplace=True returning a Series, cf pandas #60942 - s6: None = pd.Series([1, 2, 3]).rename("A", inplace=True) + check( + assert_type(pd.Series([1, 2, 3]).rename("A", inplace=True), "pd.Series[int]"), + pd.Series, + ) if TYPE_CHECKING_INVALID_USAGE: s7 = pd.Series([1, 2, 3]).rename({1: [3, 4, 5]}) # type: ignore[arg-type] # pyright: ignore[reportArgumentType] From 36de55b3111279f652d43d2aa8a56d2d5fce8bd6 Mon Sep 17 00:00:00 2001 From: Loic Diridollou Date: Sun, 2 Mar 2025 11:47:36 -0500 Subject: [PATCH 2/8] Fix linter --- pandas-stubs/core/indexes/base.pyi | 2 +- pandas-stubs/core/series.pyi | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pandas-stubs/core/indexes/base.pyi b/pandas-stubs/core/indexes/base.pyi index a28ec8c1b..5ebdcd224 100644 --- a/pandas-stubs/core/indexes/base.pyi +++ b/pandas-stubs/core/indexes/base.pyi @@ -67,7 +67,7 @@ class Index(IndexOpsMixin[S1]): __hash__: ClassVar[None] # type: ignore[assignment] # overloads with additional dtypes @overload - def __new__( # pyright: ignore[reportOverlappingOverload] + def __new__( cls, data: Sequence[int | np.integer] | IndexOpsMixin[int] | np_ndarray_anyint, *, diff --git a/pandas-stubs/core/series.pyi b/pandas-stubs/core/series.pyi index b8e925a94..de8c57989 100644 --- a/pandas-stubs/core/series.pyi +++ b/pandas-stubs/core/series.pyi @@ -249,7 +249,7 @@ class Series(IndexOpsMixin[S1], NDFrame): copy: bool = ..., ) -> Series[float]: ... @overload - def __new__( # type: ignore[overload-overlap] # pyright: ignore[reportOverlappingOverload] + def __new__( # type: ignore[overload-overlap] cls, data: Sequence[Never], index: Axes | None = ..., From 1b6e4c7fec220305f2880843829b8c02a8406a3c Mon Sep 17 00:00:00 2001 From: Loic Diridollou Date: Tue, 4 Mar 2025 17:45:34 -0500 Subject: [PATCH 3/8] GH1139 PR Feedback --- pandas-stubs/core/series.pyi | 6 +++--- tests/test_series.py | 11 ++++++++++- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/pandas-stubs/core/series.pyi b/pandas-stubs/core/series.pyi index b8e925a94..4accfa1dc 100644 --- a/pandas-stubs/core/series.pyi +++ b/pandas-stubs/core/series.pyi @@ -1041,9 +1041,9 @@ class Series(IndexOpsMixin[S1], NDFrame): broadcast_axis: AxisIndex | None = ..., ) -> tuple[Series, Series]: ... @overload - def rename( # pyright: ignore[reportOverlappingOverload] + def rename( self, - index: Hashable = ..., + index: Hashable, *, axis: Axis | None = ..., copy: bool = ..., @@ -1052,7 +1052,7 @@ class Series(IndexOpsMixin[S1], NDFrame): errors: IgnoreRaise = ..., ) -> Self: ... @overload - def rename( # type: ignore[overload-cannot-match] + def rename( self, index: Renamer | None = ..., *, diff --git a/tests/test_series.py b/tests/test_series.py index b391c6106..68f9f4cae 100644 --- a/tests/test_series.py +++ b/tests/test_series.py @@ -1138,6 +1138,7 @@ def test_types_set_flags() -> None: def test_types_getitem() -> None: s = pd.Series({"key": [0, 1, 2, 3]}) + check(assert_type(s["key"], Any), list) s2 = pd.Series([0, 1, 2, 3]) check(assert_type(s2[0], int), np.integer) check(assert_type(s[:2], pd.Series), pd.Series) @@ -1227,11 +1228,19 @@ def add1(x: int) -> int: s5 = pd.Series([1, 2, 3]).rename({1: 10}) check(assert_type(s5, "pd.Series[int]"), pd.Series, np.integer) # inplace - # TODO fix issue with inplace=True returning a Series, cf pandas #60942 check( assert_type(pd.Series([1, 2, 3]).rename("A", inplace=True), "pd.Series[int]"), pd.Series, + np.integer, + ) + check( + assert_type(pd.Series([1, 2, 3]).rename({1: 4, 2: 5}, inplace=True), None), + type(None), ) + # TODO this should not raise an error, the lambda is matched with Hashable + # check( + # assert_type(pd.Series([1, 2, 3]).rename(lambda x: x**2, inplace=True), None), type(None) + # ) if TYPE_CHECKING_INVALID_USAGE: s7 = pd.Series([1, 2, 3]).rename({1: [3, 4, 5]}) # type: ignore[arg-type] # pyright: ignore[reportArgumentType] From 17a1049a012fa809c0392c71b75adbf14b85ab18 Mon Sep 17 00:00:00 2001 From: Loic Diridollou Date: Tue, 4 Mar 2025 17:47:53 -0500 Subject: [PATCH 4/8] GH1139 PR Feedback --- pandas-stubs/core/series.pyi | 11 +++++++++++ tests/test_series.py | 4 ++++ 2 files changed, 15 insertions(+) diff --git a/pandas-stubs/core/series.pyi b/pandas-stubs/core/series.pyi index 4accfa1dc..2b6fd92c0 100644 --- a/pandas-stubs/core/series.pyi +++ b/pandas-stubs/core/series.pyi @@ -1041,6 +1041,17 @@ class Series(IndexOpsMixin[S1], NDFrame): broadcast_axis: AxisIndex | None = ..., ) -> tuple[Series, Series]: ... @overload + def rename( + self, + index: None = ..., + *, + axis: Axis | None = ..., + copy: bool = ..., + inplace: Literal[True], + level: Level | None = ..., + errors: IgnoreRaise = ..., + ) -> None: ... + @overload def rename( self, index: Hashable, diff --git a/tests/test_series.py b/tests/test_series.py index 68f9f4cae..13e4c2157 100644 --- a/tests/test_series.py +++ b/tests/test_series.py @@ -1237,6 +1237,10 @@ def add1(x: int) -> int: assert_type(pd.Series([1, 2, 3]).rename({1: 4, 2: 5}, inplace=True), None), type(None), ) + check( + assert_type(pd.Series([1, 2, 3]).rename(index=None, inplace=True), None), + type(None), + ) # TODO this should not raise an error, the lambda is matched with Hashable # check( # assert_type(pd.Series([1, 2, 3]).rename(lambda x: x**2, inplace=True), None), type(None) From 470ccf49707b89b06abd6a1a2c4b81c6931b7771 Mon Sep 17 00:00:00 2001 From: Loic Diridollou Date: Tue, 4 Mar 2025 18:02:39 -0500 Subject: [PATCH 5/8] GH1139 PR Feedback --- pandas-stubs/core/series.pyi | 15 ++------------- tests/test_series.py | 7 +++++-- 2 files changed, 7 insertions(+), 15 deletions(-) diff --git a/pandas-stubs/core/series.pyi b/pandas-stubs/core/series.pyi index 2b6fd92c0..a784e6986 100644 --- a/pandas-stubs/core/series.pyi +++ b/pandas-stubs/core/series.pyi @@ -1043,18 +1043,7 @@ class Series(IndexOpsMixin[S1], NDFrame): @overload def rename( self, - index: None = ..., - *, - axis: Axis | None = ..., - copy: bool = ..., - inplace: Literal[True], - level: Level | None = ..., - errors: IgnoreRaise = ..., - ) -> None: ... - @overload - def rename( - self, - index: Hashable, + index: Hashable | None, *, axis: Axis | None = ..., copy: bool = ..., @@ -1065,7 +1054,7 @@ class Series(IndexOpsMixin[S1], NDFrame): @overload def rename( self, - index: Renamer | None = ..., + index: Renamer = ..., *, axis: Axis | None = ..., copy: bool = ..., diff --git a/tests/test_series.py b/tests/test_series.py index 13e4c2157..475b036dd 100644 --- a/tests/test_series.py +++ b/tests/test_series.py @@ -1238,8 +1238,11 @@ def add1(x: int) -> int: type(None), ) check( - assert_type(pd.Series([1, 2, 3]).rename(index=None, inplace=True), None), - type(None), + assert_type( + pd.Series([1, 2, 3]).rename(index=None, inplace=True), "pd.Series[int]" + ), + pd.Series, + np.integer, ) # TODO this should not raise an error, the lambda is matched with Hashable # check( From 5f18c666f06bf76008cf044953190ca19d22bf46 Mon Sep 17 00:00:00 2001 From: Loic Diridollou Date: Tue, 4 Mar 2025 23:02:29 -0500 Subject: [PATCH 6/8] GH1139 PR Feedback --- pandas-stubs/core/series.pyi | 20 ++++++++++++++++---- tests/test_series.py | 6 ++---- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/pandas-stubs/core/series.pyi b/pandas-stubs/core/series.pyi index a784e6986..bace0e42f 100644 --- a/pandas-stubs/core/series.pyi +++ b/pandas-stubs/core/series.pyi @@ -25,6 +25,7 @@ from typing import ( ) from _typing import ( + Label, ReplaceValue, TimeZones, ) @@ -1041,20 +1042,20 @@ class Series(IndexOpsMixin[S1], NDFrame): broadcast_axis: AxisIndex | None = ..., ) -> tuple[Series, Series]: ... @overload - def rename( + def rename( # type: ignore[overload-overlap] # pyright: ignore[reportOverlappingOverload] self, - index: Hashable | None, + index: Callable[[Any], Label], *, axis: Axis | None = ..., copy: bool = ..., inplace: Literal[True], level: Level | None = ..., errors: IgnoreRaise = ..., - ) -> Self: ... + ) -> None: ... @overload def rename( self, - index: Renamer = ..., + index: Mapping[Any, Label], *, axis: Axis | None = ..., copy: bool = ..., @@ -1063,6 +1064,17 @@ class Series(IndexOpsMixin[S1], NDFrame): errors: IgnoreRaise = ..., ) -> None: ... @overload + def rename( # type: ignore[overload-overlap] + self, + index: Hashable | None, + *, + axis: Axis | None = ..., + copy: bool = ..., + inplace: Literal[True], + level: Level | None = ..., + errors: IgnoreRaise = ..., + ) -> Self: ... + @overload def rename( self, index: Renamer | Hashable | None = ..., diff --git a/tests/test_series.py b/tests/test_series.py index 475b036dd..5b1c543ac 100644 --- a/tests/test_series.py +++ b/tests/test_series.py @@ -1244,10 +1244,8 @@ def add1(x: int) -> int: pd.Series, np.integer, ) - # TODO this should not raise an error, the lambda is matched with Hashable - # check( - # assert_type(pd.Series([1, 2, 3]).rename(lambda x: x**2, inplace=True), None), type(None) - # ) + s6 = pd.Series([1, 2, 3]) + check(assert_type(s6.rename(lambda x: x**2, inplace=True), None), type(None)) if TYPE_CHECKING_INVALID_USAGE: s7 = pd.Series([1, 2, 3]).rename({1: [3, 4, 5]}) # type: ignore[arg-type] # pyright: ignore[reportArgumentType] From a043807b4804bff1eb6a3afe71aecf8d0bfe9126 Mon Sep 17 00:00:00 2001 From: Loic Diridollou Date: Wed, 5 Mar 2025 18:00:35 -0500 Subject: [PATCH 7/8] GH1139 PR Feedback --- pandas-stubs/core/series.pyi | 8 ++++---- tests/test_series.py | 10 ++++++---- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/pandas-stubs/core/series.pyi b/pandas-stubs/core/series.pyi index bace0e42f..d46b0b8c0 100644 --- a/pandas-stubs/core/series.pyi +++ b/pandas-stubs/core/series.pyi @@ -1042,7 +1042,7 @@ class Series(IndexOpsMixin[S1], NDFrame): broadcast_axis: AxisIndex | None = ..., ) -> tuple[Series, Series]: ... @overload - def rename( # type: ignore[overload-overlap] # pyright: ignore[reportOverlappingOverload] + def rename( self, index: Callable[[Any], Label], *, @@ -1064,9 +1064,9 @@ class Series(IndexOpsMixin[S1], NDFrame): errors: IgnoreRaise = ..., ) -> None: ... @overload - def rename( # type: ignore[overload-overlap] + def rename( self, - index: Hashable | None, + index: Scalar | tuple[Hashable, ...] | None = None, *, axis: Axis | None = ..., copy: bool = ..., @@ -1077,7 +1077,7 @@ class Series(IndexOpsMixin[S1], NDFrame): @overload def rename( self, - index: Renamer | Hashable | None = ..., + index: Renamer | Scalar | tuple[Hashable, ...] | None = ..., *, axis: Axis | None = ..., copy: bool = ..., diff --git a/tests/test_series.py b/tests/test_series.py index 5b1c543ac..9342c007a 100644 --- a/tests/test_series.py +++ b/tests/test_series.py @@ -1182,7 +1182,7 @@ def test_types_rename_axis() -> None: def test_types_values() -> None: check( - assert_type(pd.Series([1, 2, 3]).values, "np.ndarray | ExtensionArray"), + assert_type(pd.Series([1, 2, 3]).values, "ExtensionArray | np.ndarray"), np.ndarray, ) check( @@ -1244,11 +1244,13 @@ def add1(x: int) -> int: pd.Series, np.integer, ) - s6 = pd.Series([1, 2, 3]) - check(assert_type(s6.rename(lambda x: x**2, inplace=True), None), type(None)) + check( + assert_type(pd.Series([1, 2, 3]).rename(lambda x: x**2, inplace=True), None), + type(None), + ) if TYPE_CHECKING_INVALID_USAGE: - s7 = pd.Series([1, 2, 3]).rename({1: [3, 4, 5]}) # type: ignore[arg-type] # pyright: ignore[reportArgumentType] + s7 = pd.Series([1, 2, 3]).rename({1: [3, 4, 5]}) # type: ignore[dict-item] # pyright: ignore[reportArgumentType] def test_types_ne() -> None: From 29250831ebb59151a6c746b8db009bb59a682ced Mon Sep 17 00:00:00 2001 From: Loic Diridollou Date: Thu, 6 Mar 2025 17:38:07 -0500 Subject: [PATCH 8/8] GH1139 PR Feedback --- tests/test_series.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/tests/test_series.py b/tests/test_series.py index 9342c007a..9047a13ad 100644 --- a/tests/test_series.py +++ b/tests/test_series.py @@ -70,7 +70,6 @@ TimedeltaSeries: TypeAlias = pd.Series TimestampSeries: TypeAlias = pd.Series OffsetSeries: TypeAlias = pd.Series - ExtensionArray: TypeAlias = np.ndarray if TYPE_CHECKING: from pandas._typing import ( @@ -1182,24 +1181,24 @@ def test_types_rename_axis() -> None: def test_types_values() -> None: check( - assert_type(pd.Series([1, 2, 3]).values, "ExtensionArray | np.ndarray"), + assert_type(pd.Series([1, 2, 3]).values, Union[ExtensionArray, np.ndarray]), np.ndarray, ) check( - assert_type(pd.Series(list("aabc")).values, " np.ndarray | ExtensionArray "), + assert_type(pd.Series(list("aabc")).values, Union[np.ndarray, ExtensionArray]), np.ndarray, ) check( assert_type( pd.Series(list("aabc")).astype("category").values, - "np.ndarray | ExtensionArray", + Union[np.ndarray, ExtensionArray], ), pd.Categorical, ) check( assert_type( pd.Series(pd.date_range("20130101", periods=3, tz="US/Eastern")).values, - "np.ndarray | ExtensionArray", + Union[np.ndarray, ExtensionArray], ), np.ndarray, )