From c362a3eb9b54eaa2a249ac8075fbfbda39814efb Mon Sep 17 00:00:00 2001 From: Marco Gorelli <33491632+MarcoGorelli@users.noreply.github.com> Date: Wed, 13 Aug 2025 14:06:54 +0100 Subject: [PATCH] fix overload defaults for `as_index` in `groupby` --- pandas-stubs/core/frame.pyi | 42 ++++++++++++++++++++++--------------- tests/test_frame.py | 8 +++---- 2 files changed, 29 insertions(+), 21 deletions(-) diff --git a/pandas-stubs/core/frame.pyi b/pandas-stubs/core/frame.pyi index 63f5acab..5d04a78d 100644 --- a/pandas-stubs/core/frame.pyi +++ b/pandas-stubs/core/frame.pyi @@ -1145,7 +1145,7 @@ class DataFrame(NDFrame, OpsMixin, _GetItemHack): errors: IgnoreRaise = "ignore", ) -> None: ... @overload - def groupby( # pyright: ignore reportOverlappingOverload + def groupby( self, by: Scalar, axis: AxisIndex | _NoDefaultDoNotUse = ..., @@ -1162,14 +1162,15 @@ class DataFrame(NDFrame, OpsMixin, _GetItemHack): by: Scalar, axis: AxisIndex | _NoDefaultDoNotUse = ..., level: IndexLabel | None = ..., - as_index: Literal[False] = ..., + *, + as_index: Literal[False], sort: _bool = ..., group_keys: _bool = ..., observed: _bool | _NoDefaultDoNotUse = ..., dropna: _bool = ..., ) -> DataFrameGroupBy[Scalar, Literal[False]]: ... @overload - def groupby( # pyright: ignore reportOverlappingOverload + def groupby( self, by: DatetimeIndex, axis: AxisIndex | _NoDefaultDoNotUse = ..., @@ -1181,19 +1182,20 @@ class DataFrame(NDFrame, OpsMixin, _GetItemHack): dropna: _bool = ..., ) -> DataFrameGroupBy[Timestamp, Literal[True]]: ... @overload - def groupby( # pyright: ignore reportOverlappingOverload + def groupby( self, by: DatetimeIndex, axis: AxisIndex | _NoDefaultDoNotUse = ..., level: IndexLabel | None = ..., - as_index: Literal[False] = ..., + *, + as_index: Literal[False], sort: _bool = ..., group_keys: _bool = ..., observed: _bool | _NoDefaultDoNotUse = ..., dropna: _bool = ..., ) -> DataFrameGroupBy[Timestamp, Literal[False]]: ... @overload - def groupby( # pyright: ignore reportOverlappingOverload + def groupby( self, by: TimedeltaIndex, axis: AxisIndex | _NoDefaultDoNotUse = ..., @@ -1210,14 +1212,15 @@ class DataFrame(NDFrame, OpsMixin, _GetItemHack): by: TimedeltaIndex, axis: AxisIndex | _NoDefaultDoNotUse = ..., level: IndexLabel | None = ..., - as_index: Literal[False] = ..., + *, + as_index: Literal[False], sort: _bool = ..., group_keys: _bool = ..., observed: _bool | _NoDefaultDoNotUse = ..., dropna: _bool = ..., ) -> DataFrameGroupBy[Timedelta, Literal[False]]: ... @overload - def groupby( # pyright: ignore reportOverlappingOverload + def groupby( self, by: PeriodIndex, axis: AxisIndex | _NoDefaultDoNotUse = ..., @@ -1234,14 +1237,15 @@ class DataFrame(NDFrame, OpsMixin, _GetItemHack): by: PeriodIndex, axis: AxisIndex | _NoDefaultDoNotUse = ..., level: IndexLabel | None = ..., - as_index: Literal[False] = ..., + *, + as_index: Literal[False], sort: _bool = ..., group_keys: _bool = ..., observed: _bool | _NoDefaultDoNotUse = ..., dropna: _bool = ..., ) -> DataFrameGroupBy[Period, Literal[False]]: ... @overload - def groupby( # pyright: ignore reportOverlappingOverload + def groupby( self, by: IntervalIndex[IntervalT], axis: AxisIndex | _NoDefaultDoNotUse = ..., @@ -1258,14 +1262,15 @@ class DataFrame(NDFrame, OpsMixin, _GetItemHack): by: IntervalIndex[IntervalT], axis: AxisIndex | _NoDefaultDoNotUse = ..., level: IndexLabel | None = ..., - as_index: Literal[False] = ..., + *, + as_index: Literal[False], sort: _bool = ..., group_keys: _bool = ..., observed: _bool | _NoDefaultDoNotUse = ..., dropna: _bool = ..., ) -> DataFrameGroupBy[IntervalT, Literal[False]]: ... @overload - def groupby( # type: ignore[overload-overlap] # pyright: ignore reportOverlappingOverload + def groupby( self, by: MultiIndex | GroupByObjectNonScalar | None = ..., axis: AxisIndex | _NoDefaultDoNotUse = ..., @@ -1277,19 +1282,20 @@ class DataFrame(NDFrame, OpsMixin, _GetItemHack): dropna: _bool = ..., ) -> DataFrameGroupBy[tuple, Literal[True]]: ... @overload - def groupby( # type: ignore[overload-overlap] + def groupby( self, by: MultiIndex | GroupByObjectNonScalar | None = ..., axis: AxisIndex | _NoDefaultDoNotUse = ..., level: IndexLabel | None = ..., - as_index: Literal[False] = ..., + *, + as_index: Literal[False], sort: _bool = ..., group_keys: _bool = ..., observed: _bool | _NoDefaultDoNotUse = ..., dropna: _bool = ..., ) -> DataFrameGroupBy[tuple, Literal[False]]: ... @overload - def groupby( # pyright: ignore reportOverlappingOverload + def groupby( self, by: Series[SeriesByT], axis: AxisIndex | _NoDefaultDoNotUse = ..., @@ -1306,7 +1312,8 @@ class DataFrame(NDFrame, OpsMixin, _GetItemHack): by: Series[SeriesByT], axis: AxisIndex | _NoDefaultDoNotUse = ..., level: IndexLabel | None = ..., - as_index: Literal[False] = ..., + *, + as_index: Literal[False], sort: _bool = ..., group_keys: _bool = ..., observed: _bool | _NoDefaultDoNotUse = ..., @@ -1330,7 +1337,8 @@ class DataFrame(NDFrame, OpsMixin, _GetItemHack): by: CategoricalIndex | Index | Series, axis: AxisIndex | _NoDefaultDoNotUse = ..., level: IndexLabel | None = ..., - as_index: Literal[False] = ..., + *, + as_index: Literal[False], sort: _bool = ..., group_keys: _bool = ..., observed: _bool | _NoDefaultDoNotUse = ..., diff --git a/tests/test_frame.py b/tests/test_frame.py index 7d67cfc9..92f86658 100644 --- a/tests/test_frame.py +++ b/tests/test_frame.py @@ -689,8 +689,8 @@ def test_types_mean() -> None: pd.Series, ) if TYPE_CHECKING_INVALID_USAGE: - df3: pd.DataFrame = df.groupby(axis=1, level=0).mean() # type: ignore[call-overload] # pyright: ignore[reportArgumentType, reportCallIssue] - df4: pd.DataFrame = df.groupby(axis=1, level=0, dropna=True).mean() # type: ignore[call-overload] # pyright: ignore[reportArgumentType, reportCallIssue] + df3: pd.DataFrame = df.groupby(axis=1, level=0).mean() # type: ignore[call-overload] # pyright: ignore[reportArgumentType] + df4: pd.DataFrame = df.groupby(axis=1, level=0, dropna=True).mean() # type: ignore[call-overload] # pyright: ignore[reportArgumentType] def test_types_median() -> None: @@ -703,8 +703,8 @@ def test_types_median() -> None: pd.Series, ) if TYPE_CHECKING_INVALID_USAGE: - df3: pd.DataFrame = df.groupby(axis=1, level=0).median() # type: ignore[call-overload] # pyright: ignore[reportArgumentType, reportCallIssue] - df4: pd.DataFrame = df.groupby(axis=1, level=0, dropna=True).median() # type: ignore[call-overload] # pyright: ignore[reportArgumentType, reportCallIssue] + df3: pd.DataFrame = df.groupby(axis=1, level=0).median() # type: ignore[call-overload] # pyright: ignore[reportArgumentType] + df4: pd.DataFrame = df.groupby(axis=1, level=0, dropna=True).median() # type: ignore[call-overload] # pyright: ignore[reportArgumentType] def test_types_iterrows() -> None: