List[Literal[...]] type being narrowed where it shouldn't be
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 20.6k
- Forks
- 3.3k
- PR merge metrics
- PR metrics pending
Description
Bug Report
Adding an if check on a specific index of a List of Literals seems to narrow down its scope, even though the list can be modified and the value at that index can change.
To Reproduce
Run mypy over this piece of code:
foo: List[Literal['a', 'b']] = ['a', 'b', 'a']
if foo[0] == 'a':
print('a')
exit()
foo.pop(0)
reveal_type(foo[0])
if foo[0] == 'a':
pass
Expected Behavior
Revealed type to be Literal['a', 'b'], and the conditional to be valid.
Actual Behavior
t.py:11: note: Revealed type is 'Literal['b']'
t.py:12: error: Non-overlapping equality check (left operand type: "Literal['b']", right operand type: "Literal['a']")
Your Environment
- Mypy version used: 0.790
- Mypy command-line flags:
--strict - Python version used: 3.9.1 64-bit
- Operating system and version: Fedora 33 x86_64
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by running the provided Python reproducer with mypy 0.790 and inspect the type-narrowing behavior for indexed mutable Lists of Literals. Trace the narrowing entry point for foo[0] through the checker; done means reveal_type(foo[0]) remains Literal['a', 'b'] after pop(0), and the later equality check is accepted.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- devtools
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 42/100