Type narrowing for dict.get("key") is not None
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 20.6k
- Forks
- 3.3k
- PR merge metrics
- PR metrics pending
Description
Bug Report
See Code and Explanation below
To Reproduce
from typing import TypedDict, Optional
class DictA(TypedDict):
my_value: str
class DictB(TypedDict, total=False):
my_optional_dict: Optional[DictA]
def test(arg: DictB) -> None:
if arg.get("my_optional_dict") is not None:
print(arg["my_optional_dict"]["my_value"])
Expected Behavior
According to the TypedDict, we have 3 cases for the Key my_optional_dict:
- The Dict did not have this Key (indicated by
total=False - The Value of this Key is
None - The Value of this Key is a
DictA
If we look at the if in the test function, it does 2 things:
- Check if the Dict contains this Key
- Check if the value is not None
This means, that the my_optional_dict of arg is always of the type DictA, so mypy should not see a problem here.
Actual Behavior
main.py:14: error: Value of type "Optional[DictA]" is not indexable [index]
Found 1 error in 1 file (checked 1 source file)
Your Environment
- Mypy version used: 1.0.0
- Mypy command-line flags: None
- Mypy configuration options from
mypy.ini(and other config files): None - Python version used: 3.11.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 provided TypedDict reproducer with mypy using the stated Python 3.11 example and no configuration flags. Trace how the type checker narrows arg.get("my_optional_dict") after the None check, then add a regression test based on test() that passes without an indexability error.
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
- Mostly clear
- Newbie friendliness
- 35/100