python / python/mypy

Union of Literals as key in union of TypedDict false positive

Offen
#14,459 4 Kommentare 1 Reaktion 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

bug topic-typed-dict topic-union-types
Vorherrschende Sprache
Python
Sterne
20.6k
Forks
3.3k
PR-Merge-Kennzahlen
PR-Kennzahlen ausstehend

Beschreibung

Bug Report
The function

def get_value(key: CombinedDictKey, mapping: CombinedDict):
    return mapping[key]

raises an error when mapping is a union of two TypedDicts and key is a union of two Literals containing the keys of those TypedDicts. It works when typed with just one of the Literals and TypedDicts.

To Reproduce

from typing import Literal, TypedDict, Union

class DictA(TypedDict):
    x: int
    y: int

class DictB(TypedDict):
    z: str

class DictAB(DictA, DictB):
    pass

DictAKey = Literal["x", "y"]
DictBKey = Literal["z"]
DictABKey = Union[DictAKey, DictBKey]

dict_a = DictA(x=1, y=2)
dict_b = DictB(z="z")
dict_ab = DictAB(**dict_a, **dict_b)  # type: ignore  # Unrelated issue #11108

def get_value_from_A(key: DictAKey, mapping: DictA):
    return mapping[key]  # Passes type check as expected

def get_value_from_B(key: DictBKey, mapping: DictB):
    return mapping[key]  # Passes type check as expected

def get_value_from_AB(key: DictABKey, mapping: DictAB):
    return mapping[key]  # Fails type check with error: TypedDict key must be a string literal

Expected Behavior
return mapping[key] passes typing in all three cases.

Actual Behavior
In the case of get_value_from_AB, return mapping[key] raises error: TypedDict key must be a string literal; expected one of ("z", "x", "y"). This is unexpected as it passes for the functions typed with only one of DictA or DictB.

Your Environment

  • Mypy version used: 0.991
  • Python version used: 3.11.0

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 damit, die bereitgestellte Python-3.11-Reproduktion gegen mypy auszuführen, und verfolge anschließend die Validierung von TypedDict-Schlüsseln für eine Union aus Literal-Schlüsseln und TypedDict-Zuordnungen. Als abgeschlossen gilt die Aufgabe, wenn get_value_from_AB ohne den False Positive typgeprüft wird und die Fälle mit einem einzelnen Dictionary weiterhin erfolgreich sind.

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
Ruhig
Klarheit
Klar beschrieben
Anfängerfreundlichkeit
48/100

Neue Issues direkt in Ihr Postfach

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