Closed
Description
Hi, i may have found a false-positive in mypy,
Example
Below is a simplified version of a custom property we use. In my understanding the interfaces of A
and B
are compatible.
from typing import Union, Callable, Type
# similar to a get-only property
class MyProperty:
def __init__(self, func: Callable[['B'], int]) -> None:
self.func = func
def __get__(self, instance: 'B', owner: Type['B']) -> int:
return self.func(instance)
# This class has an attribute 'x'
class A:
def __init__(self) -> None:
self.x = 123
# This class has a property 'x'
class B:
@MyProperty
def x(self) -> int:
return 456
def foo(a: Union[A, B]) -> int:
return a.x # mypy detects an error here
Actual Behavior
Running mypy --strict test.py
yields an error
test.py:25: error: Argument 1 to "__get__" of "MyProperty" has incompatible type "Union[A, B]"; expected "B"
test.py:25: error: Argument 2 to "__get__" of "MyProperty" has incompatible type "Union[Type[A], Type[B]]"; expected "Type[B]"
Found 2 errors in 1 file (checked 1 source file)
It looks like mypy thinks that instances of type A
also use the property which is not true.
Expected Behavior
The expected behavior would be that mypy accepts the code without an error.
Versions
I am using python==3.8.1
and mypy==0.790+dev.6ee562a8f3e69ac134f8c501b79b3712c9e24bbd
Notes
Replacing the @MyProperty
with @property
or @functools.cached_property
works as expected. Changing foo
to acceppt either A
or B
also works as expected.