diff --git a/pandas-stubs/_libs/tslibs/timestamps.pyi b/pandas-stubs/_libs/tslibs/timestamps.pyi index 250158c2d..2b7e9a299 100644 --- a/pandas-stubs/_libs/tslibs/timestamps.pyi +++ b/pandas-stubs/_libs/tslibs/timestamps.pyi @@ -100,7 +100,7 @@ class Timestamp(datetime, SupportsIndex): def fold(self) -> int: ... if sys.version_info >= (3, 12): @classmethod - def fromtimestamp( # pyright: ignore[reportIncompatibleMethodOverride] + def fromtimestamp( # pyright: ignore[reportIncompatibleMethodOverride] # ty: ignore[invalid-method-override] cls, t: float, tz: _tzinfo | str | None = ... ) -> Self: ... else: diff --git a/pandas-stubs/_typing.pyi b/pandas-stubs/_typing.pyi index f7dcd1cfc..a6644eac1 100644 --- a/pandas-stubs/_typing.pyi +++ b/pandas-stubs/_typing.pyi @@ -22,7 +22,6 @@ from typing import ( SupportsIndex, TypeAlias, TypedDict, - Union, overload, ) @@ -596,18 +595,25 @@ IndexKeyFunc: TypeAlias = Callable[[Index], Index | AnyArrayLike] | None # types of `func` kwarg for DataFrame.aggregate and Series.aggregate # More specific than what is in pandas -# following Union is here to make it ty compliant https://github.com/astral-sh/ty/issues/591 -AggFuncTypeBase: TypeAlias = Union[Callable, str, np.ufunc] # noqa: UP007 -AggFuncTypeDictSeries: TypeAlias = Mapping[HashableT, AggFuncTypeBase] +AggFuncTypeBase: TypeAlias = Callable[P, Any] | str | np.ufunc +AggFuncTypeDictSeries: TypeAlias = Mapping[HashableT, AggFuncTypeBase[P]] AggFuncTypeDictFrame: TypeAlias = Mapping[ - HashableT, AggFuncTypeBase | list[AggFuncTypeBase] + HashableT, AggFuncTypeBase[P] | Sequence[AggFuncTypeBase[P]] ] -AggFuncTypeSeriesToFrame: TypeAlias = list[AggFuncTypeBase] | AggFuncTypeDictSeries +AggFuncTypeSeriesToFrame: TypeAlias = ( + Sequence[AggFuncTypeBase[P]] | AggFuncTypeDictSeries[HashableT, P] +) AggFuncTypeFrame: TypeAlias = ( - AggFuncTypeBase | list[AggFuncTypeBase] | AggFuncTypeDictFrame + AggFuncTypeBase[P] + | Sequence[AggFuncTypeBase[P]] + | AggFuncTypeDictFrame[HashableT, P] +) +AggFuncTypeDict: TypeAlias = ( + AggFuncTypeDictSeries[HashableT, P] | AggFuncTypeDictFrame[HashableT, P] +) +AggFuncType: TypeAlias = ( + AggFuncTypeBase[P] | Sequence[AggFuncTypeBase[P]] | AggFuncTypeDict[HashableT, P] ) -AggFuncTypeDict: TypeAlias = AggFuncTypeDictSeries | AggFuncTypeDictFrame -AggFuncType: TypeAlias = AggFuncTypeBase | list[AggFuncTypeBase] | AggFuncTypeDict # Not used in stubs # AggObjType = Union[ @@ -694,7 +700,9 @@ CompressionOptions: TypeAlias = ( # types in DataFrameFormatter FormattersType: TypeAlias = ( - list[Callable] | tuple[Callable, ...] | Mapping[str | int, Callable] + list[Callable[..., Any]] + | tuple[Callable[..., Any], ...] + | Mapping[str | int, Callable[..., Any]] ) # ColspaceType = Mapping[Hashable, Union[str, int]] not used in stubs FloatFormatType: TypeAlias = str | Callable[[float], str] | EngFormatter diff --git a/pandas-stubs/core/frame.pyi b/pandas-stubs/core/frame.pyi index 69345fa6e..b77d27224 100644 --- a/pandas-stubs/core/frame.pyi +++ b/pandas-stubs/core/frame.pyi @@ -273,8 +273,8 @@ class _LocIndexerFrame(_LocIndexer, Generic[_T]): | list[HashableT] | slice | _IndexSliceTuple - | Callable, - MaskType | Iterable[HashableT] | IndexType | Callable, + | Callable[..., Any], + MaskType | Iterable[HashableT] | IndexType | Callable[..., Any], ] ), ) -> _T: ... @@ -1268,7 +1268,7 @@ class DataFrame(NDFrame, OpsMixin, _GetItemHack): def combine( self, other: DataFrame, - func: Callable, + func: Callable[..., Any], fill_value: Scalar | None = None, overwrite: _bool = True, ) -> Self: ... @@ -1278,7 +1278,7 @@ class DataFrame(NDFrame, OpsMixin, _GetItemHack): other: DataFrame | Series, join: UpdateJoin = "left", overwrite: _bool = True, - filter_func: Callable | None = ..., + filter_func: Callable[..., Any] | None = ..., errors: IgnoreRaise = "ignore", ) -> None: ... @overload @@ -1516,21 +1516,21 @@ class DataFrame(NDFrame, OpsMixin, _GetItemHack): @overload def aggregate( # pyright: ignore[reportOverlappingOverload] self, - func: AggFuncTypeBase | AggFuncTypeDictSeries, + func: AggFuncTypeBase[...] | AggFuncTypeDictSeries[Any, ...], axis: Axis = 0, **kwargs: Any, ) -> Series: ... @overload def aggregate( self, - func: list[AggFuncTypeBase] | AggFuncTypeDictFrame | None = ..., + func: list[AggFuncTypeBase[...]] | AggFuncTypeDictFrame[Any, ...] | None = ..., axis: Axis = 0, **kwargs: Any, ) -> Self: ... agg = aggregate def transform( self, - func: AggFuncTypeFrame, + func: AggFuncTypeFrame[..., Any], axis: Axis = 0, *args: Any, **kwargs: Any, @@ -1684,7 +1684,10 @@ class DataFrame(NDFrame, OpsMixin, _GetItemHack): # Add spacing between apply() overloads and remaining annotations def map( - self, func: Callable, na_action: Literal["ignore"] | None = None, **kwargs: Any + self, + func: Callable[..., Any], + na_action: Literal["ignore"] | None = None, + **kwargs: Any, ) -> Self: ... def join( self, @@ -2332,7 +2335,7 @@ class DataFrame(NDFrame, OpsMixin, _GetItemHack): | Callable[[DataFrame], DataFrame] | Callable[[Any], _bool] ), - other: Scalar | Series | DataFrame | Callable | NAType | None = ..., + other: Scalar | Series | DataFrame | Callable[..., Any] | NAType | None = ..., *, inplace: Literal[True], axis: Axis | None = ..., @@ -2349,7 +2352,7 @@ class DataFrame(NDFrame, OpsMixin, _GetItemHack): | Callable[[DataFrame], DataFrame] | Callable[[Any], _bool] ), - other: Scalar | Series | DataFrame | Callable | NAType | None = ..., + other: Scalar | Series | DataFrame | Callable[..., Any] | NAType | None = ..., *, inplace: Literal[False] = False, axis: Axis | None = ..., @@ -2510,8 +2513,12 @@ class DataFrame(NDFrame, OpsMixin, _GetItemHack): def rename_axis( self, *, - index: _str | Sequence[_str] | dict[_str | int, _str] | Callable | None = ..., - columns: _str | Sequence[_str] | dict[_str | int, _str] | Callable | None = ..., + index: ( + _str | Sequence[_str] | dict[_str | int, _str] | Callable[..., Any] | None + ) = ..., + columns: ( + _str | Sequence[_str] | dict[_str | int, _str] | Callable[..., Any] | None + ) = ..., copy: _bool = ..., inplace: Literal[True], ) -> None: ... @@ -2520,8 +2527,12 @@ class DataFrame(NDFrame, OpsMixin, _GetItemHack): def rename_axis( self, *, - index: _str | Sequence[_str] | dict[_str | int, _str] | Callable | None = ..., - columns: _str | Sequence[_str] | dict[_str | int, _str] | Callable | None = ..., + index: ( + _str | Sequence[_str] | dict[_str | int, _str] | Callable[..., Any] | None + ) = ..., + columns: ( + _str | Sequence[_str] | dict[_str | int, _str] | Callable[..., Any] | None + ) = ..., copy: _bool = ..., inplace: Literal[False] = False, ) -> Self: ... diff --git a/pandas-stubs/core/groupby/generic.pyi b/pandas-stubs/core/groupby/generic.pyi index ac06e7311..52ee1c026 100644 --- a/pandas-stubs/core/groupby/generic.pyi +++ b/pandas-stubs/core/groupby/generic.pyi @@ -78,7 +78,7 @@ class SeriesGroupBy(GroupBy[Series[S2]], Generic[S2, ByT]): @overload def aggregate( self, - func: list[AggFuncTypeBase], + func: list[AggFuncTypeBase[...]], /, *args: Any, engine: WindowingEngine = ..., @@ -88,7 +88,7 @@ class SeriesGroupBy(GroupBy[Series[S2]], Generic[S2, ByT]): @overload def aggregate( self, - func: AggFuncTypeBase | None = ..., + func: AggFuncTypeBase[...] | None = ..., /, *args: Any, engine: WindowingEngine = ..., @@ -109,16 +109,20 @@ class SeriesGroupBy(GroupBy[Series[S2]], Generic[S2, ByT]): @overload def transform( self, - func: Callable, - *args: Any, - **kwargs: Any, + func: Callable[Concatenate[Series, P], Any], + *args: P.args, + **kwargs: P.kwargs, ) -> Series: ... @overload def transform( self, func: TransformReductionListType, *args: Any, **kwargs: Any ) -> Series: ... def filter( - self, func: Callable | str, dropna: bool = ..., *args: Any, **kwargs: Any + self, + func: Callable[Concatenate[Series, P], Any] | str, + dropna: bool = ..., + *args: P.args, + **kwargs: P.kwargs, ) -> Series: ... def nunique(self, dropna: bool = ...) -> Series[int]: ... # describe delegates to super() method but here it has keyword-only parameters @@ -257,7 +261,7 @@ class DataFrameGroupBy(GroupBy[DataFrame], Generic[ByT, _TT]): @overload def aggregate( self, - func: AggFuncTypeFrame | None = ..., + func: AggFuncTypeFrame[..., Any] | None = ..., *args: Any, engine: WindowingEngine = ..., engine_kwargs: WindowingEngineKwargs = ..., @@ -266,7 +270,7 @@ class DataFrameGroupBy(GroupBy[DataFrame], Generic[ByT, _TT]): @overload def aggregate( self, - func: AggFuncTypeFrame | None = None, + func: AggFuncTypeFrame[..., Any] | None = None, /, **kwargs: Any, ) -> DataFrame: ... @@ -283,16 +287,20 @@ class DataFrameGroupBy(GroupBy[DataFrame], Generic[ByT, _TT]): @overload def transform( self, - func: Callable, - *args: Any, - **kwargs: Any, + func: Callable[Concatenate[DataFrame, P], Any], + *args: P.args, + **kwargs: P.kwargs, ) -> DataFrame: ... @overload def transform( self, func: TransformReductionListType, *args: Any, **kwargs: Any ) -> DataFrame: ... def filter( - self, func: Callable, dropna: bool = ..., *args: Any, **kwargs: Any + self, + func: Callable[Concatenate[DataFrame, P], Any], + dropna: bool = ..., + *args: P.args, + **kwargs: P.kwargs, ) -> DataFrame: ... @overload def __getitem__(self, key: Scalar) -> SeriesGroupBy[Any, ByT]: ... # type: ignore[overload-overlap] # pyright: ignore[reportOverlappingOverload] diff --git a/pandas-stubs/core/groupby/groupby.pyi b/pandas-stubs/core/groupby/groupby.pyi index b60864ada..242dcd38f 100644 --- a/pandas-stubs/core/groupby/groupby.pyi +++ b/pandas-stubs/core/groupby/groupby.pyi @@ -78,7 +78,12 @@ _ResamplerGroupBy: TypeAlias = ( class GroupBy(BaseGroupBy[NDFrameT]): def __getattr__(self, attr: str) -> Any: ... - def apply(self, func: Callable | str, *args: Any, **kwargs: Any) -> NDFrameT: ... + def apply( + self, + func: Callable[Concatenate[NDFrameT, P], Any] | str, + *args: P.args, + **kwargs: P.kwargs, + ) -> NDFrameT: ... @final @overload def any(self: GroupBy[Series], skipna: bool = ...) -> Series[bool]: ... diff --git a/pandas-stubs/core/indexes/base.pyi b/pandas-stubs/core/indexes/base.pyi index 80b1cca4f..94c2846db 100644 --- a/pandas-stubs/core/indexes/base.pyi +++ b/pandas-stubs/core/indexes/base.pyi @@ -408,7 +408,10 @@ class Index(IndexOpsMixin[S1], ElementOpsMixin[S1]): ) -> Self: ... def copy(self, name: Hashable = ..., deep: bool = False) -> Self: ... def format( - self, name: bool = ..., formatter: Callable | None = ..., na_rep: _str = ... + self, + name: bool = ..., + formatter: Callable[..., Any] | None = ..., + na_rep: _str = ..., ) -> list[_str]: ... def to_series( self, index: Index | None = None, name: Hashable | None = None diff --git a/pandas-stubs/core/indexes/multi.pyi b/pandas-stubs/core/indexes/multi.pyi index dbb9b766e..7e44938b0 100644 --- a/pandas-stubs/core/indexes/multi.pyi +++ b/pandas-stubs/core/indexes/multi.pyi @@ -94,7 +94,7 @@ class MultiIndex(Index): def format( self, name: bool | None = ..., - formatter: Callable | None = ..., + formatter: Callable[..., Any] | None = ..., na_rep: str | None = ..., names: bool = ..., space: int = ..., diff --git a/pandas-stubs/core/series.pyi b/pandas-stubs/core/series.pyi index c732e3826..f24854920 100644 --- a/pandas-stubs/core/series.pyi +++ b/pandas-stubs/core/series.pyi @@ -309,7 +309,7 @@ class _LocIndexerSeries(_LocIndexer, Generic[S1]): | slice | _IndexSliceTuple | Sequence[_IndexSliceTuple] - | Callable + | Callable[..., Any] ), # _IndexSliceTuple is when having a tuple that includes a slice. Could just # be s.loc[1, :], or s.loc[pd.IndexSlice[1, :]] @@ -559,7 +559,7 @@ class Series(IndexOpsMixin[S1], ElementOpsMixin[S1], NDFrame): def __len__(self) -> int: ... @final def __array_ufunc__( - self, ufunc: Callable, method: _str, *inputs: Any, **kwargs: Any + self, ufunc: Callable[..., Any], method: _str, *inputs: Any, **kwargs: Any ) -> Any: ... def __array__( # ty: ignore[invalid-method-override] self, dtype: _str | np.dtype = ..., copy: bool | None = ... @@ -594,7 +594,7 @@ class Series(IndexOpsMixin[S1], ElementOpsMixin[S1], NDFrame): | slice | _IndexSliceTuple | Sequence[_IndexSliceTuple] - | Callable + | Callable[..., Any] ), # _IndexSliceTuple is when having a tuple that includes a slice. Could just # be s.loc[1, :], or s.loc[pd.IndexSlice[1, :]] @@ -1025,7 +1025,10 @@ class Series(IndexOpsMixin[S1], ElementOpsMixin[S1], NDFrame): result_names: Suffixes = ..., ) -> DataFrame: ... def combine( - self, other: Series[S1], func: Callable, fill_value: Scalar | None = ... + self, + other: Series[S1], + func: Callable[..., Any], + fill_value: Scalar | None = ..., ) -> Series[S1]: ... def combine_first(self, other: Series[S1]) -> Series[S1]: ... def update(self, other: Series[S1] | Sequence[S1] | Mapping[int, S1]) -> None: ... @@ -1132,9 +1135,9 @@ class Series(IndexOpsMixin[S1], ElementOpsMixin[S1], NDFrame): **kwargs: Any, ) -> float: ... @overload - def aggregate( + def aggregate( # pyright: ignore[reportOverlappingOverload] self, - func: AggFuncTypeBase, + func: AggFuncTypeBase[...], axis: AxisIndex = ..., *args: Any, **kwargs: Any, @@ -1142,16 +1145,16 @@ class Series(IndexOpsMixin[S1], ElementOpsMixin[S1], NDFrame): @overload def aggregate( self, - func: AggFuncTypeSeriesToFrame = ..., + func: AggFuncTypeSeriesToFrame[..., Any] = ..., axis: AxisIndex = ..., *args: Any, **kwargs: Any, ) -> Series: ... agg = aggregate @overload - def transform( + def transform( # pyright: ignore[reportOverlappingOverload] self, - func: AggFuncTypeBase, + func: AggFuncTypeBase[...], axis: AxisIndex = ..., *args: Any, **kwargs: Any, @@ -1159,7 +1162,7 @@ class Series(IndexOpsMixin[S1], ElementOpsMixin[S1], NDFrame): @overload def transform( self, - func: list[AggFuncTypeBase] | AggFuncTypeDictFrame, + func: Sequence[AggFuncTypeBase[...]] | AggFuncTypeDictFrame[Hashable, ...], axis: AxisIndex = ..., *args: Any, **kwargs: Any, @@ -1670,7 +1673,9 @@ class Series(IndexOpsMixin[S1], ElementOpsMixin[S1], NDFrame): | Callable[[Series[S1]], Series[bool]] | Callable[[S1], bool] ), - other: Scalar | Series[S1] | DataFrame | Callable | NAType | None = ..., + other: ( + Scalar | Series[S1] | DataFrame | Callable[..., Any] | NAType | None + ) = ..., *, inplace: Literal[True], axis: AxisIndex | None = 0, @@ -1686,7 +1691,9 @@ class Series(IndexOpsMixin[S1], ElementOpsMixin[S1], NDFrame): | Callable[[Series[S1]], Series[bool]] | Callable[[S1], bool] ), - other: Scalar | Series[S1] | DataFrame | Callable | NAType | None = ..., + other: ( + Scalar | Series[S1] | DataFrame | Callable[..., Any] | NAType | None + ) = ..., *, inplace: Literal[False] = False, axis: AxisIndex | None = 0, @@ -4631,7 +4638,7 @@ class Series(IndexOpsMixin[S1], ElementOpsMixin[S1], NDFrame): def rename_axis( self, *, - index: Scalar | ListLike | Callable | dict | None = ..., + index: Scalar | ListLike | Callable[..., Any] | dict | None = ..., copy: _bool = ..., inplace: Literal[True], ) -> None: ... @@ -4640,7 +4647,7 @@ class Series(IndexOpsMixin[S1], ElementOpsMixin[S1], NDFrame): def rename_axis( self, *, - index: Scalar | ListLike | Callable | dict | None = ..., + index: Scalar | ListLike | Callable[..., Any] | dict | None = ..., copy: _bool = ..., inplace: Literal[False] = False, ) -> Self: ... diff --git a/pandas-stubs/core/window/rolling.pyi b/pandas-stubs/core/window/rolling.pyi index 8f9af36a3..457894b0f 100644 --- a/pandas-stubs/core/window/rolling.pyi +++ b/pandas-stubs/core/window/rolling.pyi @@ -46,20 +46,23 @@ class BaseWindow(SelectionMixin[NDFrameT]): def __getattr__(self, attr: str) -> Self: ... def __iter__(self) -> Iterator[NDFrameT]: ... @overload - def aggregate( - self: BaseWindow[Series], func: AggFuncTypeBase, *args: Any, **kwargs: Any + def aggregate( # pyright: ignore[reportOverlappingOverload] + self: BaseWindow[Series], + func: AggFuncTypeBase[...], + *args: Any, + **kwargs: Any, ) -> Series: ... @overload def aggregate( self: BaseWindow[Series], - func: AggFuncTypeSeriesToFrame, + func: AggFuncTypeSeriesToFrame[..., Any], *args: Any, **kwargs: Any, ) -> DataFrame: ... @overload def aggregate( self: BaseWindow[DataFrame], - func: AggFuncTypeFrame, + func: AggFuncTypeFrame[..., Any], *args: Any, **kwargs: Any, ) -> DataFrame: ... diff --git a/pandas-stubs/io/clipboards.pyi b/pandas-stubs/io/clipboards.pyi index 7f57c2845..25a1ed180 100644 --- a/pandas-stubs/io/clipboards.pyi +++ b/pandas-stubs/io/clipboards.pyi @@ -59,7 +59,7 @@ def read_clipboard( ) = ..., infer_datetime_format: bool = ..., keep_date_col: bool = ..., - date_parser: Callable = ..., + date_parser: Callable[..., Any] = ..., dayfirst: bool = ..., cache_dates: bool = ..., iterator: Literal[True], @@ -118,7 +118,7 @@ def read_clipboard( ) = ..., infer_datetime_format: bool = ..., keep_date_col: bool = ..., - date_parser: Callable = ..., + date_parser: Callable[..., Any] = ..., dayfirst: bool = ..., cache_dates: bool = ..., iterator: bool = ..., @@ -177,7 +177,7 @@ def read_clipboard( ) = ..., infer_datetime_format: bool = ..., keep_date_col: bool = ..., - date_parser: Callable = ..., + date_parser: Callable[..., Any] = ..., dayfirst: bool = ..., cache_dates: bool = ..., iterator: Literal[False] = False, diff --git a/pandas-stubs/io/excel/_base.pyi b/pandas-stubs/io/excel/_base.pyi index fdd1a03c4..9e772560c 100644 --- a/pandas-stubs/io/excel/_base.pyi +++ b/pandas-stubs/io/excel/_base.pyi @@ -276,7 +276,7 @@ class ExcelFile: | Sequence[Sequence[str] | Sequence[int]] | dict[str, Sequence[int] | list[str]] ) = ..., - date_parser: Callable | None = ..., + date_parser: Callable[..., Any] | None = ..., thousands: str | None = ..., comment: str | None = ..., skipfooter: int = ..., @@ -304,7 +304,7 @@ class ExcelFile: | Sequence[Sequence[str] | Sequence[int]] | dict[str, Sequence[int] | list[str]] ) = ..., - date_parser: Callable | None = ..., + date_parser: Callable[..., Any] | None = ..., thousands: str | None = ..., comment: str | None = ..., skipfooter: int = ..., diff --git a/pandas-stubs/io/formats/style.pyi b/pandas-stubs/io/formats/style.pyi index 29a461f8a..b79c708f0 100644 --- a/pandas-stubs/io/formats/style.pyi +++ b/pandas-stubs/io/formats/style.pyi @@ -5,6 +5,7 @@ from collections.abc import ( ) from typing import ( Any, + Concatenate, Literal, Protocol, overload, @@ -13,6 +14,7 @@ from typing import ( from matplotlib.colors import Colormap from pandas.core.frame import DataFrame from pandas.core.series import Series +from typing_extensions import Self from pandas._typing import ( Axis, @@ -24,6 +26,7 @@ from pandas._typing import ( IndexLabel, IntervalClosedType, Level, + P, QuantileInterpolation, Scalar, StorageOptions, @@ -390,7 +393,10 @@ class Styler(StylerRenderer): ) -> type[Styler]: ... def pipe( self, - func: Callable[..., T] | tuple[Callable[..., T], str], - *args: Any, - **kwargs: Any, + func: ( + Callable[Concatenate[Self, P], T] + | tuple[Callable[Concatenate[Self, P], T], str] + ), + *args: P.args, + **kwargs: P.kwargs, ) -> T: ... diff --git a/pyproject.toml b/pyproject.toml index 787874d01..c1f47ae81 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -355,3 +355,5 @@ filterwarnings = [ [tool.ty.rules] unresolved-import = "ignore" +# TODO: report to ty +invalid-type-arguments = "ignore" diff --git a/tests/test_frame.py b/tests/test_frame.py index 60e6292e6..4b56b8ae0 100644 --- a/tests/test_frame.py +++ b/tests/test_frame.py @@ -1882,7 +1882,7 @@ def wrapped_min(x: pd.Series[S1]) -> S1: ) # Here, MyPy infers dict[object, object], so it must be explicitly annotated - agg_dict3: dict[str | int, str | Callable] = { + agg_dict3: dict[str | int, str | Callable[..., Any]] = { "col2": min, "col3": "max", 0: wrapped_min, diff --git a/tests/test_windowing.py b/tests/test_windowing.py index ced325fed..741d3192f 100644 --- a/tests/test_windowing.py +++ b/tests/test_windowing.py @@ -157,7 +157,7 @@ def _mean(df: DataFrame) -> Series: DataFrame, ) - # func: np.ufunc | Callable | str | list[Callable | str, np.ufunc] | dict[Hashable, Callable | str | np.ufunc| list[Callable | str]] + # func: np.ufunc | Callable[..., Any] | str | list[Callable[..., Any] | str, np.ufunc] | dict[Hashable, Callable[..., Any] | str | np.ufunc | list[Callable[..., Any] | str]] check(assert_type(DF.rolling(10).agg("sum"), DataFrame), DataFrame)