Skip to content

DataFrame.apply / GroupBy.apply: first parameter named f in stubs but func at runtime #1896

Description

@sshishov

Describe the bug

The first parameter of DataFrame.apply (and DataFrameGroupBy.apply) is named f in pandas-stubs, but the runtime pandas signature names it func. This makes the keyword-argument form inconsistent between the stubs and runtime:

  • df.apply(func=...)valid at runtime, but rejected by the stubs (no overload variant matches).
  • df.apply(f=...)accepted by the stubs, but raises TypeError at runtime.

Only the positional form (df.apply(callable, ...)) works with both. So code that correctly calls apply(func=...) fails type checking, and code written to satisfy the stubs (apply(f=...)) crashes at runtime.

The stubs declare f (pandas-stubs/core/frame.pyi):

def apply(self, f: Callable[..., ListLikeExceptSeriesAndStr | Series], axis: AxisIndex = ...): ...

while runtime pandas declares func (pandas/core/frame.py):

def apply(self, func: AggFuncType, axis: Axis = 0, ...): ...

To Reproduce

  1. Minimal example — correct at runtime, but rejected by the stubs:
import pandas as pd

df = pd.DataFrame({"a": [1, 2, 3]})
result = df.apply(func=lambda row: row["a"] * 2, axis="columns")  # runs fine at runtime
  1. Type checker: mypy (2.1.0)

  2. Error message from mypy:

error: No overload variant of "apply" of "DataFrame" matches argument types "Callable[[Any], Any]", "str"  [call-overload]
note:     def apply(self, f: Callable[..., ...], axis: Literal['index', 0] = ..., ...) -> ...

Conversely, the form the stubs accept crashes at runtime:

df.apply(f=lambda row: row["a"] * 2, axis="columns")   # mypy: Success: no issues found
# runtime: TypeError: DataFrame.apply() missing 1 required positional argument: 'func'

System specifications

  • OS and its version: macOS 26.5.2 (Darwin 25.5.0)
  • python version: 3.14.6
  • type checker and its version: mypy 2.1.0
  • version of installed pandas-stubs: 3.0.5.260730 (with pandas 3.0.5)

Additional context

Renaming the stub parameter from f to func (matching the runtime signature) would make the keyword form consistent across all DataFrame.apply overloads. The same mismatch affects DataFrameGroupBy.apply, where the parameter is additionally declared positional-only (/), so no keyword form works there at all.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions