python / python/mypy

unpacking dict in function call with optional arguments fails

Offen
#10,008 1 Kommentar 16 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

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

Beschreibung

Bug Report

Unpacking a dict when calling a function with **kwargs should not fail. This seems to be related to #4771 and #9676, but slightly different since the function definition is wider than those reports.

To Reproduce

from __future__ import annotations

from collections.abc import Mapping
from typing import Any, cast, TYPE_CHECKING


def test(one: int | None = None, **kwargs: Any) -> int | None:
    print(repr(kwargs))
    return one


if TYPE_CHECKING:
    reveal_type(test)
    reveal_type(test())
    reveal_type(test(test='one'))
    reveal_type(test(**{'test': 'one'}))

which outputs:

test.py:13: note: Revealed type is 'def (one: Union[builtins.int, None] =, **kwargs: Any) -> Union[builtins.int, None]'
test.py:14: note: Revealed type is 'Union[builtins.int, None]'
test.py:15: note: Revealed type is 'Union[builtins.int, None]'
test.py:16: error: Argument 1 to "test" has incompatible type "**Dict[str, str]"; expected "Optional[int]"  [arg-type]

Expected Behavior

There is no issue passing kwargs via a dict and you shouldn't need to cast to a Mapping type.

Actual Behavior

There is an error message, but reveal_type(test(**cast(Mapping[str, str], {'test': 'one'}))) (or saving as a temporary variable with Mapping as its type) will allow the code to succeed.

Your Environment

  • Mypy version used: 0.800
  • Mypy command-line flags: --show-error-codes
  • Mypy configuration options from mypy.ini (and other config files):
  • Python version used: 3.8

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

Führen Sie den bereitgestellten Python-3.8-Reproducer mit mypy und --show-error-codes aus und vergleichen Sie direkte Schlüsselwortargumente mit dem Fall des Dictionary-Unpackings. Verfolgen Sie das Argument-Unpacking zusammen mit optionalen Parametern und **kwargs; abgeschlossen ist die Aufgabe, wenn der Aufruf mit Dictionary-Unpacking ohne einen Mapping cast zu erfordern akzeptiert wird und den erwarteten Rückgabetyp 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
45/100

Neue Issues direkt in Ihr Postfach

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