python / python/mypy

`*args` and `**kwargs` are allowed even to methods with no arguments

Offen
#13,380 3 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

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

Beschreibung

I am working on removing dict and **kwargs hack from mypy after https://github.com/python/typeshed/pull/8517 is merged.

But, I found a very confusing thing in how *args and **kwargs are checked.

Simple repro (all of the examples below work):

def some() -> None: ...

# args
some(*[1, 2])
args = [1, 2]
some(*args)

# kwargs
some(**{'a': 1})
kw = {'a': 2}
some(**kw)

All of these would raise TypeError in runtime.
I think that the main idea was to allow calls like some(*[]) and some(**{}) which are fine in runtime.

This affects how overloads are selected in complex cases like:

class dict2(Generic[KT, VT]):
    @overload
    def __init__(self, __iterable: Iterable[Tuple[KT, VT]]) -> None: pass
    @overload
    def __init__(self: "dict2[str, VT]", __iterable: Iterable[Tuple[str, VT]], **kwargs: VT) -> None: pass

it = [(1, 'x')]
kw = {'x': 'y'}
reveal_type(dict2(it, **kw))

It looks like the second @overload will raise an error: Iterable[Tuple[str, VT]] is required, but Iterable[Tuple[int, str]] is given.

But it does not, because of how **kwargs are silently ignored. So, first @overload always matches.

This is broken, if you ask me 😢

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

Beginne mit dem im Reproducer beschriebenen Verhalten bei der Aufrufprüfung und Überladungsauswahl für *args und **kwargs. Überprüfe, wie Aufrufe einer Funktion ohne Argumente nichtleere entpackte Argumente und Schlüsselwortargumente behandeln, und bewahre dabei gültiges leeres Entpacken. Als abgeschlossen gilt die Aufgabe, wenn ungültige Aufrufe zur Laufzeit abgewiesen werden und das dict2-Überladungsbeispiel entweder korrekt auswählt oder Fehler meldet.

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
35/100

Neue Issues direkt in Ihr Postfach

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