python / python/mypy

Protocol incorrectly matches when positional or keyword parameter matches *args

Offen
#21,014 3 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

bug
Vorherrschende Sprache
Python
Sterne
20.6k
Forks
3.3k
PR-Merge-Kennzahlen
PR-Kennzahlen ausstehend

Beschreibung

Bug Report

When a protocol defines a function with a keyword or positional parameter (a: int) -> None, a concrete function where said parameter is missing, but matches the *args parameter (*args: int) -> None will be seen as implementing the protocol.

I would expect (a: int) -> None to also need matching **kwargs such as (*args: int, **kwargs: int) -> None and for it to only match *args alone when specified as a positional only argument (e.g. (a: int, /) -> None)

Otherwise it cannot be called safely, pyright and ty both successfully raise errors for this case.

To Reproduce

https://mypy-play.net/?mypy=master&python=3.14&flags=strict&gist=a5f86e32e70cbc84c45a53db5426f78f

Expected Behavior

main.py:13: error: Argument 1 to "f" has incompatible type "C"; expected "P"  [arg-type]

because calling the method as foo(a=1) would fail.

Actual Behavior

mypy:

Success: no issues found in 1 source file

pyright:

Argument of type "C" cannot be assigned to parameter "o" of type "P" in function "f"
  "C" is incompatible with protocol "P"
    "foo" is an incompatible type
      Type "(*args: int) -> None" is not assignable to type "(a: int) -> None"
        Missing keyword parameter "a"  (reportArgumentType)

ty:

Argument to function `f` is incorrect: Expected `P`, found `C` (invalid-argument-type) [Ln 17, Col 3]

python:

Traceback (most recent call last):
  File "xxx.py", line 17, in <module>
    f(C())
    ~^^^^^
  File "xxx.py", line 14, in f
    o.foo(a=1)
    ~~~~~^^^^^
TypeError: C.foo() got an unexpected keyword argument 'a'

Your Environment

  • Mypy version used: 1.19.1 and master
  • Mypy command-line flags: --strict
  • Mypy configuration options from mypy.ini (and other config files):
  • Python version used: 1.14

Beitragsleitfaden

Beitragsleitfaden öffnen

Erste Schritte

  1. Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
  3. Forke das Repository und arbeite in einem Branch.
  4. Öffne einen Pull Request, der die Issue-Nummer nennt.

Rechercherichtung

Reproduziere das verlinkte mypy-play-Beispiel mit mypy master, Python 3.14 und --strict. Verfolge die Behandlung der Protokollkompatibilität für die gezeigten Signaturen von foo und vergleiche das Ergebnis mit pyright und ty. Abgeschlossen ist die Aufgabe, wenn mypy den erwarteten incompatible-protocol-Fehler meldet und dabei den positional-only-Fall beibehält.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
python
Bereich
devtools
Issue-Typ
Bug
Schwierigkeit
4/5
Geschätzter Aufwand
3-5 Tage
Aktivitätsstatus
Veraltet
Klarheit
Größtenteils klar
Anfängerfreundlichkeit
42/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.