mypy
mypy copied to clipboard
Union of Literals as key in union of TypedDict false positive
Bug Report The function
def get_value(key: CombinedDictKey, mapping: CombinedDict):
return mapping[key]
raises an error when mapping
is a union of two TypedDict
s and key
is a union of two Literals
containing the keys of those TypedDict
s. It works when typed with just one of the Literal
s and TypedDict
s.
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