Skip to content

Invalid ParamSpec usage in function with added kwargs not reported as error #14832

@sterliakov

Description

@sterliakov

Bug Report

According to PEP-612,

Placing keyword-only parameters between the *args and **kwargs is forbidden.

However, mypy doesn't reject such usage.

To Reproduce

from __future__ import annotations

from typing import TypeVar, ParamSpec, Protocol

_P = ParamSpec('_P')
_R = TypeVar('_R', covariant=True)

class BetterCallable(Protocol[_P, _R]):
    def __call__(self, *args: _P.args, x: int, **kwargs: _P.kwargs) -> _R: ...

Playground

Also consider this code quoted from PEP-612:

from __future__ import annotations
from typing import TypeVar, ParamSpec, Callable, Concatenate

P = ParamSpec('P')

def add(f: Callable[P, int]) -> Callable[Concatenate[str, P], None]:

  def foo(s: str, *args: P.args, **kwargs: P.kwargs) -> None:  # Accepted
    pass

  def bar(*args: P.args, s: str, **kwargs: P.kwargs) -> None:  # Rejected
    pass

  return foo                                                   # Accepted

And here's another playground.

Expected Behavior

In first case the __call__ definition should be flagged as error.

In second case the behaviour should match the inline comments.

Actual Behavior

In first case no errors are found.

In second case foo is rejected due to named arguments (this violates PEP-612, but is easily fixable with __s arg name instead, as usual, error message can be improved here). while bar is accepted, also violating the PEP:

main.py:14: error: Incompatible return value type (got "Callable[[Arg(str, 's'), **P], None]", expected "Callable[[str, **P], None]")  [return-value]
main.py:14: note: This is likely because "foo" has named arguments: "s". Consider marking them positional-only
Found 1 error in 1 file (checked 1 source file)

Your Environment

  • Mypy version used: master, 1.0.1
  • Mypy command-line flags: --strict and without it
  • Mypy configuration options from mypy.ini (and other config files): none
  • Python version used: 3.10, 3.11

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugmypy got something wrongtopic-paramspecPEP 612, ParamSpec, Concatenate

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions