Flow-sensitive typing ignores dictionary key mutation
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 20.6k
- Forks
- 3.3k
- PR merge metrics
- PR metrics pending
Description
Bug Report
mypy allows runtime type checks for dictionary items. However it ignores subsequent dictionary mutations. This leads to mypy accepting code that fails at runtime.
To Reproduce
from typing import Dict, Optional
foo_dict: Dict[str, Optional[str]] = {'bar': 'baz'}
if foo_dict['bar'] is not None:
foo_dict['bar'] = None
foo_dict['bar'].upper()
Expected Behavior
mypy reports .upper() call as error. This is similar to what already happens with object attributes:
from dataclasses import dataclass
from typing import Optional
@dataclass
class Foo:
bar: Optional[str]
foo = Foo(bar='baz')
if foo.bar is not None:
foo.bar = None
foo.bar.upper()
For such code mypy outputs the following error: "None" has no attribute "upper".
Actual Behavior
mypy reports no error.
Your Environment
- Mypy version used: 0.812
- Mypy command-line flags:
--strict - Mypy configuration options from
mypy.ini(and other config files): none - Python version used: 3.6.8
- Operating system and version: Windows 8.1
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 Python reproduction with mypy --strict and compare it with the dataclass attribute example, confirming the dictionary case is accepted while the attribute case is rejected. Trace the flow-sensitive narrowing logic for dictionary item expressions and add coverage for the mutation; done when mypy reports the .upper() call as an error.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- compilers, devtools
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100