mypy ignores type checking and produces error for union types when using `is` keyword to check the boolean result from `isinstance()`
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 the is True or is False keywords in the if statement along with isinstance, mypy does not recognize the type checking and produces an error, and ignores the instance type checking.
To Reproduce
from typing import Union
class A:
prop: str = "Test"
prop2: int = 999
class B:
prop: str = "Test 2"
AB = Union[A, B]
if __name__ == '__main__':
test_var: AB = A()
if isinstance(test_var, A) is True:
print(test_var.prop2)```
Playground: https://mypy-play.net/?mypy=latest&python=3.9&gist=7c4401069c861413b72a395a4ce92757
Expected Behavior
I expected that both expressions below were interpreted the same way by mypy as both are syntactically valid and produce the same result:
Using the is keyword to check the result:
if isinstance(test_var, A) is True:
pass
No is keyword:
if isinstance(test_var, A):
pass
Actual Behavior
main.py:19: error: Item "B" of "Union[A, B]" has no attribute "prop2" [union-attr]
Found 1 error in 1 file (checked 1 source file)
Your Environment
- Mypy version used: 0.991
- Mypy command-line flags:
--follow-imports silent - Mypy configuration options from
mypy.ini(and other config files):-
python_version = 3.9 warn_return_any = True warn_unused_configs = True ignore_missing_imports = True disallow_untyped_defs = True disallow_incomplete_defs = True check_untyped_defs = True disallow_untyped_decorators = True no_implicit_optional = True strict_equality = True warn_redundant_casts = True warn_unused_ignores = True show_error_codes = True
-
- Python version used: 3.9
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 reproducing the reported example in the linked mypy playground with Python 3.9 and mypy 0.991, comparing isinstance(test_var, A) with isinstance(test_var, A) is True. Trace how mypy narrows union types for these conditions and add a regression test; done means both forms recognize test_var as A without the union-attribute 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
- 42/100