Skip to content

TYP: use overload to refine return type of reset_index #33519

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

Closed
Changes from all commits
Commits
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
25 changes: 23 additions & 2 deletions pandas/core/frame.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
Type,
Union,
cast,
overload,
)
import warnings

Expand Down Expand Up @@ -4302,7 +4303,29 @@ def set_index(
if not inplace:
return frame

@overload
def reset_index(
self,
level: Optional[Union[Hashable, Sequence[Hashable]]] = None,
drop: bool = False,
*,
Copy link
Member

Choose a reason for hiding this comment

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

Is it possible to combine Literal and overload here instead of this? I don’t think this is 100% accurate if a user provides inplace=False

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 can't use Literal til Python 3.8 or unless we adopt typing extensions.

If we pass inplace=False the return type will match the second signature and so the return type will be the Union. This is not inaccurate and no change from the status quo.

If we don't pass an inplace argument, the return type will be DataFrame and additional asserts, casts or ignores aren't needed. This is an improvement from the status quo.

Copy link
Member

Choose a reason for hiding this comment

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

Whether explicitly passing inplace=False or just sticking with the default signature the expected return type shouldn't be different, which is what is being introduced here. The ideal overload should be something like "return None if inplace=True, otherwise return a DataFrame".

While the current approach may appease most type checking it introduces unexpected behavior when providing the inplace keyword; would rather try to integrate a Literal type or actually deprecate inplace.

col_level: Hashable = 0,
col_fill: Label = "",
) -> "DataFrame":
...

@overload
def reset_index( # noqa: F811
self,
level: Optional[Union[Hashable, Sequence[Hashable]]] = None,
drop: bool = False,
inplace: bool = False,
col_level: Hashable = 0,
col_fill: Label = "",
) -> Optional["DataFrame"]:
...

def reset_index( # noqa: F811
self,
level: Optional[Union[Hashable, Sequence[Hashable]]] = None,
drop: bool = False,
Expand Down Expand Up @@ -6559,8 +6582,6 @@ def explode(self, column: Union[str, Tuple]) -> "DataFrame":
raise ValueError("columns must be unique")

df = self.reset_index(drop=True)
# TODO: use overload to refine return type of reset_index
assert df is not None # needed for mypy
result = df[column].explode()
result = df.drop([column], axis=1).join(result)
result.index = self.index.take(result.index)
Expand Down