Bug Report
Mypy fails to narrow the type of a dictionary key from str to a Literal type even after an existence check with in operator. This pattern is commonly used and type-safe, as the runtime check guarantees the key exists and thus must be one of the literal values.
To Reproduce
from typing import Literal
KeyType = Literal["a", "b", "c"]
data: dict[KeyType, int] = {"a": 1, "b": 2, "c": 3}
def process(key: str) -> int:
if key in data:
return data[key] # error: Invalid index type "str" for "dict[Literal['a', 'b', 'c'], int]"
return 0
Playground link: https://mypy-play.net/?mypy=latest&python=3.11&gist=92110930ab70a8949ae51cbcf8b8cb5f
Expected Behavior
After checking key in data, mypy should recognize that key must be one of the literal values defined in KeyType since it exists as a key in the dictionary. Therefore, the dictionary access data[key] should type-check successfully.
Actual Behavior
error: Invalid index type "str" for "dict[Literal['a', 'b', 'c'], int]"; expected type "Literal['a', 'b', 'c']" [index]
Your Environment
- Mypy version used: 1.13.0
- Python version used: 3.11.10
Bug Report
Mypy fails to narrow the type of a dictionary key from
strto aLiteraltype even after an existence check withinoperator. This pattern is commonly used and type-safe, as the runtime check guarantees the key exists and thus must be one of the literal values.To Reproduce
Playground link: https://mypy-play.net/?mypy=latest&python=3.11&gist=92110930ab70a8949ae51cbcf8b8cb5f
Expected Behavior
After checking
key in data, mypy should recognize thatkeymust be one of the literal values defined inKeyTypesince it exists as a key in the dictionary. Therefore, the dictionary accessdata[key]should type-check successfully.Actual Behavior
Your Environment