Skip to content

Commit 4fb7876

Browse files
committed
Type args and kwargs in frame pipe
1 parent c0ca527 commit 4fb7876

File tree

3 files changed

+87
-10
lines changed

3 files changed

+87
-10
lines changed

pandas-stubs/_typing.pyi

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,10 @@ from pandas.core.generic import NDFrame
2828
from pandas.core.groupby.grouper import Grouper
2929
from pandas.core.indexes.base import Index
3030
from pandas.core.series import Series
31-
from typing_extensions import TypeAlias
31+
from typing_extensions import (
32+
ParamSpec,
33+
TypeAlias,
34+
)
3235

3336
from pandas._libs.interval import Interval
3437
from pandas._libs.tslibs import (
@@ -446,6 +449,7 @@ JSONSerializable: TypeAlias = PythonScalar | list | dict
446449
Axes: TypeAlias = AnyArrayLike | list | dict | range | tuple
447450
Renamer: TypeAlias = Mapping[Any, Label] | Callable[[Any], Label]
448451
T = TypeVar("T")
452+
P = ParamSpec("P")
449453
FuncType: TypeAlias = Callable[..., Any]
450454
F = TypeVar("F", bound=FuncType)
451455
HashableT = TypeVar("HashableT", bound=Hashable)

pandas-stubs/core/frame.pyi

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,10 @@ from pandas.core.window.rolling import (
5252
Rolling,
5353
Window,
5454
)
55-
from typing_extensions import Self
55+
from typing_extensions import (
56+
Concatenate,
57+
Self,
58+
)
5659
import xarray as xr
5760

5861
from pandas._libs.missing import NAType
@@ -100,6 +103,7 @@ from pandas._typing import (
100103
MergeHow,
101104
NaPosition,
102105
NDFrameT,
106+
P,
103107
ParquetEngine,
104108
QuantileInterpolation,
105109
RandomState,
@@ -1832,9 +1836,9 @@ class DataFrame(NDFrame, OpsMixin):
18321836
) -> DataFrame: ...
18331837
def pipe(
18341838
self,
1835-
func: Callable[..., TType] | tuple[Callable[..., TType], _str],
1836-
*args,
1837-
**kwargs,
1839+
func: Callable[Concatenate[Self, P], TType] | tuple[Callable[..., TType], _str],
1840+
*args: P.args,
1841+
**kwargs: P.kwargs,
18381842
) -> TType: ...
18391843
def pop(self, item: _str) -> Series: ...
18401844
def pow(

tests/test_frame.py

Lines changed: 74 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1398,21 +1398,90 @@ def foo(df: pd.DataFrame) -> pd.DataFrame:
13981398
.pipe(foo)
13991399
)
14001400

1401+
df = pd.DataFrame({"a": [1], "b": [2]})
14011402
check(assert_type(val, pd.DataFrame), pd.DataFrame)
14021403

1403-
check(assert_type(pd.DataFrame({"a": [1]}).pipe(foo), pd.DataFrame), pd.DataFrame)
1404+
check(assert_type(df.pipe(foo), pd.DataFrame), pd.DataFrame)
14041405

14051406
def bar(val: Styler) -> Styler:
14061407
return val
14071408

1408-
check(
1409-
assert_type(pd.DataFrame({"a": [1], "b": [1]}).style.pipe(bar), Styler), Styler
1410-
)
1409+
check(assert_type(df.style.pipe(bar), Styler), Styler)
14111410

14121411
def baz(val: Styler) -> str:
14131412
return val.to_latex()
14141413

1415-
check(assert_type(pd.DataFrame({"a": [1], "b": [1]}).style.pipe(baz), str), str)
1414+
check(assert_type(df.style.pipe(baz), str), str)
1415+
1416+
def qux(
1417+
df: pd.DataFrame,
1418+
positional_only: int,
1419+
/,
1420+
argument_1: list[float],
1421+
argument_2: str,
1422+
*,
1423+
keyword_only: tuple[int, int],
1424+
) -> pd.DataFrame:
1425+
return pd.DataFrame(df)
1426+
1427+
check(
1428+
assert_type(
1429+
df.pipe(qux, 1, [1.0, 2.0], argument_2="hi", keyword_only=(1, 2)),
1430+
pd.DataFrame,
1431+
),
1432+
pd.DataFrame,
1433+
)
1434+
1435+
if TYPE_CHECKING_INVALID_USAGE:
1436+
df.pipe(
1437+
qux, # type: ignore[arg-type]
1438+
"a", # pyright: ignore[reportGeneralTypeIssues]
1439+
[1.0, 2.0],
1440+
argument_2="hi",
1441+
keyword_only=(1, 2),
1442+
)
1443+
df.pipe(
1444+
qux, # type: ignore[arg-type]
1445+
1,
1446+
[1.0, "b"], # pyright: ignore[reportGeneralTypeIssues]
1447+
argument_2="hi",
1448+
keyword_only=(1, 2),
1449+
)
1450+
df.pipe(
1451+
qux, # type: ignore[arg-type]
1452+
1,
1453+
[1.0, 2.0],
1454+
argument_2=11, # pyright: ignore[reportGeneralTypeIssues]
1455+
keyword_only=(1, 2),
1456+
)
1457+
df.pipe(
1458+
qux, # type: ignore[arg-type]
1459+
1,
1460+
[1.0, 2.0],
1461+
argument_2="hi",
1462+
keyword_only=(1,), # pyright: ignore[reportGeneralTypeIssues]
1463+
)
1464+
df.pipe(
1465+
qux, # type: ignore[arg-type]
1466+
1,
1467+
[1.0, 2.0],
1468+
argument_3="hi", # pyright: ignore[reportGeneralTypeIssues]
1469+
keyword_only=(1, 2),
1470+
)
1471+
df.pipe(
1472+
qux, # type: ignore[arg-type]
1473+
1,
1474+
[1.0, 2.0],
1475+
11,
1476+
(1, 2), # pyright: ignore[reportGeneralTypeIssues]
1477+
)
1478+
df.pipe(
1479+
qux, # type: ignore[arg-type]
1480+
positional_only=1, # pyright: ignore[reportGeneralTypeIssues]
1481+
argument_1=[1.0, 2.0],
1482+
argument_2=11,
1483+
keyword_only=(1, 2),
1484+
)
14161485

14171486

14181487
# set_flags() method added in 1.2.0 https://pandas.pydata.org/docs/whatsnew/v1.2.0.html

0 commit comments

Comments
 (0)