| -- Assignment |
| -- ---------- |
| |
| |
| [case testAssignmentWithDynamic] |
| from typing import Any |
| d = None # type: Any |
| a = None # type: A |
| |
| if int(): |
| a = d # Everything ok |
| if int(): |
| d = a |
| if int(): |
| d = d |
| d.x = a |
| d.x = d |
| |
| class A: pass |
| |
| [case testMultipleAssignmentWithDynamic] |
| from typing import Any |
| d = None # type: Any |
| a, b = None, None # type: (A, B) |
| |
| if int(): |
| d, a = b, b # E: Incompatible types in assignment (expression has type "B", variable has type "A") |
| if int(): |
| d, d = d, d, d # E: Too many values to unpack (2 expected, 3 provided) |
| |
| if int(): |
| a, b = d, d |
| if int(): |
| d, d = a, b |
| if int(): |
| a, b = d |
| s, t = d |
| |
| class A: pass |
| class B: pass |
| [builtins fixtures/tuple.pyi] |
| |
| |
| -- Expressions |
| -- ----------- |
| |
| |
| [case testCallingFunctionWithDynamicArgumentTypes] |
| from typing import Any |
| a, b = None, None # type: (A, B) |
| |
| if int(): |
| b = f(a) # E: Incompatible types in assignment (expression has type "A", variable has type "B") |
| |
| if int(): |
| a = f(a) |
| if int(): |
| a = f(b) |
| if int(): |
| a = f(None) |
| if int(): |
| a = f(f) |
| |
| def f(x: Any) -> 'A': |
| pass |
| |
| class A: pass |
| class B: pass |
| [builtins fixtures/tuple.pyi] |
| |
| [case testCallingWithDynamicReturnType] |
| from typing import Any |
| a, b = None, None # type: (A, B) |
| |
| a = f(b) # E: Argument 1 to "f" has incompatible type "B"; expected "A" |
| |
| a = f(a) |
| b = f(a) |
| |
| def f(x: 'A') -> Any: |
| pass |
| |
| class A: pass |
| class B: pass |
| [builtins fixtures/tuple.pyi] |
| |
| [case testBinaryOperationsWithDynamicLeftOperand] |
| from typing import Any |
| d = None # type: Any |
| a = None # type: A |
| c = None # type: C |
| b = None # type: bool |
| n = 0 |
| |
| d in a # E: Unsupported right operand type for in ("A") |
| d and a |
| d or a |
| if int(): |
| c = d and b # E: Incompatible types in assignment (expression has type "Union[Any, bool]", variable has type "C") |
| if int(): |
| c = d or b # E: Incompatible types in assignment (expression has type "Union[Any, bool]", variable has type "C") |
| |
| if int(): |
| c = d + a |
| if int(): |
| c = d - a |
| if int(): |
| c = d * a |
| if int(): |
| c = d / a |
| if int(): |
| c = d // a |
| if int(): |
| c = d % a |
| if int(): |
| c = d ** a |
| if int(): |
| b = d == a |
| if int(): |
| b = d != a |
| if int(): |
| b = d < a |
| if int(): |
| b = d <= a |
| if int(): |
| b = d > a |
| if int(): |
| b = d >= a |
| if int(): |
| b = d in c |
| if int(): |
| b = d and b |
| if int(): |
| b = d or b |
| |
| class A: pass |
| class C: |
| def __contains__(self, a: A) -> bool: |
| pass |
| [file builtins.py] |
| class object: |
| def __init__(self): pass |
| class bool: pass |
| class int: pass |
| class type: pass |
| class function: pass |
| class str: pass |
| |
| [case testBinaryOperationsWithDynamicAsRightOperand] |
| from typing import Any |
| d = None # type: Any |
| a = None # type: A |
| c = None # type: C |
| b = None # type: bool |
| n = 0 |
| |
| a and d |
| a or d |
| if int(): |
| c = a in d # E: Incompatible types in assignment (expression has type "bool", variable has type "C") |
| if int(): |
| c = b and d # E: Incompatible types in assignment (expression has type "Union[bool, Any]", variable has type "C") |
| if int(): |
| c = b or d # E: Incompatible types in assignment (expression has type "Union[bool, Any]", variable has type "C") |
| if int(): |
| b = a + d |
| if int(): |
| b = a / d |
| |
| if int(): |
| c = a + d |
| if int(): |
| c = a - d |
| if int(): |
| c = a * d |
| if int(): |
| c = a / d |
| if int(): |
| c = a // d |
| if int(): |
| c = a % d |
| if int(): |
| c = a ** d |
| if int(): |
| b = a in d |
| if int(): |
| b = b and d |
| if int(): |
| b = b or d |
| |
| class A: |
| def __add__(self, a: 'A') -> 'C': |
| pass |
| def __sub__(self, a: 'A') -> 'C': |
| pass |
| def __mul__(self, a: 'A') -> 'C': |
| pass |
| def __truediv__(self, a: 'A') -> 'C': |
| pass |
| def __floordiv__(self, a: 'A') -> 'C': |
| pass |
| def __mod__(self, a: 'A') -> 'C': |
| pass |
| def __pow__(self, a: 'A') -> 'C': |
| pass |
| def _lt(self, a: 'A') -> bool: |
| pass |
| def _gt(self, a: 'A') -> bool: |
| pass |
| |
| class C: pass |
| [file builtins.py] |
| class object: |
| def __init__(self): pass |
| class bool: pass |
| class int: pass |
| class type: pass |
| class function: pass |
| class str: pass |
| |
| [case testDynamicWithUnaryExpressions] |
| from typing import Any |
| d = None # type: Any |
| a = None # type: A |
| b = None # type: bool |
| if int(): |
| a = not d # E: Incompatible types in assignment (expression has type "bool", variable has type "A") |
| if int(): |
| b = not d |
| a = -d |
| class A: pass |
| [builtins fixtures/bool.pyi] |
| [out] |
| |
| [case testDynamicWithMemberAccess] |
| from typing import Any |
| d = None # type: Any |
| a = None # type: A |
| |
| if int(): |
| a = d.foo(a()) # E: "A" not callable |
| |
| if int(): |
| a = d.x |
| if int(): |
| a = d.foo(a, a) |
| d.x = a |
| d.x.y.z # E: "A" has no attribute "y" |
| |
| class A: pass |
| [out] |
| |
| [case testIndexingWithDynamic] |
| from typing import Any |
| d = None # type: Any |
| a = None # type: A |
| |
| if int(): |
| a = d[a()] # E: "A" not callable |
| d[a()] = a # E: "A" not callable |
| |
| if int(): |
| a = d[a] |
| d[a] = a |
| d[a], d[a] = a, a |
| |
| class A: pass |
| |
| [case testTupleExpressionsWithDynamci] |
| from typing import Tuple, Any |
| t2 = None # type: Tuple[A, A] |
| d = None # type: Any |
| |
| if int(): |
| t2 = (d, d, d) # E: Incompatible types in assignment (expression has type "Tuple[Any, Any, Any]", variable has type "Tuple[A, A]") |
| if int(): |
| t2 = (d, d) |
| |
| class A: pass |
| [builtins fixtures/tuple.pyi] |
| |
| [case testCastsWithDynamicType] |
| from typing import Any, cast |
| class A: pass |
| class B: pass |
| d = None # type: Any |
| a = None # type: A |
| b = None # type: B |
| if int(): |
| b = cast(A, d) # E: Incompatible types in assignment (expression has type "A", variable has type "B") |
| if int(): |
| a = cast(A, d) |
| if int(): |
| b = cast(Any, d) |
| if int(): |
| a = cast(Any, f()) |
| def f() -> None: pass |
| |
| [case testCompatibilityOfDynamicWithOtherTypes] |
| from typing import Any, Tuple |
| d = None # type: Any |
| t = None # type: Tuple[A, A] |
| # TODO: callable types, overloaded functions |
| |
| d = None # All ok |
| d = t |
| d = g |
| d = A |
| t = d |
| f = d |
| |
| def g(a: 'A') -> None: |
| pass |
| |
| class A: pass |
| class B: pass |
| [builtins fixtures/tuple.pyi] |
| |
| |
| -- Statements |
| -- ---------- |
| |
| |
| [case testDynamicCondition] |
| from typing import Any |
| d = None # type: Any |
| while d: |
| pass |
| if d: |
| pass |
| elif d: |
| pass |
| [builtins fixtures/bool.pyi] |
| |
| [case testRaiseWithDynamic] |
| from typing import Any |
| d = None # type: Any |
| raise d |
| [builtins fixtures/exception.pyi] |
| |
| [case testReturnWithDynamic] |
| from typing import Any |
| d = None # type: Any |
| |
| def f() -> None: |
| return d # Ok |
| |
| def g() -> 'A': |
| return d # Ok |
| |
| class A: pass |
| |
| |
| -- Implicit dynamic types for functions |
| -- ------------------------------------ |
| |
| |
| [case testImplicitGlobalFunctionSignature] |
| from typing import Any, Callable |
| x = None # type: Any |
| a = None # type: A |
| g = None # type: Callable[[], None] |
| h = None # type: Callable[[A], None] |
| |
| f() # E: Missing positional argument "x" in call to "f" |
| f(x, x) # E: Too many arguments for "f" |
| if int(): |
| g = f # E: Incompatible types in assignment (expression has type "Callable[[Any], Any]", variable has type "Callable[[], None]") |
| f(a) |
| f(x) |
| if int(): |
| a = f(a) |
| if int(): |
| h = f |
| |
| def f(x): pass |
| |
| class A: pass |
| |
| [case testImplicitGlobalFunctionSignatureWithDifferentArgCounts] |
| from typing import Callable |
| g0 = None # type: Callable[[], None] |
| g1 = None # type: Callable[[A], None] |
| g2 = None # type: Callable[[A, A], None] |
| a = None # type: A |
| |
| if int(): |
| g1 = f0 # E: Incompatible types in assignment (expression has type "Callable[[], Any]", variable has type "Callable[[A], None]") |
| if int(): |
| g2 = f0 # E: Incompatible types in assignment (expression has type "Callable[[], Any]", variable has type "Callable[[A, A], None]") |
| if int(): |
| g0 = f2 # E: Incompatible types in assignment (expression has type "Callable[[Any, Any], Any]", variable has type "Callable[[], None]") |
| if int(): |
| g1 = f2 # E: Incompatible types in assignment (expression has type "Callable[[Any, Any], Any]", variable has type "Callable[[A], None]") |
| |
| if int(): |
| g0 = g0 |
| if int(): |
| g2 = f2 |
| f0() |
| f2(a, a) |
| |
| def f0(): pass |
| |
| def f2(x, y): pass |
| |
| class A: pass |
| |
| [case testImplicitGlobalFunctionSignatureWithDefaultArgs] |
| from typing import Callable |
| a, b = None, None # type: (A, B) |
| |
| g0 = None # type: Callable[[], None] |
| g1 = None # type: Callable[[A], None] |
| g2 = None # type: Callable[[A, A], None] |
| g3 = None # type: Callable[[A, A, A], None] |
| g4 = None # type: Callable[[A, A, A, A], None] |
| |
| f01(a, a) # E: Too many arguments for "f01" |
| f13() # E: Missing positional argument "x" in call to "f13" |
| f13(a, a, a, a) # E: Too many arguments for "f13" |
| if int(): |
| g2 = f01 # E: Incompatible types in assignment (expression has type "Callable[[Any], Any]", variable has type "Callable[[A, A], None]") |
| if int(): |
| g0 = f13 # E: Incompatible types in assignment (expression has type "Callable[[Any, Any, Any], Any]", variable has type "Callable[[], None]") |
| if int(): |
| g4 = f13 # E: Incompatible types in assignment (expression has type "Callable[[Any, Any, Any], Any]", variable has type "Callable[[A, A, A, A], None]") |
| |
| f01() |
| f01(a) |
| f13(a) |
| f13(a, a) |
| f13(a, a, a) |
| |
| if int(): |
| g0 = f01 |
| if int(): |
| g1 = f01 |
| if int(): |
| g1 = f13 |
| if int(): |
| g2 = f13 |
| if int(): |
| g3 = f13 |
| |
| def f01(x = b): pass |
| def f13(x, y = b, z = b): pass |
| |
| class A: pass |
| class B: pass |
| [builtins fixtures/tuple.pyi] |
| |
| [case testSkipTypeCheckingWithImplicitSignature] |
| a = None # type: A |
| def f(): |
| a() |
| def g(x): |
| a() |
| a.x |
| a + a |
| if a(): |
| a() |
| class A: pass |
| [builtins fixtures/bool.pyi] |
| |
| [case testSkipTypeCheckingWithImplicitSignatureAndDefaultArgs] |
| a = None # type: A |
| def f(x=a()): |
| a() |
| def g(x, y=a, z=a()): |
| a() |
| class A: pass |
| |
| [case testImplicitMethodSignature] |
| from typing import Callable |
| g0 = None # type: Callable[[], None] |
| g1 = None # type: Callable[[A], None] |
| g2 = None # type: Callable[[A, A], None] |
| a = None # type: A |
| |
| if int(): |
| g0 = a.f # E: Incompatible types in assignment (expression has type "Callable[[Any], Any]", variable has type "Callable[[], None]") |
| if int(): |
| g2 = a.f # E: Incompatible types in assignment (expression has type "Callable[[Any], Any]", variable has type "Callable[[A, A], None]") |
| if int(): |
| a = a.f # E: Incompatible types in assignment (expression has type "Callable[[Any], Any]", variable has type "A") |
| |
| class A: |
| def g(self) -> None: |
| a = self.f(a) |
| def f(self, x): pass |
| |
| if int(): |
| g1 = a.f |
| if int(): |
| a = a.f(a) |
| |
| [case testSkipTypeCheckingImplicitMethod] |
| |
| a = None # type: A |
| class A: |
| def f(self): |
| a() |
| def g(self, x, y=a()): |
| a() |
| |
| [case testImplicitInheritedMethod] |
| from typing import Callable |
| g0 = None # type: Callable[[], None] |
| g1 = None # type: Callable[[A], None] |
| a = None # type: A |
| |
| if int(): |
| g0 = a.f # E: Incompatible types in assignment (expression has type "Callable[[Any], Any]", variable has type "Callable[[], None]") |
| |
| if int(): |
| g1 = a.f |
| if int(): |
| a = a.f(a) |
| |
| class B: |
| def f(self, x): |
| pass |
| class A(B): |
| def g(self) -> None: |
| a = self.f(a) |
| |
| [case testEmptyReturnWithImplicitSignature] |
| import typing |
| def f(): |
| return |
| class A: |
| def g(self): |
| return |
| |
| [case testVarArgsWithImplicitSignature] |
| from typing import Any |
| o = None # type: Any |
| def f(x, *a): pass |
| f() # E: Missing positional argument "x" in call to "f" |
| f(o) |
| f(o, o) |
| f(o, o, o) |
| [builtins fixtures/list.pyi] |
| |
| |
| -- Implicit types for constructors |
| -- ------------------------------- |
| |
| |
| [case testInitMethodWithImplicitSignature] |
| from typing import Callable |
| f1 = None # type: Callable[[A], A] |
| f2 = None # type: Callable[[A, A], A] |
| a = None # type: A |
| |
| A(a) # E: Missing positional argument "b" in call to "A" |
| if int(): |
| f1 = A # E: Incompatible types in assignment (expression has type "Type[A]", variable has type "Callable[[A], A]") |
| |
| A(a, a) |
| if int(): |
| f2 = A |
| |
| class A: |
| def __init__(self, a, b): pass |
| |
| [case testUsingImplicitTypeObjectWithIs] |
| |
| t = None # type: type |
| t = A |
| t = B |
| |
| class A: pass |
| class B: |
| def __init__(self): pass |
| |
| |
| -- Type compatibility |
| -- ------------------ |
| |
| |
| [case testTupleTypeCompatibility] |
| from typing import Any, Tuple |
| t1 = None # type: Tuple[Any, A] |
| t2 = None # type: Tuple[A, Any] |
| t3 = None # type: Tuple[Any, Any] |
| t4 = None # type: Tuple[A, A] |
| t5 = None # type: Tuple[Any, Any, Any] |
| |
| def f(): t1, t2, t3, t4, t5 # Prevent redefinition |
| |
| t3 = t5 # E: Incompatible types in assignment (expression has type "Tuple[Any, Any, Any]", variable has type "Tuple[Any, Any]") |
| t5 = t4 # E: Incompatible types in assignment (expression has type "Tuple[A, A]", variable has type "Tuple[Any, Any, Any]") |
| |
| t1 = t1 |
| t1 = t2 |
| t1 = t3 |
| t1 = t4 |
| t2 = t1 |
| t2 = t3 |
| t2 = t4 |
| t3 = t1 |
| t3 = t2 |
| t3 = t4 |
| t4 = t1 |
| t4 = t2 |
| t4 = t3 |
| |
| class A: pass |
| [builtins fixtures/tuple.pyi] |
| |
| [case testFunctionTypeCompatibilityAndReturnTypes] |
| from typing import Any, Callable |
| f1 = None # type: Callable[[], Any] |
| f11 = None # type: Callable[[], Any] |
| f2 = None # type: Callable[[], A] |
| f3 = None # type: Callable[[], None] |
| |
| f2 = f3 |
| |
| f1 = f2 |
| f1 = f3 |
| f2 = f11 |
| f3 = f11 |
| |
| class A: pass |
| |
| [case testFunctionTypeCompatibilityAndArgumentTypes] |
| from typing import Any, Callable |
| f1 = None # type: Callable[[A, Any], None] |
| f2 = None # type: Callable[[Any, A], None] |
| f3 = None # type: Callable[[A, A], None] |
| |
| f1 = f1 |
| f1 = f2 |
| f1 = f3 |
| |
| f2 = f1 |
| f2 = f2 |
| f2 = f3 |
| |
| f3 = f1 |
| f3 = f2 |
| f3 = f3 |
| |
| class A: pass |
| |
| [case testFunctionTypeCompatibilityAndArgumentCounts] |
| from typing import Any, Callable |
| f1 = None # type: Callable[[Any], None] |
| f2 = None # type: Callable[[Any, Any], None] |
| |
| if int(): |
| f1 = f2 # E: Incompatible types in assignment (expression has type "Callable[[Any, Any], None]", variable has type "Callable[[Any], None]") |
| |
| |
| -- Overriding |
| -- ---------- |
| |
| |
| [case testOverridingMethodWithDynamicTypes] |
| from typing import Any |
| a, b = None, None # type: (A, B) |
| |
| b.f(b) # E: Argument 1 to "f" of "B" has incompatible type "B"; expected "A" |
| a = a.f(b) |
| |
| class B: |
| def f(self, x: 'A') -> 'B': |
| pass |
| def g(self, x: 'B') -> None: |
| pass |
| class A(B): |
| def f(self, x: Any) -> Any: |
| pass |
| def g(self, x: Any) -> None: |
| pass |
| [builtins fixtures/tuple.pyi] |
| |
| [case testOverridingMethodWithImplicitDynamicTypes] |
| |
| a, b = None, None # type: (A, B) |
| |
| b.f(b) # E: Argument 1 to "f" of "B" has incompatible type "B"; expected "A" |
| a = a.f(b) |
| |
| class B: |
| def f(self, x: 'A') -> 'B': |
| pass |
| def g(self, x: 'B') -> None: |
| pass |
| class A(B): |
| def f(self, x): |
| pass |
| def g(self, x): |
| pass |
| [builtins fixtures/tuple.pyi] |
| |
| [case testOverridingMethodAcrossHierarchy] |
| import typing |
| class C: |
| def f(self, a: 'A') -> None: pass |
| class B(C): |
| def f(self, a): pass |
| class A(B): |
| def f(self, a: 'D') -> None: # E: Argument 1 of "f" is incompatible with supertype "C"; supertype defines the argument type as "A" \ |
| # N: This violates the Liskov substitution principle \ |
| # N: See https://mypy.readthedocs.io/en/stable/common_issues.html#incompatible-overrides |
| pass |
| class D: pass |
| [out] |
| |
| [case testInvalidOverrideArgumentCountWithImplicitSignature1] |
| import typing |
| class B: |
| def f(self, x: A) -> None: pass |
| class A(B): |
| def f(self, x, y): # dynamic function not type checked |
| x() |
| [out] |
| |
| [case testInvalidOverrideArgumentCountWithImplicitSignature2] |
| import typing |
| class B: |
| def f(self, x, y): pass |
| class A(B): |
| def f(self, x: 'A') -> None: # E: Signature of "f" incompatible with supertype "B" |
| pass |
| [out] |
| |
| [case testInvalidOverrideArgumentCountWithImplicitSignature3] |
| import typing |
| class B: |
| def f(self, x: A) -> None: pass |
| class A(B): |
| def f(self, x, y) -> None: # E: Signature of "f" incompatible with supertype "B" |
| x() |
| [out] |
| |
| [case testInvalidOverrideWithImplicitSignatureAndClassMethod1] |
| class B: |
| @classmethod |
| def f(cls, x, y): pass |
| class A(B): |
| @classmethod |
| def f(cls, x, y, z): pass # No error since no annotations |
| [builtins fixtures/classmethod.pyi] |
| |
| [case testInvalidOverrideWithImplicitSignatureAndClassMethod2] |
| class B: |
| @classmethod |
| def f(cls, x: int, y): pass |
| class A(B): |
| @classmethod |
| def f(cls, x, y, z): pass # No error since no annotations |
| [builtins fixtures/classmethod.pyi] |
| |
| [case testInvalidOverrideWithImplicitSignatureAndStaticMethod1] |
| class B: |
| @staticmethod |
| def f(x, y): pass |
| class A(B): |
| @staticmethod |
| def f(x, y, z): pass # No error since no annotations |
| [builtins fixtures/classmethod.pyi] |
| |
| [case testInvalidOverrideWithImplicitSignatureAndStaticMethod2] |
| class B: |
| @staticmethod |
| def f(self, x: int, y): pass |
| class A(B): |
| @staticmethod |
| def f(self, x, y, z): pass # No error since no annotations |
| [builtins fixtures/classmethod.pyi] |
| |
| |
| -- Don't complain about too few/many arguments in dynamic functions |
| -- ---------------------------------------------------------------- |
| |
| [case testTooManyArgsInDynamic] |
| def f() -> None: pass |
| def g(): |
| f(1) # Silent |
| [out] |
| |
| [case testTooFewArgsInDynamic] |
| def f(a: int) -> None: pass |
| def g(): |
| f() # Silent |
| [out] |
| |
| [case testJustRightInDynamic] |
| def f(a: int) -> None: pass |
| def g(): |
| f('') # Silent |
| [out] |