Repository: pandas-dev/pandas-stubs (language: python)

Issue:
`lower` and `upper` from `DataFrame.clip` don't accept array-like
**Describe the bug**
Hi,

There is an inconsistency with Pandas's doc regarding `clip`. This was already fixed for Series in #443, but not for DataFrame

https://github.com/pandas-dev/pandas-stubs/blob/2acc94d60c63484d9b664b8e68aa213a4d39b937/pandas-stubs/core/frame.pyi#L1633-L1641


**To Reproduce**
1. From https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.clip.html
```python
import pandas as pd

data = {"col_0": [9, -3, 0, -1, 5], "col_1": [-2, -7, 6, 8, -5]}
df = pd.DataFrame(data)
t = pd.Series([2, -4, -1, 6, 3])
df.clip(t, t + 4, axis=0)
```
2. Pyright 1.1.373
3. 
```
Argument of type "Series[int]" cannot be assigned to parameter "upper" of type "float | None" in function "clip"
  Type "Series[int]" is incompatible with type "float | None"
    "Series[int]" is incompatible with "float"
    "Series[int]" is incompatible with "None"Pylance[reportArgumentType](https://github.com/microsoft/pyright/blob/main/docs/configuration.md#reportArgumentType)
```


**Please complete the following information:**
 - OS: Windows 11
 - OS Version 23H2
 - python version 3.12.2
 - version of type checker:  Pyright 1.1.373
 - version of installed `pandas-stubs`: 2.2.2.240807


Discussion / hints:
Thanks for the report.  PR with tests welcome.

Fix patch:
diff --git a/pandas-stubs/core/frame.pyi b/pandas-stubs/core/frame.pyi
index 8607343c..1ca7c568 100644
--- a/pandas-stubs/core/frame.pyi
+++ b/pandas-stubs/core/frame.pyi
@@ -1632,8 +1632,8 @@ class DataFrame(NDFrame, OpsMixin):
     ) -> DataFrame: ...
     def clip(
         self,
-        lower: float | None = ...,
-        upper: float | None = ...,
+        lower: float | AnyArrayLike | None = ...,
+        upper: float | AnyArrayLike | None = ...,
         *,
         axis: Axis | None = ...,
         inplace: _bool = ...,


Test patch:
diff --git a/tests/test_frame.py b/tests/test_frame.py
index a8b03e76..33aa1616 100644
--- a/tests/test_frame.py
+++ b/tests/test_frame.py
@@ -527,9 +527,23 @@ def test_types_quantile() -> None:
     df.quantile(np.array([0.25, 0.75]))
 
 
-def test_types_clip() -> None:
+@pytest.mark.parametrize("lower", [None, 5, pd.Series([3, 4])])
+@pytest.mark.parametrize("upper", [None, 15, pd.Series([12, 13])])
+@pytest.mark.parametrize("axis", [None, 0, "index"])
+def test_types_clip(lower, upper, axis) -> None:
+    def is_none_or_numeric(val: Any) -> bool:
+        return val is None or isinstance(val, int | float)
+
     df = pd.DataFrame(data={"col1": [20, 12], "col2": [3, 14]})
-    df.clip(lower=5, upper=15)
+    uses_array = not (is_none_or_numeric(lower) and is_none_or_numeric(upper))
+    if uses_array and axis is None:
+        with pytest.raises(ValueError):
+            df.clip(lower=lower, upper=upper, axis=axis)
+    else:
+        check(
+            assert_type(df.clip(lower=lower, upper=upper, axis=axis), pd.DataFrame),
+            pd.DataFrame,
+        )
 
 
 def test_types_abs() -> None: