Repository: pandas-dev/pandas
Pull request: TYP: tighten return type in function any
- [x] closes #44802
- [ ] [Tests added and passed](https://pandas.pydata.org/pandas-docs/dev/development/contributing_codebase.html#writing-tests) if fixing a bug or adding a new feature
- [x] All [code checks passed](https://pandas.pydata.org/pandas-docs/dev/development/contributing_codebase.html#pre-commit).
- [ ] Added an entry in the latest `doc/source/whatsnew/vX.X.X.rst` file if fixing a bug or adding a new feature.

Continuing remaining work after Pull request #44896.
`DataFrame.any` the return type should be DataFrame or Series, and for `Series.any` the return type should be Series or bool.


Problem statement:
TYP tighten `any` return type
Currently, `any` returns `Series | bool`.

However, for `DataFrame.any` the return type should be `Series`, and for `Series.any` the return type should be `bool`.

Marking as good first issue, but please only attempt this if you already have some experience with Python typing and `mypy`.

Hints from issue discussion:
Hi @MarcoGorelli I've always wanted to contribute to Pandas. Would I be able to be assigned this issue? Cheers
If you're familiar with mypy, sure, I'll assign you
@sglambert 
I want to take this issue. I have implemented some ideas. 
Are you still working on it?
@yadav-sachin I think you're OK to take this on if you want

Commit message: remove keyword-args constraint in generic

Patch to review:
diff --git a/pandas/core/frame.py b/pandas/core/frame.py
index ef5e6dd1d6757..a516de7a6e2e7 100644
--- a/pandas/core/frame.py
+++ b/pandas/core/frame.py
@@ -8988,6 +8988,42 @@ def aggregate(self, func=None, axis: Axis = 0, *args, **kwargs):
 
     agg = aggregate
 
+    @overload
+    def any(
+        self: DataFrame,
+        *,
+        axis: Axis = ...,
+        bool_only: bool | None = ...,
+        skipna: bool = ...,
+        level: None = ...,
+        **kwargs,
+    ) -> Series:
+        ...
+
+    @overload
+    def any(
+        self: DataFrame,
+        *,
+        axis: Axis = ...,
+        bool_only: bool | None = ...,
+        skipna: bool = ...,
+        level=Level,
+        **kwargs,
+    ) -> DataFrame | Series:
+        ...
+
+    @doc(NDFrame.any, **_shared_doc_kwargs)
+    def any(
+        self: DataFrame,
+        *,
+        axis: Axis = 0,
+        bool_only: bool | None = None,
+        skipna: bool = True,
+        level: Level | None = None,
+        **kwargs,
+    ) -> DataFrame | Series:
+        ...
+
     @doc(
         _shared_docs["transform"],
         klass=_shared_doc_kwargs["klass"],
diff --git a/pandas/core/series.py b/pandas/core/series.py
index 1d3509cac0edd..99d09a08f66f4 100644
--- a/pandas/core/series.py
+++ b/pandas/core/series.py
@@ -4397,6 +4397,42 @@ def aggregate(self, func=None, axis=0, *args, **kwargs):
 
     agg = aggregate
 
+    @overload
+    def any(
+        self: Series,
+        *,
+        axis: Axis = ...,
+        bool_only: bool | None = ...,
+        skipna: bool = ...,
+        level: None = ...,
+        **kwargs,
+    ) -> bool:
+        ...
+
+    @overload
+    def any(
+        self: Series,
+        *,
+        axis: Axis = ...,
+        bool_only: bool | None = ...,
+        skipna: bool = ...,
+        level=Level,
+        **kwargs,
+    ) -> Series | bool:
+        ...
+
+    @doc(NDFrame.any, **_shared_doc_kwargs)
+    def any(
+        self: Series,
+        *,
+        axis: Axis = 0,
+        bool_only: bool | None = None,
+        skipna: bool = True,
+        level: Level | None = None,
+        **kwargs,
+    ) -> Series | bool:
+        ...
+
     @doc(
         _shared_docs["transform"],
         klass=_shared_doc_kwargs["klass"],


Code review comments:
diff_hunk: @@ -8988,6 +8988,42 @@ def aggregate(self, func=None, axis: Axis = 0, *args, **kwargs):
 
     agg = aggregate
 
+    @overload
+    def any(
+        self: DataFrame,
+        *,
+        axis: Axis = ...,
+        bool_only: bool | None = ...,
+        skipna: bool = ...,
+        level: None = ...,
+        **kwargs,
+    ) -> Series:
+        ...
+
+    @overload
+    def any(
+        self: DataFrame,
+        *,
+        axis: Axis = ...,
+        bool_only: bool | None = ...,
+        skipna: bool = ...,
+        level=Level,
path: pandas/core/frame.py
text: @user1:
`level: Level,` and also for the overload in series.py