A working example of the issue (Python 3.8):
from typing import Union
class TestA:
def test(self) -> str:
return "testa"
class TestB:
def test(self) -> str:
return "testb"
tests = Union[TestA, TestB]
more = Union[TestA, TestB, str]
def test_pass(p: tests) -> str:
return p.test() # No error
def test_fail(p: more) -> str:
if type(p) in [TestA, TestB]:
return p.test() # Item "str" of "Union[TestA, TestB, str]" has no attribute "test"
else:
return ""
print(test_fail(TestA())) # "testa"
print(test_fail(TestB())) # "testb"
print(test_fail("str")) # "str"
I have this exact scenario showing up in a few places in my codebase and it's really bothering me I have to disable type checking on these lines. Is this something mypy is expected to miss or am I the one in error here? The error being returned seems unreasonable since a str could never make it to that leg of the conditional.