| -- Test cases for multiple inheritance. |
| -- |
| -- Related: check-abstract.test |
| |
| |
| -- No name collisions |
| -- ------------------ |
| |
| |
| [case testSimpleMultipleInheritanceAndMethods] |
| import typing |
| class A: |
| def f(self, x: int) -> None: pass |
| class B: |
| def g(self, x: str) -> None: pass |
| class C(A, B): pass |
| c = C() |
| c.f(1) |
| c.f('') # E: Argument 1 to "f" of "A" has incompatible type "str"; expected "int" |
| c.g('') |
| c.g(1) # E: Argument 1 to "g" of "B" has incompatible type "int"; expected "str" |
| |
| [case testSimpleMultipleInheritanceAndMethods2] |
| import typing |
| class A: |
| def f(self, x: int) -> None: pass |
| class B: |
| def g(self, x): pass |
| class C(A, B): pass |
| c = C() |
| c.f(1) |
| c.f('') # E: Argument 1 to "f" of "A" has incompatible type "str"; expected "int" |
| c.g('') |
| c.g(1) |
| |
| [case testSimpleMultipleInheritanceAndInstanceVariables] |
| import typing |
| class A: |
| def f(self) -> None: |
| self.x = 1 |
| class B: |
| def g(self) -> None: |
| self.y = '' |
| class C(A, B): pass |
| c = C() |
| c.x = 1 |
| c.x = '' # E: Incompatible types in assignment (expression has type "str", variable has type "int") |
| c.y = '' |
| c.y = 1 # E: Incompatible types in assignment (expression has type "int", variable has type "str") |
| |
| [case testSimpleMultipleInheritanceAndInstanceVariableInClassBody] |
| import typing |
| class A: |
| x = 1 |
| class B: |
| y = '' |
| class C(A, B): pass |
| c = C() |
| c.x = 1 |
| c.x = '' # E: Incompatible types in assignment (expression has type "str", variable has type "int") |
| c.y = '' |
| c.y = 1 # E: Incompatible types in assignment (expression has type "int", variable has type "str") |
| |
| [case testSimpleMultipleInheritanceAndClassVariable] |
| import typing |
| class A: |
| x = 1 |
| class B: |
| y = '' |
| class C(A, B): pass |
| C.x = 1 |
| C.x = '' # E: Incompatible types in assignment (expression has type "str", variable has type "int") |
| C.y = '' |
| C.y = 1 # E: Incompatible types in assignment (expression has type "int", variable has type "str") |
| |
| |
| -- Name collisions |
| -- --------------- |
| |
| |
| [case testMethodNameCollisionInMultipleInheritanceWithValidSigs] |
| import typing |
| class A: |
| def f(self, x: int) -> None: pass |
| class B: |
| def f(self, x: int) -> None: pass |
| class C(A, B): pass |
| c = C() |
| c.f(1) |
| c.f('') # E: Argument 1 to "f" of "A" has incompatible type "str"; expected "int" |
| |
| [case testInstanceVarNameOverlapInMultipleInheritanceWithCompatibleTypes] |
| import typing |
| class A: |
| def f(self) -> None: |
| self.x = 1 |
| class B: |
| def g(self) -> None: |
| self.x = 1 |
| class C(A, B): pass |
| c = C() |
| c.x = 1 |
| c.x = '' # E: Incompatible types in assignment (expression has type "str", variable has type "int") |
| |
| [case testClassVarNameOverlapInMultipleInheritanceWithCompatibleTypes] |
| import typing |
| class A: |
| x = 1 |
| class B: |
| x = 1 |
| class C(A, B): pass |
| c = C() |
| c.x = 1 |
| c.x = '' # E: Incompatible types in assignment (expression has type "str", variable has type "int") |
| C.x = 1 |
| C.x = '' # E: Incompatible types in assignment (expression has type "str", variable has type "int") |
| |
| [case testMethodNameCollisionInMultipleInheritanceWithIncompatibleSigs] |
| import typing |
| class A: |
| def f(self, x: int) -> None: pass |
| class B: |
| def f(self, x: str) -> None: pass |
| class C(A, B): pass |
| [out] |
| main:6: error: Definition of "f" in base class "A" is incompatible with definition in base class "B" |
| |
| [case testMethodNameCollisionInMultipleInheritanceWithIncompatibleSigs2] |
| import typing |
| class A: |
| def f(self, x: int) -> None: pass |
| class B: |
| def f(self, x, y): pass |
| class C(A, B): pass |
| class D(B, A): pass |
| [out] |
| main:6: error: Definition of "f" in base class "A" is incompatible with definition in base class "B" |
| main:7: error: Definition of "f" in base class "B" is incompatible with definition in base class "A" |
| |
| |
| [case testMethodOverridingWithBothDynamicallyAndStaticallyTypedMethods] |
| class A: |
| def f(self) -> int: pass |
| class B: |
| def f(self): pass |
| class C(B, A): pass |
| class D(A, B): pass |
| [out] |
| |
| [case testInstanceVarNameOverlapInMultipleInheritanceWithInvalidTypes] |
| import typing |
| class A: |
| def f(self) -> None: |
| self.x = 1 |
| class B: |
| def g(self) -> None: |
| self.x = '' |
| class C(A, B): pass |
| [out] |
| main:8: error: Definition of "x" in base class "A" is incompatible with definition in base class "B" |
| |
| [case testClassVarNameOverlapInMultipleInheritanceWithInvalidTypes] |
| import typing |
| class A: |
| x = 1 |
| class B: |
| x = '' |
| class C(A, B): pass |
| [out] |
| main:6: error: Definition of "x" in base class "A" is incompatible with definition in base class "B" |
| |
| [case testMethodOverlapsWithClassVariableInMultipleInheritance] |
| from typing import Callable |
| class A: |
| def f(self) -> None: pass |
| class B: |
| f = '' |
| class C(A, B): pass |
| [out] |
| main:6: error: Definition of "f" in base class "A" is incompatible with definition in base class "B" |
| |
| [case testMethodOverlapsWithInstanceVariableInMultipleInheritance] |
| from typing import Callable |
| class A: |
| def f(self) -> None: pass |
| class B: |
| def g(self) -> None: |
| self.f = '' |
| class C(A, B): pass |
| [out] |
| main:7: error: Definition of "f" in base class "A" is incompatible with definition in base class "B" |
| |
| [case testMultipleInheritanceAndInit] |
| import typing |
| class A: |
| def __init__(self, x: int) -> None: pass |
| class B: |
| def __init__(self) -> None: pass |
| class C(A, B): pass |
| |
| [case testMultipleInheritanceAndDifferentButCompatibleSignatures] |
| class A: |
| def clear(self): pass |
| |
| class B: |
| def clear(self, x=None): pass |
| |
| class C(B, A): pass |
| class D(A, B): pass |
| [out] |
| main:8: error: Definition of "clear" in base class "A" is incompatible with definition in base class "B" |
| |
| |
| -- Special cases |
| -- ------------- |
| |
| |
| [case testGenericInheritanceAndOverridingWithMultipleInheritance] |
| from typing import Generic, TypeVar |
| T = TypeVar('T') |
| class G(Generic[T]): |
| def f(self, s: int) -> 'G[T]': pass |
| class A(G[int]): |
| def f(self, s: int) -> 'A': pass |
| class B(A, int): pass |
| |
| [case testCannotDetermineTypeInMultipleInheritance] |
| from typing import Callable, TypeVar |
| T = TypeVar('T') |
| class A(B, C): |
| def f(self): pass |
| class B: |
| @dec |
| def f(self): pass |
| class C: |
| @dec |
| def f(self): pass |
| def dec(f: Callable[..., T]) -> Callable[..., T]: |
| return f |
| [out] |
| main:3: error: Cannot determine type of 'f' in base class 'B' |
| main:3: error: Cannot determine type of 'f' in base class 'C' |