Incorrect type narrowing on union of `TypedDict`
Open
Nobody has claimed this yet.
bug
topic-type-narrowing
topic-typed-dict
- Dominant language
- Python
- Stars
- 20.6k
- Forks
- 3.3k
- PR merge metrics
- PR metrics pending
Description
from typing import Any, TypedDict
class _SessionData(TypedDict):
created: int
session: dict[str, Any]
class _EmptyDict(TypedDict):
"""Empty dict for typing."""
SessionData = _SessionData | _EmptyDict
data: SessionData
reveal_type(data)
a = data if data else None
reveal_type(a)
aiohttp_session/__init__.py:56: note: Revealed type is "Union[TypedDict('aiohttp_session._SessionData', {'created': builtins.int, 'session': builtins.dict[builtins.str, Any]}), TypedDict('aiohttp_session._EmptyDict', {})]"
aiohttp_session/__init__.py:58: note: Revealed type is "Union[TypedDict('aiohttp_session._EmptyDict', {}), None]"
I also get the same result if I make it not data. The _SessionData type just disappears for no reason and it keeps saying the empty dict will be the result regardless of the boolean check.
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 union example and checking the two reveal_type results reported from aiohttp_session/init.py. Trace mypy's boolean narrowing for the union and verify that both the non-empty and empty TypedDict branches are handled correctly for both data and not data.
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
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100