-
-
Notifications
You must be signed in to change notification settings - Fork 3k
Description
Let's start with a couple of base classes in a classical diamond-inheritance shape, with member conflict explicitly solved:
class A:
class M:
pass
class B0(A):
class M(A.M):
pass
class B1(A):
class M(A.M):
pass
class C(B0,B1):
class M(B0.M, B1.M):
pass
All of these in real code are abstract base classes, classes A
, B0
, B1
all add behaviors of their own; class C
is here precisely to provide this version of M
compatible with both B0
and B1
and deal with diamond inheritance in a "centralized" way, so all classes deriving from B0
and B1
don't have to duplicate the same version of M
over and over. It could, though, also add behavior of its own.
More abstract classes derive from B0
and B1
, each adding more behavior:
class D0(B0):
pass
class D1(B1):
pass
And then comes concrete class deriving from D0
and D1
, deriving from C
to get the diamond inheritance solved:
class D(D0,D1,C):
pass
python
has no issue with this, and understands D.M
as defined as C.M
. mypy
on the other hand does not take python's resolution of the problem into account, and compares all bases classes, leading to false positive:
test-mypy-diamond-inheritance.py:22: error: Definition of "M" in base class "B0" is incompatible with definition in base class "B1" [misc]
To Reproduce
See https://mypy-play.net/?gist=132dcea42366fad6d56d9c150d8e6c60