Skip to content

Commit

Permalink
Ban diamond inheritance of generic base classes
Browse files Browse the repository at this point in the history
  • Loading branch information
gnprice committed Dec 22, 2015
1 parent e9447d6 commit 8c949d9
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 0 deletions.
2 changes: 2 additions & 0 deletions mypy/maptype.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ def class_derivation_paths(typ: TypeInfo,
"""
# FIX: Currently we might only ever have a single path, so this could be
# simplified
# TODO(gregprice): Not actually true! But all paths are equivalent for
# this module's purposes.
result = [] # type: List[List[TypeInfo]]

for base in typ.bases:
Expand Down
3 changes: 3 additions & 0 deletions mypy/semanal.py
Original file line number Diff line number Diff line change
Expand Up @@ -731,6 +731,9 @@ def verify_base_classes(self, defn: ClassDef) -> bool:
info.bases = []
return False # ???
for base in nxt.bases:
if base.type in visited and len(base.type.type_vars) > 0:
self.fail('Diamond inheritance of generic base class "%s"'
% base.type.name(), defn)
if base.type not in visited:
worklist.append(base.type)
visited.add(base.type)
Expand Down
27 changes: 27 additions & 0 deletions mypy/test/data/check-multiple-inheritance.test
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,33 @@ main: note: In class "D":
main:8: error: Definition of "clear" in base class "A" is incompatible with definition in base class "B"


-- Diamond inheritance hierarchies
-- -------------------------------


[case testDiamondPlain]
class A: pass
class B(A): pass
class C(A): pass
class D(B, C): pass

a = None # type: A
d = None # type: D
a = d

[case testDiamondGeneric]
from typing import TypeVar, Generic
T = TypeVar('T')
class A(Generic[T]): pass
class B(Generic[T], A[T]): pass
class C(Generic[T], A[T]): pass
class D(Generic[T], B[T], C[T]): pass # E: Diamond inheritance of generic base class "A"

a = None # type: A[int]
d = None # type: D[int]
a = d


-- Special cases
-- -------------

Expand Down

0 comments on commit 8c949d9

Please sign in to comment.