Type narrowing fails for union of iterable and dictionary when using `isinstance(x, Iterable)` in a conditional
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 20.6k
- Forks
- 3.3k
- PR merge metrics
- PR metrics pending
Description
Bug Report
When using Union[Iterable[int], Dict[str, int]] together with isinstance(x, Iterable) in a conditional, the narrowing of the type does not work as expected. The previously correctly narrowed type is reverted to the un-narrowed type inside the branch.
To Reproduce
from typing import Dict, Iterable, Union
def test_iterable(x: Union[Iterable[int], Dict[str, int]]) -> Iterable[int]:
if isinstance(x, dict):
return [1, 2, 3]
reveal_type(x) # typing.Iterable[builtins.int]
if isinstance(x, Iterable):
reveal_type(x) # Union[typing.Iterable[builtins.int], builtins.dict[builtins.str, builtins.int]]
return x # mypy falsely returns an error here
Expected Behavior
The type of x should be correctly narrowed down to Iterable[int].
Actual Behavior
Running mypy returns:
example.py:10: error: Incompatible return value type (got "Union[Iterable[int], Dict[str, int]]", expected "Iterable[int]")
Found 1 error in 1 file (checked 1 source file)
The problem persists even if the second if is changed to elif.
Your Environment
I used a clean virtual environment to test, only mypy was installed.
- Mypy version used: 0.971
- Python version used: 3.9.5
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 with the reproducer in example.py and run mypy against it to confirm the reported error with the union and isinstance checks. Trace the type narrowing behavior until the branch reports Iterable[int] as expected, then verify that the example completes without the incompatible return 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
- 45/100