mypy
mypy copied to clipboard
Incompatible definition of generic field on multiple base classes
[BUG] Edited for a clearer example Given this code:
# mypy version 0.770
from typing import Generic, TypeVar
T = TypeVar("T", int, str)
class A:
foo: int
class B(Generic[T]):
foo: T
class C(B[int], A):
pass
reveal_type(A().foo)
reveal_type(B().foo)
reveal_type(C().foo)
I get this output:
example.py:11: error: Definition of "foo" in base class "B" is incompatible with definition in base class "A"
example.py:14: note: Revealed type is 'builtins.int'
example.py:15: note: Revealed type is 'builtins.int*'
example.py:16: note: Revealed type is 'builtins.int*'
I couldn't find what builtins.int*. The code makes sense though, right?
Yeah, this is a mypy bug. Likely related to https://github.com/python/mypy/issues/7724
Still happening with mypy 0.960 :( Although, now without "*" in the revealed types.
I think I just encountered a modified version of this in django-stubs: https://github.com/typeddjango/django-stubs/issues/1227 . Due to the structure of the classes we are trying to type, the attribute is defined as generic in both base classes, and passed as a type parameter to each:
from typing import Generic, TypeVar
T = TypeVar("T", int, str)
class A(Generic[T]):
foo: T
class B(Generic[T]):
foo: T
class C(Generic[T], B[T], A[T]):
pass
c: C[int] = C()
reveal_type(A().foo)
reveal_type(B().foo)
reveal_type(c.foo)
I just ran into the same issue. I don't see it explicitly mentioned above, but one workaround is to explicitly type the attribute in the concrete class (if that's an option; i.e. if the type is resolved in the class definition rather than the variable declaration); e.g.
from typing import Generic, TypeVar
T = TypeVar('T')
class A(Generic[T]):
value: T
class B(Generic[T]):
value: T
class C(A[int], B[int]):
value: int