python / python/mypy

Union of Literals as key in union of TypedDict false positive

Aperta
#14,459 4 commenti 1 reazione 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

bug topic-typed-dict topic-union-types
Lingua principale
Python
Stelle
20.6k
Fork
3.3k
Metriche di merge delle PR
Metriche PR in attesa

Descrizione

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

Guida per i contributori

Apri la guida per i contributori

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Direzione di ricerca

Inizia eseguendo la riproduzione fornita in Python 3.11 con mypy, quindi traccia la validazione delle chiavi TypedDict per un’unione di chiavi Literal e mapping TypedDict. Il lavoro è completato quando get_value_from_AB supera il controllo dei tipi senza il falso positivo, mentre i casi con un singolo dizionario continuano a superare il controllo.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Valutazione

Stack tecnologico
python
Ambito
devtools
Tipo di issue
Bug
Difficoltà
4/5
Tempo stimato
3-5 giorni
Stato di attività
Tranquilla
Chiarezza
Specificata chiaramente
Idoneità per principianti
48/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.