-
-
Notifications
You must be signed in to change notification settings - Fork 3.1k
Description
When type checking the following example.py:
from typing import Type
from typing import TypeVar
_Base = TypeVar('_Base', bound='Base')
class Meta(type):
def method_to_access_a_special_instance(cls: Type[_Base]) -> _Base:
# In the real code, this returns some special instance of cls instead of `None`.
return None # type: ignore
@property
def property_to_access_a_special_instance(cls: Type[_Base]) -> Base:
# In the real code, this returns some special instance of cls instead of `None`.
return None # type: ignore
class Base(metaclass=Meta):
pass
class Sub(Base):
pass
a = Base()
a = Base.method_to_access_a_special_instance() # Line 29
b = Sub()
b = Base.method_to_access_a_special_instance() # Line 32
b = Sub.method_to_access_a_special_instance() # Line 33
a = Base.property_to_access_a_special_instance # Line 35
b = Sub.property_to_access_a_special_instance # Line 36Then mypy produces the following errors:
example.py:32: error: Incompatible types in assignment (expression has type "Base", variable has type "Sub")
example.py:35: error: Invalid method type
example.py:36: error: Incompatible types in assignment (expression has type "Base", variable has type "Sub")
example.py:36: error: Invalid method type
Expected results:
-
Lines 29 and 33 are accepted by
mypy, as they should. -
Line 32 is properly rejected because
bhas the typeSuband we assign aBaseto it.
Unexpected results (bugs?):
-
Lines 35 and 36 are rejected with the message
Invalid method type. This seems strange, as the only difference between them and the valid lines 29 and 33 is that the code is using a property instead of a method. -
Line 36 also triggers an additional rejection claiming that the property returns a different type
Basethan the expected typeSub. Again this is strange sincemypycorrectly deduces the return type of the method, but gets confused and deduces a different type when using a property.
Workaround:
For now, I am using the method syntax, since the property syntax is rejected by mypy. However, this causes ugliness in the code. For example, I need to write something like MyClass.special_instance()[x], when I would much rather write MyClass.special_instance[x] instead.