| -- Inferring locals/globals with simple types |
| -- ------------------------------------------ |
| |
| |
| [case testInferSimpleGvarType] |
| import typing |
| x = A() |
| y = B() |
| x = B() # Fail |
| x = A() |
| x = y # Fail |
| x = x |
| class A: pass |
| class B: pass |
| [out] |
| main:4: error: Incompatible types in assignment (expression has type "B", variable has type "A") |
| main:6: error: Incompatible types in assignment (expression has type "B", variable has type "A") |
| |
| [case testInferSimpleLvarType] |
| import typing |
| def f() -> None: |
| x = A() |
| y = B() |
| x = B() # Fail |
| x = A() |
| x = y # Fail |
| x = x |
| class A: pass |
| class B: pass |
| [out] |
| main:5: error: Incompatible types in assignment (expression has type "B", variable has type "A") |
| main:7: error: Incompatible types in assignment (expression has type "B", variable has type "A") |
| |
| [case testLvarInitializedToVoid] |
| import typing |
| def f() -> None: |
| a = g() # E: "g" does not return a value |
| #b, c = g() # "g" does not return a value TODO |
| |
| def g() -> None: pass |
| [out] |
| |
| [case testInferringLvarTypeFromArgument] |
| import typing |
| def f(a: 'A') -> None: |
| b = a |
| b = B() # E: Incompatible types in assignment (expression has type "B", variable has type "A") |
| b = a |
| a = b |
| |
| class A: pass |
| class B: pass |
| [out] |
| |
| [case testInferringLvarTypeFromGvar] |
| |
| g = None # type: B |
| |
| def f() -> None: |
| a = g |
| a = A() # E: Incompatible types in assignment (expression has type "A", variable has type "B") |
| a = B() |
| |
| class A: pass |
| class B: pass |
| [out] |
| |
| [case testInferringImplicitDynamicTypeForLvar] |
| import typing |
| def f() -> None: |
| a = g() |
| None(a) # E: None not callable |
| a.x() |
| |
| def g(): pass |
| [out] |
| |
| [case testInferringExplicitDynamicTypeForLvar] |
| from typing import Any |
| g = None # type: Any |
| |
| def f(a: Any) -> None: |
| b = g |
| None(b) # E: None not callable |
| a.x() |
| [out] |
| |
| |
| -- Inferring types of local variables with complex types |
| -- ----------------------------------------------------- |
| |
| |
| [case testInferringTupleTypeForLvar] |
| |
| def f() -> None: |
| a = A(), B() |
| aa = None # type: A |
| bb = None # type: B |
| bb = a[0] # E: Incompatible types in assignment (expression has type "A", variable has type "B") |
| aa = a[1] # E: Incompatible types in assignment (expression has type "B", variable has type "A") |
| aa = a[0] |
| bb = a[1] |
| |
| class A: pass |
| class B: pass |
| [builtins fixtures/tuple.pyi] |
| [out] |
| |
| [case testInferringTupleTypeForLvarWithNones] |
| import typing |
| def f() -> None: |
| a = A(), None # E: Need type annotation for variable |
| b = None, A() # E: Need type annotation for variable |
| |
| class A: pass |
| [builtins fixtures/tuple.pyi] |
| [out] |
| |
| [case testInferringGenericTypeForLvar] |
| from typing import TypeVar, Generic |
| T = TypeVar('T') |
| class A(Generic[T]): pass |
| a_i = None # type: A[int] |
| a_s = None # type: A[str] |
| |
| def f() -> None: |
| a_int = A() # type: A[int] |
| a = a_int |
| a = a_s # E: Incompatible types in assignment (expression has type A[str], variable has type A[int]) |
| a = a_i |
| [builtins fixtures/tuple.pyi] |
| [out] |
| |
| [case testInferringFunctionTypeForLvar] |
| import typing |
| def f() -> None: |
| a = g |
| a(B()) # E: Argument 1 has incompatible type "B"; expected "A" |
| a(A()) |
| |
| def g(a: 'A') -> None: pass |
| |
| class A: pass |
| class B: pass |
| [out] |
| |
| [case testInferringFunctionTypeForLvarFromTypeObject] |
| import typing |
| def f() -> None: |
| a = A |
| a(A()) # E: Too many arguments |
| a() |
| t = a # type: type |
| |
| class A: pass |
| [out] |
| |
| |
| -- Inferring variable types in multiple definition |
| -- ----------------------------------------------- |
| |
| |
| [case testInferringLvarTypesInMultiDef] |
| import typing |
| def f() -> None: |
| a, b = A(), B() |
| a = b # E: Incompatible types in assignment (expression has type "B", variable has type "A") |
| a = B() # E: Incompatible types in assignment (expression has type "B", variable has type "A") |
| b = A() # E: Incompatible types in assignment (expression has type "A", variable has type "B") |
| |
| a = A() |
| b = B() |
| |
| class A: pass |
| class B: pass |
| [out] |
| |
| [case testInferringLvarTypesInTupleAssignment] |
| from typing import Tuple |
| def f() -> None: |
| t = None # type: Tuple[A, B] |
| a, b = t |
| a = b # E: Incompatible types in assignment (expression has type "B", variable has type "A") |
| a = B() # E: Incompatible types in assignment (expression has type "B", variable has type "A") |
| b = A() # E: Incompatible types in assignment (expression has type "A", variable has type "B") |
| |
| a = A() |
| b = B() |
| |
| class A: pass |
| class B: pass |
| [out] |
| |
| [case testInferringLvarTypesInNestedTupleAssignment1] |
| from typing import Tuple |
| def f() -> None: |
| t = None # type: Tuple[A, B] |
| a1, (a, b) = A(), t |
| a = b # E: Incompatible types in assignment (expression has type "B", variable has type "A") |
| a = B() # E: Incompatible types in assignment (expression has type "B", variable has type "A") |
| b = A() # E: Incompatible types in assignment (expression has type "A", variable has type "B") |
| |
| a = A() |
| b = B() |
| |
| class A: pass |
| class B: pass |
| [out] |
| |
| [case testInferringLvarTypesInNestedTupleAssignment2] |
| import typing |
| def f() -> None: |
| a, (b, c) = A(), (B(), C()) |
| a = b # E: Incompatible types in assignment (expression has type "B", variable has type "A") |
| a = B() # E: Incompatible types in assignment (expression has type "B", variable has type "A") |
| b = A() # E: Incompatible types in assignment (expression has type "A", variable has type "B") |
| c = A() # E: Incompatible types in assignment (expression has type "A", variable has type "C") |
| |
| a = A() |
| b = B() |
| c = C() |
| |
| class A: pass |
| class B: pass |
| class C: pass |
| [out] |
| |
| [case testInferringLvarTypesInNestedListAssignment] |
| import typing |
| def f() -> None: |
| a, (b, c) = A(), [B(), C()] |
| a = b # E: Incompatible types in assignment (expression has type "B", variable has type "A") |
| a = B() # E: Incompatible types in assignment (expression has type "B", variable has type "A") |
| b = A() # E: Incompatible types in assignment (expression has type "A", variable has type "B") |
| c = A() # E: Incompatible types in assignment (expression has type "A", variable has type "C") |
| |
| a = A() |
| b = B() |
| c = C() |
| |
| class A: pass |
| class B: pass |
| class C: pass |
| [out] |
| |
| [case testInferringLvarTypesInMultiDefWithNoneTypes] |
| import typing |
| def f() -> None: |
| a, b = A(), None # E: Need type annotation for variable |
| c, d = None, A() # E: Need type annotation for variable |
| |
| class A: pass |
| [out] |
| |
| [case testInferringLvarTypesInNestedTupleAssignmentWithNoneTypes] |
| import typing |
| def f() -> None: |
| a1, (a2, b) = A(), (A(), None) # E: Need type annotation for variable |
| |
| class A: pass |
| [out] |
| |
| [case testInferringLvarTypesInMultiDefWithInvalidTuple] |
| from typing import Tuple |
| t = None # type: Tuple[object, object, object] |
| |
| def f() -> None: |
| a, b = t # Fail |
| c, d, e, f = t # Fail |
| g, h, i = t |
| [builtins fixtures/tuple.pyi] |
| [out] |
| main:5: error: Too many values to unpack (2 expected, 3 provided) |
| main:6: error: Need more than 3 values to unpack (4 expected) |
| |
| [case testInvalidRvalueTypeInInferredMultipleLvarDefinition] |
| import typing |
| def f() -> None: |
| a, b = f # E: 'def ()' object is not iterable |
| c, d = A() # E: '__main__.A' object is not iterable |
| class A: pass |
| [builtins fixtures/for.pyi] |
| [out] |
| |
| [case testInvalidRvalueTypeInInferredNestedTupleAssignment] |
| import typing |
| def f() -> None: |
| a1, (a2, b) = A(), f # E: 'def ()' object is not iterable |
| a3, (c, d) = A(), A() # E: '__main__.A' object is not iterable |
| class A: pass |
| [builtins fixtures/for.pyi] |
| [out] |
| |
| [case testInferringMultipleLvarDefinitionWithListRvalue] |
| from typing import List |
| |
| class C: pass |
| class D: pass |
| |
| def f() -> None: |
| list_c = [C()] |
| list_d = [D()] |
| a, b = list_c |
| c, d, e = list_d |
| a = D() # E: Incompatible types in assignment (expression has type "D", variable has type "C") |
| b = D() # E: Incompatible types in assignment (expression has type "D", variable has type "C") |
| c = C() # E: Incompatible types in assignment (expression has type "C", variable has type "D") |
| b = c # E: Incompatible types in assignment (expression has type "D", variable has type "C") |
| |
| a = C() |
| b = C() |
| c = D() |
| d = D() |
| e = D() |
| |
| a = b |
| c = d |
| d = e |
| [builtins fixtures/for.pyi] |
| [out] |
| |
| [case testInferringNestedTupleAssignmentWithListRvalue] |
| from typing import List |
| |
| class C: pass |
| class D: pass |
| |
| def f() -> None: |
| list_c = [C()] |
| list_d = [D()] |
| c1, (a, b) = C(), list_c |
| c2, (c, d, e) = C(), list_d |
| a = D() # E: Incompatible types in assignment (expression has type "D", variable has type "C") |
| b = D() # E: Incompatible types in assignment (expression has type "D", variable has type "C") |
| c = C() # E: Incompatible types in assignment (expression has type "C", variable has type "D") |
| b = c # E: Incompatible types in assignment (expression has type "D", variable has type "C") |
| |
| a = C() |
| b = C() |
| c = D() |
| d = D() |
| e = D() |
| |
| a = b |
| c = d |
| d = e |
| [builtins fixtures/for.pyi] |
| [out] |
| |
| [case testInferringMultipleLvarDefinitionWithImplicitDynamicRvalue] |
| import typing |
| def f() -> None: |
| a, b = g() |
| a.x |
| b.x |
| def g(): pass |
| |
| [case testInferringMultipleLvarDefinitionWithExplicitDynamicRvalue] |
| from typing import Any |
| def f(d: Any) -> None: |
| a, b = d |
| a.x |
| b.x |
| |
| [case testInferringTypesFromIterable] |
| from typing import Iterable |
| class Nums(Iterable[int]): |
| def __iter__(self): pass |
| def __next__(self): pass |
| a, b = Nums() |
| a = b = 1 |
| a = '' # E: Incompatible types in assignment (expression has type "str", variable has type "int") |
| b = '' # E: Incompatible types in assignment (expression has type "str", variable has type "int") |
| [builtins fixtures/for.pyi] |
| |
| |
| -- Type variable inference for generic functions |
| -- --------------------------------------------- |
| |
| |
| [case testInferSimpleGenericFunction] |
| from typing import Tuple, TypeVar |
| T = TypeVar('T') |
| a = None # type: A |
| b = None # type: B |
| c = None # type: Tuple[A, object] |
| |
| b = id(a) # E: Incompatible types in assignment (expression has type "A", variable has type "B") |
| a = id(b) # E: Incompatible types in assignment (expression has type "B", variable has type "A") |
| a = id(c) # E: Incompatible types in assignment (expression has type "Tuple[A, object]", variable has type "A") |
| |
| a = id(a) |
| b = id(b) |
| c = id(c) |
| |
| def id(a: T) -> T: pass |
| |
| class A: pass |
| class B: pass |
| [builtins fixtures/tuple.pyi] |
| |
| [case testInferringGenericFunctionTypeForLvar] |
| from typing import TypeVar |
| T = TypeVar('T') |
| def f() -> None: |
| a = id |
| b = None # type: int |
| c = None # type: str |
| b = a(c) # E: Incompatible types in assignment (expression has type "str", variable has type "int") |
| b = a(b) |
| c = a(c) |
| def id(x: T) -> T: |
| return x |
| [out] |
| |
| [case testUnderspecifiedInferenceResult] |
| from typing import TypeVar |
| T = TypeVar('T') |
| class A: pass |
| a = None # type: A |
| |
| def ff() -> None: |
| x = f() # E: Need type annotation for variable |
| |
| g(None) # Ok |
| f() # Ok because not used to infer local variable type |
| g(a) |
| |
| def f() -> T: pass |
| def g(a: T) -> None: pass |
| [out] |
| |
| [case testUnsolvableInferenceResult] |
| from typing import TypeVar |
| T = TypeVar('T') |
| f(A(), g()) # Fail |
| f(A(), A()) |
| |
| def f(a: T, b: T) -> None: pass |
| def g() -> None: pass |
| class A: pass |
| [out] |
| main:3: error: Cannot infer type argument 1 of "f" |
| main:3: error: "g" does not return a value |
| |
| [case testInferenceWithMultipleConstraints] |
| from typing import TypeVar |
| T = TypeVar('T') |
| a = None # type: A |
| b = None # type: B |
| |
| b = f(a, b) # E: Incompatible types in assignment (expression has type "A", variable has type "B") |
| b = f(b, a) # E: Incompatible types in assignment (expression has type "A", variable has type "B") |
| a = f(a, b) |
| a = f(b, a) |
| |
| def f(a: T, b: T) -> T: pass |
| |
| class A: pass |
| class B(A): pass |
| |
| [case testInferenceWithMultipleVariables] |
| from typing import Tuple, TypeVar |
| T = TypeVar('T') |
| S = TypeVar('S') |
| a, b = None, None # type: (A, B) |
| taa = None # type: Tuple[A, A] |
| tab = None # type: Tuple[A, B] |
| tba = None # type: Tuple[B, A] |
| |
| taa = f(a, b) # Fail |
| taa = f(b, a) # Fail |
| tba = f(a, b) # Fail |
| |
| tab = f(a, b) |
| tba = f(b, a) |
| |
| def f(a: T, b: S) -> Tuple[T, S]: pass |
| |
| class A: pass |
| class B: pass |
| [builtins fixtures/tuple.pyi] |
| [out] |
| main:9: error: Argument 2 to "f" has incompatible type "B"; expected "A" |
| main:10: error: Argument 1 to "f" has incompatible type "B"; expected "A" |
| main:11: error: Argument 1 to "f" has incompatible type "A"; expected "B" |
| main:11: error: Argument 2 to "f" has incompatible type "B"; expected "A" |
| |
| [case testConstraintSolvingWithSimpleGenerics] |
| from typing import TypeVar, Generic |
| T = TypeVar('T') |
| ao = None # type: A[object] |
| ab = None # type: A[B] |
| ac = None # type: A[C] |
| |
| ab = f(ao) # E: Argument 1 to "f" has incompatible type A[object]; expected A[B] |
| ao = f(ab) # E: Argument 1 to "f" has incompatible type A[B]; expected A[object] |
| ab = f(ac) # E: Argument 1 to "f" has incompatible type A[C]; expected A[B] |
| ab = g(ao) # E: Argument 1 to "g" has incompatible type A[object]; expected A[B] |
| ao = g(ab) # E: Argument 1 to "g" has incompatible type A[B]; expected A[object] |
| |
| ab = f(ab) |
| ac = f(ac) |
| ao = f(ao) |
| |
| ab = g(ab) |
| ao = g(ao) |
| |
| def f(a: 'A[T]') -> 'A[T]': pass |
| |
| def g(a: T) -> T: pass |
| |
| class A(Generic[T]): pass |
| class B: pass |
| class C: pass |
| |
| [case testConstraintSolvingFailureWithSimpleGenerics] |
| from typing import TypeVar, Generic |
| T = TypeVar('T') |
| ao = None # type: A[object] |
| ab = None # type: A[B] |
| |
| f(ao, ab) # E: Cannot infer type argument 1 of "f" |
| f(ab, ao) # E: Cannot infer type argument 1 of "f" |
| f(ao, ao) |
| f(ab, ab) |
| |
| def f(a: 'A[T]', b: 'A[T]') -> None: pass |
| |
| class A(Generic[T]): pass |
| class B: pass |
| |
| [case testTypeInferenceWithCalleeDefaultArgs] |
| from typing import TypeVar |
| T = TypeVar('T') |
| a = None # type: A |
| o = None # type: object |
| |
| a = f(o) # E: Incompatible types in assignment (expression has type "object", variable has type "A") |
| a = g(a, o) # E: Incompatible types in assignment (expression has type "object", variable has type "A") |
| |
| o = f() |
| o = f(o) |
| a = f(a) |
| a = g(a) |
| |
| def f(a: T = None) -> T: pass |
| def g(a: T, b: T = None) -> T: pass |
| |
| class A: pass |
| |
| |
| -- Generic function inference with multiple inheritance |
| -- ---------------------------------------------------- |
| |
| |
| [case testGenericFunctionInferenceWithMultipleInheritance] |
| from typing import TypeVar |
| |
| class I: pass |
| class J: pass |
| |
| class A(I, J): pass |
| class B(I, J): pass |
| class C(I): pass |
| class D(J): pass |
| |
| T = TypeVar('T') |
| def f(a: T, b: T) -> T: pass |
| def g(x: I) -> None: pass |
| |
| a = f(A(), C()) |
| g(a) |
| b = f(A(), B()) |
| g(b) |
| c = f(A(), D()) |
| g(c) # E: Argument 1 to "g" has incompatible type "J"; expected "I" |
| d = f(D(), A()) |
| g(d) # E: Argument 1 to "g" has incompatible type "J"; expected "I" |
| e = f(D(), C()) |
| g(e) # E: Argument 1 to "g" has incompatible type "object"; expected "I" |
| |
| [case testGenericFunctionInferenceWithMultipleInheritance2] |
| from typing import TypeVar |
| |
| class I: pass |
| class J: pass |
| |
| class A(I): pass |
| class B(A, J): pass |
| class C(I, J): pass |
| |
| T = TypeVar('T') |
| def f(a: T, b: T) -> T: pass |
| def g(x: I) -> None: pass |
| def h(x: J) -> None: pass |
| |
| a = f(B(), C()) |
| g(a) |
| h(a) # E: Argument 1 to "h" has incompatible type "I"; expected "J" |
| b = f(C(), B()) |
| g(b) |
| h(b) # E: Argument 1 to "h" has incompatible type "I"; expected "J" |
| c = f(A(), B()) |
| g(a) |
| h(b) # E: Argument 1 to "h" has incompatible type "I"; expected "J" |
| |
| [case testGenericFunctionInferenceWithMultipleInheritance3] |
| from typing import TypeVar |
| |
| class I: pass |
| class J: pass |
| class K(J): pass |
| |
| class A(K): pass |
| class B(A, I): pass |
| class C(I, J): pass |
| |
| T = TypeVar('T') |
| def f(a: T, b: T) -> T: pass |
| def g(x: K) -> None: pass |
| |
| a = f(B(), C()) |
| g(a) # E: Argument 1 to "g" has incompatible type "J"; expected "K" |
| b = f(A(), C()) |
| g(b) # E: Argument 1 to "g" has incompatible type "J"; expected "K" |
| c = f(A(), B()) |
| g(c) |
| |
| [case testPrecedenceOfFirstBaseAsInferenceResult] |
| from typing import TypeVar |
| from abc import abstractmethod, ABCMeta |
| T = TypeVar('T') |
| a, i, j = None, None, None # type: (A, I, J) |
| |
| a = f(B(), C()) |
| |
| class I(metaclass=ABCMeta): pass |
| class J(metaclass=ABCMeta): pass |
| |
| def f(a: T, b: T) -> T: pass |
| |
| class A: pass |
| class B(A, I, J): pass |
| class C(A, I, J): pass |
| |
| |
| -- Generic function inference with function arguments |
| -- -------------------------------------------------- |
| |
| |
| [case testNonOverloadedMapInference] |
| from typing import TypeVar, Callable, List |
| t = TypeVar('t') |
| s = TypeVar('s') |
| class A: pass |
| b = bool() |
| def f(x: bool) -> A: pass |
| def mymap(f: Callable[[t], s], a: List[t]) -> List[s]: pass |
| |
| l = mymap(f, [b]) |
| l = [A()] |
| lb = [b] |
| l = lb # E: Incompatible types in assignment (expression has type List[bool], variable has type List[A]) |
| [builtins fixtures/for.pyi] |
| |
| |
| -- Generic function inference with unions |
| -- -------------------------------------- |
| |
| |
| [case testUnionInference] |
| from typing import TypeVar, Union, List |
| T = TypeVar('T') |
| U = TypeVar('U') |
| def f(x: Union[T, int], y: T) -> T: pass |
| f(1, 'a')() # E: "str" not callable |
| f('a', 1)() # E: "object" not callable |
| f('a', 'a')() # E: "str" not callable |
| f(1, 1)() # E: "int" not callable |
| |
| def g(x: Union[T, List[T]]) -> List[T]: pass |
| def h(x: List[str]) -> None: pass |
| g('a')() # E: List[str] not callable |
| |
| # The next line is a case where there are multiple ways to satisfy a constraint |
| # involving a Union. Either T = List[str] or T = str would turn out to be valid, |
| # but mypy doesn't know how to branch on these two options (and potentially have |
| # to backtrack later) and defaults to T = None. The result is an awkward error |
| # message. Either a better error message, or simply accepting the call, would be |
| # preferable here. |
| g(['a']) # E: Argument 1 to "g" has incompatible type List[str]; expected List[None] |
| |
| h(g(['a'])) |
| |
| def i(x: Union[List[T], List[U]], y: List[T], z: List[U]) -> None: pass |
| a = [1] |
| b = ['b'] |
| i(a, a, b) |
| i(b, a, b) |
| i(a, b, b) # E: Argument 1 to "i" has incompatible type List[int]; expected List[str] |
| [builtins fixtures/list.pyi] |
| |
| |
| [case testUnionInferenceWithTypeVarValues] |
| from typing import TypeVar, Union |
| AnyStr = TypeVar('AnyStr', bytes, str) |
| def f(x: Union[AnyStr, int], *a: AnyStr) -> None: pass |
| f('foo') |
| f('foo', 'bar') |
| f('foo', b'bar') # E: Type argument 1 of "f" has incompatible value "object" |
| f(1) |
| f(1, 'foo') |
| f(1, 'foo', b'bar') # E: Type argument 1 of "f" has incompatible value "object" |
| [builtins fixtures/primitives.pyi] |
| |
| |
| [case testUnionTwoPassInference-skip] |
| from typing import TypeVar, Union, List |
| T = TypeVar('T') |
| U = TypeVar('U') |
| def j(x: Union[List[T], List[U]], y: List[T]) -> List[U]: pass |
| |
| a = [1] |
| b = ['b'] |
| # We could infer: Since List[str] <: List[T], we must have T = str. |
| # Then since List[int] <: Union[List[str], List[U]], and List[int] is |
| # not a subtype of List[str], we must have U = int. |
| # This is not currently implemented. |
| j(a, b) |
| [builtins fixtures/list.pyi] |
| |
| |
| [case testUnionContext] |
| from typing import TypeVar, Union, List |
| T = TypeVar('T') |
| def f() -> List[T]: pass |
| d1 = f() # type: Union[List[int], str] |
| d2 = f() # type: Union[int, str] # E: Incompatible types in assignment (expression has type List[None], variable has type "Union[int, str]") |
| def g(x: T) -> List[T]: pass |
| d3 = g(1) # type: Union[List[int], List[str]] |
| [builtins fixtures/list.pyi] |
| |
| |
| [case testGenericFunctionSubtypingWithUnions] |
| from typing import TypeVar, Union, List |
| T = TypeVar('T') |
| S = TypeVar('S') |
| def k1(x: int, y: List[T]) -> List[Union[T, int]]: pass |
| def k2(x: S, y: List[T]) -> List[Union[T, int]]: pass |
| a = k2 |
| a = k2 |
| a = k1 # E: Incompatible types in assignment (expression has type Callable[[int, List[T]], List[Union[T, int]]], variable has type Callable[[S, List[T]], List[Union[T, int]]]) |
| b = k1 |
| b = k1 |
| b = k2 |
| [builtins fixtures/list.pyi] |
| |
| |
| -- Literal expressions |
| -- ------------------- |
| |
| |
| [case testDictLiteral] |
| from typing import Dict |
| class A: pass |
| class B: pass |
| def d_ab() -> Dict[A, B]: return {} |
| def d_aa() -> Dict[A, A]: return {} |
| a, b = None, None # type: (A, B) |
| d = {a:b} |
| d = d_ab() |
| d = d_aa() # E: Incompatible types in assignment (expression has type Dict[A, A], variable has type Dict[A, B]) |
| [builtins fixtures/dict.pyi] |
| |
| [case testSetLiteral] |
| from typing import Any, Set |
| a, x = None, None # type: (int, Any) |
| def s_i() -> Set[int]: return set() |
| def s_s() -> Set[str]: return set() |
| s = {a} |
| s = {x} |
| s = s_i() |
| s = s_s() # E: Incompatible types in assignment (expression has type Set[str], variable has type Set[int]) |
| [builtins fixtures/set.pyi] |
| |
| [case testSetWithStarExpr] |
| # flags: --fast-parser |
| s = {1, 2, *(3, 4)} |
| t = {1, 2, *s} |
| reveal_type(s) # E: Revealed type is 'builtins.set[builtins.int*]' |
| reveal_type(t) # E: Revealed type is 'builtins.set[builtins.int*]' |
| [builtins fixtures/set.pyi] |
| |
| |
| -- For statements |
| -- -------------- |
| |
| |
| [case testInferenceOfFor1] |
| a, b = None, None # type: (A, B) |
| |
| for x in [A()]: |
| b = x # E: Incompatible types in assignment (expression has type "A", variable has type "B") |
| a = x |
| |
| for y in []: # E: Need type annotation for variable |
| a = y |
| |
| class A: pass |
| class B: pass |
| [builtins fixtures/for.pyi] |
| |
| [case testInferenceOfFor2] |
| |
| a, b, c = None, None, None # type: (A, B, C) |
| for x, (y, z) in [(A(), (B(), C()))]: |
| b = x # Fail |
| c = y # Fail |
| a = z # Fail |
| a = x |
| b = y |
| c = z |
| for xx, yy, zz in [(A(), B())]: # Fail |
| pass |
| for xx, (yy, zz) in [(A(), B())]: # Fail |
| pass |
| for xxx, yyy in [(None, None)]: # Fail |
| pass |
| |
| class A: pass |
| class B: pass |
| class C: pass |
| [builtins fixtures/for.pyi] |
| [out] |
| main:4: error: Incompatible types in assignment (expression has type "A", variable has type "B") |
| main:5: error: Incompatible types in assignment (expression has type "B", variable has type "C") |
| main:6: error: Incompatible types in assignment (expression has type "C", variable has type "A") |
| main:10: error: Need more than 2 values to unpack (3 expected) |
| main:12: error: '__main__.B' object is not iterable |
| main:14: error: Need type annotation for variable |
| |
| [case testInferenceOfFor3] |
| |
| a, b = None, None # type: (A, B) |
| |
| for x, y in [[A()]]: |
| b = x # E: Incompatible types in assignment (expression has type "A", variable has type "B") |
| b = y # E: Incompatible types in assignment (expression has type "A", variable has type "B") |
| a = x |
| a = y |
| |
| for e, f in [[]]: # E: Need type annotation for variable |
| pass |
| |
| class A: pass |
| class B: pass |
| [builtins fixtures/for.pyi] |
| |
| [case testForStatementInferenceWithVoid] |
| import typing |
| for x in f(): # E: "f" does not return a value |
| pass |
| def f() -> None: pass |
| [builtins fixtures/for.pyi] |
| |
| [case testReusingInferredForIndex] |
| import typing |
| for a in [A()]: pass |
| a = A() |
| a = B() # E: Incompatible types in assignment (expression has type "B", variable has type "A") |
| for a in []: pass |
| a = A() |
| a = B() # E: Incompatible types in assignment (expression has type "B", variable has type "A") |
| class A: pass |
| class B: pass |
| [builtins fixtures/for.pyi] |
| |
| [case testReusingInferredForIndex2] |
| import typing |
| def f() -> None: |
| for a in [A()]: pass |
| a = A() |
| a = B() # E: Incompatible types in assignment (expression has type "B", variable has type "A") |
| for a in []: pass |
| a = A() |
| a = B() # E: Incompatible types in assignment (expression has type "B", variable has type "A") |
| class A: pass |
| class B: pass |
| [builtins fixtures/for.pyi] |
| [out] |
| |
| |
| -- Regression tests |
| -- ---------------- |
| |
| |
| [case testMultipleAssignmentWithPartialDefinition] |
| |
| a = None # type: A |
| x, a = a, a |
| x = a |
| a = x |
| x = object() # E: Incompatible types in assignment (expression has type "object", variable has type "A") |
| a = object() # E: Incompatible types in assignment (expression has type "object", variable has type "A") |
| class A: pass |
| |
| [case testMultipleAssignmentWithPartialDefinition2] |
| |
| a = None # type: A |
| a, x = [a, a] |
| x = a |
| a = x |
| x = object() # E: Incompatible types in assignment (expression has type "object", variable has type "A") |
| a = object() # E: Incompatible types in assignment (expression has type "object", variable has type "A") |
| class A: pass |
| [builtins fixtures/for.pyi] |
| |
| [case testMultipleAssignmentWithPartialDefinition3] |
| from typing import Any |
| a = None # type: A |
| x, a = Any(a) |
| x = a |
| a = x |
| x = object() |
| a = object() # E: Incompatible types in assignment (expression has type "object", variable has type "A") |
| class A: pass |
| |
| [case testInferGlobalDefinedInBlock] |
| import typing |
| if A: |
| a = A() |
| a = A() |
| a = B() # E: Incompatible types in assignment (expression has type "B", variable has type "A") |
| class A: pass |
| class B: pass |
| |
| |
| -- Inferring attribute types |
| -- ------------------------- |
| |
| |
| [case testInferAttributeType] |
| import typing |
| class A: |
| a = B() |
| class B: pass |
| |
| A().a = B() |
| A().a = A() # E: Incompatible types in assignment (expression has type "A", variable has type "B") |
| |
| [case testInferAttributeTypeAndAssignInInit] |
| import typing |
| class A: |
| a = B() |
| def __init__(self) -> None: |
| self.a = A() # E: Incompatible types in assignment (expression has type "A", variable has type "B") |
| self.a = B() |
| class B: pass |
| [out] |
| |
| [case testInferAttributeInInit] |
| import typing |
| class B: pass |
| class A: |
| def __init__(self) -> None: |
| self.a = A() |
| self.b = B() |
| a = A() |
| a.a = A() |
| a.b = B() |
| a.a = B() # E: Incompatible types in assignment (expression has type "B", variable has type "A") |
| a.b = A() # E: Incompatible types in assignment (expression has type "A", variable has type "B") |
| |
| [case testInferAttributeInInitUsingChainedAssignment] |
| import typing |
| class B: pass |
| class A: |
| def __init__(self) -> None: |
| self.a = self.b = A() |
| a = A() |
| a.a = A() |
| a.b = A() |
| a.a = B() # E: Incompatible types in assignment (expression has type "B", variable has type "A") |
| a.b = B() # E: Incompatible types in assignment (expression has type "B", variable has type "A") |
| |
| |
| -- Lambdas |
| -- ------- |
| |
| |
| [case testInferLambdaType] |
| from typing import List, Callable |
| li = [1] |
| l = lambda: li |
| f1 = l # type: Callable[[], List[int]] |
| f2 = l # type: Callable[[], List[str]] # E: Incompatible types in assignment (expression has type Callable[[], List[int]], variable has type Callable[[], List[str]]) |
| [builtins fixtures/list.pyi] |
| |
| [case testInferLambdaType2] |
| from typing import List, Callable |
| l = lambda: [B()] |
| f1 = l # type: Callable[[], List[B]] |
| f2 = l # type: Callable[[], List[A]] # E: Incompatible types in assignment (expression has type Callable[[], List[B]], variable has type Callable[[], List[A]]) |
| |
| class A: pass |
| class B: pass |
| [builtins fixtures/list.pyi] |
| |
| [case testUninferableLambda] |
| from typing import TypeVar, Callable |
| X = TypeVar('X') |
| def f(x: Callable[[X], X]) -> X: pass |
| y = f(lambda x: x) # E: Cannot infer type argument 1 of "f" |
| |
| [case testUninferableLambdaWithTypeError] |
| from typing import TypeVar, Callable |
| X = TypeVar('X') |
| def f(x: Callable[[X], X], y: str) -> X: pass |
| y = f(lambda x: x, 1) # Fail |
| [out] |
| main:4: error: Cannot infer type argument 1 of "f" |
| main:4: error: Argument 2 to "f" has incompatible type "int"; expected "str" |
| |
| [case testInferLambdaNone] |
| from typing import Callable |
| def f(x: Callable[[], None]) -> None: pass |
| def g(x: Callable[[], int]) -> None: pass |
| a = lambda: None |
| f(a) |
| g(a) # E: Argument 1 to "g" has incompatible type Callable[[], None]; expected Callable[[], int] |
| b = lambda: None # type: Callable[[], None] |
| f(b) |
| g(b) # E: Argument 1 to "g" has incompatible type Callable[[], None]; expected Callable[[], int] |
| |
| |
| -- Boolean operators |
| -- ----------------- |
| |
| |
| [case testOrOperationWithGenericOperands] |
| from typing import List |
| a = None # type: List[A] |
| o = None # type: List[object] |
| a2 = a or [] |
| a = a2 |
| a2 = o # E: Incompatible types in assignment (expression has type List[object], variable has type List[A]) |
| class A: pass |
| [builtins fixtures/list.pyi] |
| |
| |
| -- Accessing variable before its type has been inferred |
| -- ---------------------------------------------------- |
| |
| |
| [case testAccessGlobalVarBeforeItsTypeIsAvailable] |
| import typing |
| x.y # E: Cannot determine type of 'x' |
| x = object() |
| x.y # E: "object" has no attribute "y" |
| |
| [case testAccessDataAttributeBeforeItsTypeIsAvailable] |
| |
| a = None # type: A |
| a.x.y # E: Cannot determine type of 'x' |
| class A: |
| def __init__(self) -> None: |
| self.x = object() |
| a.x.y # E: "object" has no attribute "y" |
| |
| |
| -- Ducktype declarations |
| -- --------------------- |
| |
| |
| [case testListWithDucktypeCompatibility] |
| from typing import List, _promote |
| class A: pass |
| @_promote(A) |
| class B: pass |
| a = None # type: List[A] |
| x1 = [A(), B()] |
| x2 = [B(), A()] |
| x3 = [B(), B()] |
| a = x1 |
| a = x2 |
| a = x3 # E: Incompatible types in assignment (expression has type List[B], variable has type List[A]) |
| [builtins fixtures/list.pyi] |
| |
| [case testListWithDucktypeCompatibilityAndTransitivity] |
| from typing import List, _promote |
| class A: pass |
| @_promote(A) |
| class B: pass |
| @_promote(B) |
| class C: pass |
| a = None # type: List[A] |
| x1 = [A(), C()] |
| x2 = [C(), A()] |
| x3 = [B(), C()] |
| a = x1 |
| a = x2 |
| a = x3 # E: Incompatible types in assignment (expression has type List[B], variable has type List[A]) |
| [builtins fixtures/list.pyi] |
| |
| |
| -- Inferring type of variable when initialized to an empty collection |
| -- ------------------------------------------------------------------ |
| |
| |
| [case testInferListInitializedToEmpty] |
| a = [] |
| a.append(1) |
| a.append('') # E: Argument 1 to "append" of "list" has incompatible type "str"; expected "int" |
| [builtins fixtures/list.pyi] |
| [out] |
| |
| [case testInferListInitializedToEmptyUsingUpdate] |
| a = [] |
| a.extend(['']) |
| a.append(0) # E: Argument 1 to "append" of "list" has incompatible type "int"; expected "str" |
| [builtins fixtures/list.pyi] |
| [out] |
| |
| [case testInferListInitializedToEmptyAndNotAnnotated] |
| a = [] # E: Need type annotation for variable |
| [builtins fixtures/list.pyi] |
| [out] |
| |
| [case testInferListInitializedToEmptyAndReadBeforeAppend] |
| a = [] # E: Need type annotation for variable |
| if a: pass |
| a.xyz |
| a.append('') |
| [builtins fixtures/list.pyi] |
| [out] |
| |
| [case testInferListInitializedToEmptyAndIncompleteTypeInAppend] |
| a = [] # E: Need type annotation for variable |
| a.append([]) |
| a() |
| [builtins fixtures/list.pyi] |
| [out] |
| |
| [case testInferListInitializedToEmptyAndMultipleAssignment] |
| a, b = [], [] |
| a.append(1) |
| b.append('') |
| a() # E: List[int] not callable |
| b() # E: List[str] not callable |
| [builtins fixtures/list.pyi] |
| [out] |
| |
| [case testInferListInitializedToEmptyInFunction] |
| def f() -> None: |
| a = [] |
| a.append(1) |
| a.append('') # E: Argument 1 to "append" of "list" has incompatible type "str"; expected "int" |
| [builtins fixtures/list.pyi] |
| [out] |
| |
| [case testInferListInitializedToEmptyAndNotAnnotatedInFunction] |
| def f() -> None: |
| a = [] # E: Need type annotation for variable |
| |
| def g() -> None: pass |
| |
| a = [] |
| a.append(1) |
| [builtins fixtures/list.pyi] |
| [out] |
| |
| [case testInferListInitializedToEmptyAndReadBeforeAppendInFunction] |
| def f() -> None: |
| a = [] # E: Need type annotation for variable |
| if a: pass |
| a.xyz |
| a.append('') |
| [builtins fixtures/list.pyi] |
| [out] |
| |
| [case testInferListInitializedToEmptyInClassBody] |
| class A: |
| a = [] |
| a.append(1) |
| a.append('') # E: Argument 1 to "append" of "list" has incompatible type "str"; expected "int" |
| [builtins fixtures/list.pyi] |
| [out] |
| |
| [case testInferListInitializedToEmptyAndNotAnnotatedInClassBody] |
| class A: |
| a = [] # E: Need type annotation for variable |
| |
| class B: |
| a = [] |
| a.append(1) |
| [builtins fixtures/list.pyi] |
| [out] |
| |
| [case testInferListInitializedToEmptyInMethod] |
| class A: |
| def f(self) -> None: |
| a = [] |
| a.append(1) |
| a.append('') # E: Argument 1 to "append" of "list" has incompatible type "str"; expected "int" |
| [builtins fixtures/list.pyi] |
| [out] |
| |
| [case testInferListInitializedToEmptyAndNotAnnotatedInMethod] |
| class A: |
| def f(self) -> None: |
| a = [] # E: Need type annotation for variable |
| [builtins fixtures/list.pyi] |
| [out] |
| |
| [case testInferListInitializedToEmptyInMethodViaAttribute] |
| class A: |
| def f(self) -> None: |
| # Attributes aren't supported right now. |
| self.a = [] # E: Need type annotation for variable |
| self.a.append(1) # E: Cannot determine type of 'a' |
| self.a.append('') # E: Cannot determine type of 'a' |
| [builtins fixtures/list.pyi] |
| [out] |
| |
| [case testInferSetInitializedToEmpty] |
| a = set() |
| a.add(1) |
| a.add('') # E: Argument 1 to "add" of "set" has incompatible type "str"; expected "int" |
| [builtins fixtures/set.pyi] |
| [out] |
| |
| [case testInferSetInitializedToEmptyUsingDiscard] |
| a = set() |
| a.discard('') |
| a.add(0) # E: Argument 1 to "add" of "set" has incompatible type "int"; expected "str" |
| [builtins fixtures/set.pyi] |
| [out] |
| |
| [case testInferSetInitializedToEmptyUsingUpdate] |
| a = set() |
| a.update({0}) |
| a.add('') # E: Argument 1 to "add" of "set" has incompatible type "str"; expected "int" |
| [builtins fixtures/set.pyi] |
| [out] |
| |
| [case testInferDictInitializedToEmpty] |
| a = {} |
| a[1] = '' |
| a() # E: Dict[int, str] not callable |
| [builtins fixtures/dict.pyi] |
| [out] |
| |
| [case testInferDictInitializedToEmptyUsingUpdate] |
| a = {} |
| a.update({'': 42}) |
| a() # E: Dict[str, int] not callable |
| [builtins fixtures/dict.pyi] |
| [out] |
| |
| [case testInferDictInitializedToEmptyUsingUpdateError] |
| a = {} # E: Need type annotation for variable |
| a.update([1, 2]) |
| a() |
| [builtins fixtures/dict.pyi] |
| [out] |
| |
| [case testInferDictInitializedToEmptyAndIncompleteTypeInUpdate] |
| a = {} # E: Need type annotation for variable |
| a[1] = {} |
| b = {} # E: Need type annotation for variable |
| b[{}] = 1 |
| [builtins fixtures/dict.pyi] |
| [out] |
| |
| [case testInferDictInitializedToEmptyAndUpdatedFromMethod] |
| map = {} |
| def add(): |
| map[1] = 2 |
| [builtins fixtures/dict.pyi] |
| [out] |
| |
| [case testSpecialCaseEmptyListInitialization] |
| def f(blocks: Any): # E: Name 'Any' is not defined |
| to_process = [] # E: Need type annotation for variable |
| to_process = list(blocks) |
| [builtins fixtures/list.pyi] |
| [out] |
| |
| [case testSpecialCaseEmptyListInitialization2] |
| def f(blocks: object): |
| to_process = [] # E: Need type annotation for variable |
| to_process = list(blocks) # E: No overload variant of "list" matches argument types [builtins.object] |
| [builtins fixtures/list.pyi] |
| [out] |
| |
| |
| -- Inferring types of variables first initialized to None (partial types) |
| -- ---------------------------------------------------------------------- |
| |
| |
| [case testLocalVariablePartiallyInitializedToNone] |
| def f() -> None: |
| if object(): |
| x = None |
| else: |
| x = 1 |
| x() # E: "int" not callable |
| [out] |
| |
| [case testLocalVariablePartiallyTwiceInitializedToNone] |
| def f() -> None: |
| if object(): |
| x = None |
| elif object(): |
| x = None |
| else: |
| x = 1 |
| x() # E: "int" not callable |
| [out] |
| |
| [case testLvarInitializedToNoneWithoutType] |
| import typing |
| def f() -> None: |
| a = None # E: Need type annotation for variable |
| a.x() # E: None has no attribute "x" |
| [out] |
| |
| [case testGvarPartiallyInitializedToNone] |
| x = None |
| if object(): |
| x = 1 |
| x() # E: "int" not callable |
| |
| [case testPartiallyInitializedToNoneAndThenToPartialList] |
| x = None |
| if object(): |
| # Promote from partial None to partial list. |
| x = [] |
| x.append(1) |
| x.append('') # E: Argument 1 to "append" of "list" has incompatible type "str"; expected "int" |
| [builtins fixtures/list.pyi] |
| |
| [case testPartiallyInitializedToNoneAndThenReadPartialList] |
| x = None |
| if object(): |
| # Promote from partial None to partial list. |
| x = [] # E: Need type annotation for variable |
| x |
| [builtins fixtures/list.pyi] |
| |
| [case testPartiallyInitializedToNoneAndPartialListAndLeftPartial] |
| def f() -> None: |
| x = None |
| if object(): |
| # Promote from partial None to partial list. |
| x = [] # E: Need type annotation for variable |
| [builtins fixtures/list.pyi] |
| [out] |
| |
| [case testPartiallyInitializedToNoneAndThenToIncompleteType] |
| from typing import TypeVar, Dict |
| T = TypeVar('T') |
| def f(*x: T) -> Dict[int, T]: pass |
| x = None # E: Need type annotation for variable |
| if object(): |
| x = f() |
| [builtins fixtures/dict.pyi] |
| |
| [case testPartiallyInitializedVariableDoesNotEscapeScope1] |
| def f() -> None: |
| x = None # E: Need type annotation for variable |
| x = 1 |
| [out] |
| |
| [case testPartiallyInitializedVariableDoesNotEscapeScope2] |
| x = None # E: Need type annotation for variable |
| def f() -> None: |
| x = None |
| x = 1 |
| x() # E: None not callable |
| |
| [case testAttributePartiallyInitializedToNone] |
| class A: |
| def f(self) -> None: |
| self.x = None |
| self.x = 1 |
| self.x() # E: "int" not callable |
| [out] |
| |
| [case testAttributePartiallyInitializedToNoneWithMissingAnnotation] |
| class A: |
| def f(self) -> None: |
| self.x = None |
| |
| def g(self) -> None: |
| self.x = 1 |
| self.x() |
| [out] |
| main:3: error: Need type annotation for variable |
| main:7: error: "int" not callable |
| |
| [case testGlobalInitializedToNoneSetFromFunction] |
| a = None |
| def f(): |
| global a |
| a = 42 |
| [out] |
| |
| [case testGlobalInitializedToNoneSetFromMethod] |
| a = None |
| class C: |
| def m(self): |
| global a |
| a = 42 |
| [out] |
| |
| -- More partial type errors |
| -- ------------------------ |
| |
| [case testPartialTypeErrorSpecialCase1] |
| # This used to crash. |
| class A: |
| x = None |
| def f(self) -> None: |
| for a in self.x: |
| pass |
| [builtins fixtures/for.pyi] |
| [out] |
| main:3: error: Need type annotation for variable |
| main:5: error: None has no attribute "__iter__" |
| |
| [case testPartialTypeErrorSpecialCase2] |
| # This used to crash. |
| class A: |
| x = [] |
| def f(self) -> None: |
| for a in self.x: |
| pass |
| [builtins fixtures/for.pyi] |
| [out] |
| main:3: error: Need type annotation for variable |
| |
| [case testPartialTypeErrorSpecialCase3] |
| class A: |
| x = None |
| def f(self) -> None: |
| for a in A.x: |
| pass |
| [builtins fixtures/for.pyi] |
| [out] |
| main:2: error: Need type annotation for variable |
| main:4: error: None has no attribute "__iter__" |
| |
| |
| -- Multipass |
| -- --------- |
| |
| |
| [case testMultipassAndAccessVariableBeforeDefinition] |
| def f() -> None: |
| y = x |
| y() # E: "int" not callable |
| x = 1 |
| [out] |
| |
| [case testMultipassAndAccessInstanceVariableBeforeDefinition] |
| class A: |
| def f(self) -> None: |
| y = self.x |
| y() # E: "int" not callable |
| |
| def g(self) -> None: |
| self.x = 1 |
| [out] |
| |
| [case testMultipassAndTopLevelVariable] |
| y = x # E: Cannot determine type of 'x' |
| y() |
| x = 1+0 |
| [out] |
| |
| [case testMultipassAndDecoratedMethod] |
| from typing import Callable, TypeVar |
| |
| T = TypeVar('T') |
| |
| class A: |
| def f(self) -> None: |
| self.g() # E: Too few arguments for "g" of "A" |
| self.g(1) |
| @dec |
| def g(self, x: str) -> None: pass |
| |
| def dec(f: Callable[[A, str], T]) -> Callable[[A, int], T]: pass |
| [out] |
| |
| [case testMultipassAndDefineAttributeBasedOnNotReadyAttribute] |
| class A: |
| def f(self) -> None: |
| self.y = self.x |
| |
| def g(self) -> None: |
| self.x = 1 |
| |
| def h(self) -> None: |
| self.y() # E: "int" not callable |
| [out] |
| |
| [case testMultipassAndDefineAttributeBasedOnNotReadyAttribute2] |
| class A: |
| def f(self) -> None: |
| self.y = self.x |
| self.z = self.y |
| self.z() # E |
| self.y() # E |
| |
| def g(self) -> None: |
| self.x = 1 |
| |
| def h(self) -> None: |
| self.y() # E |
| [out] |
| main:5: error: "int" not callable |
| main:6: error: "int" not callable |
| main:12: error: "int" not callable |
| |
| [case testMultipassAndPartialTypes] |
| def f() -> None: |
| x = [] |
| y |
| x.append(1) |
| x.append('') # E: Argument 1 to "append" of "list" has incompatible type "str"; expected "int" |
| x.append(y) # E: Argument 1 to "append" of "list" has incompatible type "str"; expected "int" |
| y = '' |
| [builtins fixtures/list.pyi] |
| [out] |
| |
| [case testMultipassAndPartialTypes2] |
| s = '' |
| n = 0 |
| def f() -> None: |
| global s, n |
| x = [] |
| x.append(y) |
| s = x[0] |
| n = x[0] # E: Incompatible types in assignment (expression has type "str", variable has type "int") |
| x.append(1) # E: Argument 1 to "append" of "list" has incompatible type "int"; expected "str" |
| y = '' |
| [builtins fixtures/list.pyi] |
| [out] |
| |
| [case testMultipassAndPartialTypes3] |
| from typing import Dict |
| def g(d: Dict[str, int]) -> None: pass |
| def f() -> None: |
| x = {} |
| x[1] = y |
| g(x) # E: Argument 1 to "g" has incompatible type Dict[int, str]; expected Dict[str, int] |
| x[1] = 1 # E: Incompatible types in assignment (expression has type "int", target has type "str") |
| x[1] = '' |
| y = '' |
| [builtins fixtures/dict.pyi] |
| [out] |
| |
| [case testMultipassAndPartialTypes4] |
| from typing import Dict |
| def g(d: Dict[str, int]) -> None: pass |
| def f() -> None: |
| x = {} |
| y |
| x[1] = 1 |
| g(x) # E: Argument 1 to "g" has incompatible type Dict[int, int]; expected Dict[str, int] |
| y = '' |
| [builtins fixtures/dict.pyi] |
| [out] |
| |
| [case testMultipassAndCircularDependency] |
| class A: |
| def f(self) -> None: |
| self.x = self.y # E: Cannot determine type of 'y' |
| |
| def g(self) -> None: |
| self.y = self.x |
| [out] |
| |
| [case testMultipassAndPartialTypesSpecialCase1] |
| def f() -> None: |
| y = o |
| x = [] |
| x.append(y) |
| x() # E: List[int] not callable |
| o = 1 |
| [builtins fixtures/list.pyi] |
| [out] |
| |
| [case testMultipassAndPartialTypesSpecialCase2] |
| def f() -> None: |
| y = o |
| x = {} |
| x[''] = y |
| x() # E: Dict[str, int] not callable |
| o = 1 |
| [builtins fixtures/dict.pyi] |
| [out] |
| |
| [case testMultipassAndPartialTypesSpecialCase3] |
| def f() -> None: |
| x = {} # E: Need type annotation for variable |
| y = o |
| z = {} # E: Need type annotation for variable |
| o = 1 |
| [builtins fixtures/dict.pyi] |
| [out] |
| |
| [case testMultipassAndPartialTypesSpecialCase4] |
| def f() -> None: |
| y = o |
| x = None |
| x = y |
| x() # E: "int" not callable |
| o = 1 |
| [out] |
| |
| [case testMultipassAndPartialTypesSpecialCase5] |
| def f() -> None: |
| x = None |
| y = o |
| x = y |
| x() # E: "int" not callable |
| o = 1 |
| [out] |
| |
| [case testMultipassAndClassAttribute] |
| class S: |
| def foo(self) -> int: |
| return R.X |
| |
| class R: |
| X = 2 |
| |
| [case testMultipassAndMultipleFiles] |
| import m |
| def f() -> None: |
| x() |
| x = 0 |
| [file m.py] |
| def g() -> None: |
| y() |
| y = 0 |
| [out] |
| tmp/m.py:2: error: "int" not callable |
| main:3: error: "int" not callable |
| |
| |
| -- Tests for special cases of unification |
| -- -------------------------------------- |
| |
| [case testUnificationRedundantUnion] |
| from typing import Union |
| a = None # type: Union[int, str] |
| b = None # type: Union[str, tuple] |
| def f(): pass |
| def g(x: Union[int, str]): pass |
| c = a if f() else b |
| g(c) # E: Argument 1 to "g" has incompatible type "Union[int, str, tuple]"; expected "Union[int, str]" |
| |
| [case testUnificationMultipleInheritance] |
| class A: pass |
| class B: |
| def foo(self): pass |
| class C(A, B): pass |
| def f(): pass |
| a1 = B() if f() else C() |
| a1.foo() |
| a2 = C() if f() else B() |
| a2.foo() |
| |
| [case testUnificationMultipleInheritanceAmbiguous] |
| # Show that join_instances_via_supertype() breaks ties using the first base class. |
| class A1: pass |
| class B1: |
| def foo1(self): pass |
| class C1(A1, B1): pass |
| |
| class A2: pass |
| class B2: |
| def foo2(self): pass |
| class C2(A2, B2): pass |
| |
| class D1(C1, C2): pass |
| class D2(C2, C1): pass |
| |
| def f(): pass |
| |
| a1 = D1() if f() else D2() |
| a1.foo1() |
| a2 = D2() if f() else D1() |
| a2.foo2() |
| |
| [case testUnificationEmptyListLeft] |
| def f(): pass |
| a = [] if f() else [0] |
| a() # E: List[int] not callable |
| [builtins fixtures/list.pyi] |
| |
| [case testUnificationEmptyListRight] |
| def f(): pass |
| a = [0] if f() else [] |
| a() # E: List[int] not callable |
| [builtins fixtures/list.pyi] |
| |
| [case testUnificationEmptyListLeftInContext] |
| from typing import List |
| def f(): pass |
| a = [] if f() else [0] # type: List[int] |
| a() # E: List[int] not callable |
| [builtins fixtures/list.pyi] |
| |
| [case testUnificationEmptyListRightInContext] |
| # TODO Find an example that really needs the context |
| from typing import List |
| def f(): pass |
| a = [0] if f() else [] # type: List[int] |
| a() # E: List[int] not callable |
| [builtins fixtures/list.pyi] |
| |
| [case testUnificationEmptySetLeft] |
| def f(): pass |
| a = set() if f() else {0} |
| a() # E: Set[int] not callable |
| [builtins fixtures/set.pyi] |
| |
| [case testUnificationEmptyDictLeft] |
| def f(): pass |
| a = {} if f() else {0: 0} |
| a() # E: Dict[int, int] not callable |
| [builtins fixtures/dict.pyi] |
| |
| [case testUnificationEmptyDictRight] |
| def f(): pass |
| a = {0: 0} if f() else {} |
| a() # E: Dict[int, int] not callable |
| [builtins fixtures/dict.pyi] |
| |
| [case testUnificationDictWithEmptyListLeft] |
| def f(): pass |
| a = {0: []} if f() else {0: [0]} |
| a() # E: Dict[int, List[int]] not callable |
| [builtins fixtures/dict.pyi] |
| |
| [case testUnificationDictWithEmptyListRight] |
| def f(): pass |
| a = {0: [0]} if f() else {0: []} |
| a() # E: Dict[int, List[int]] not callable |
| [builtins fixtures/dict.pyi] |
| |
| [case testMisguidedSetItem] |
| from typing import Generic, Sequence, TypeVar |
| T = TypeVar('T') |
| class C(Sequence[T], Generic[T]): pass |
| C[0] = 0 |
| [out] |
| main:4: error: Type expected within [...] |
| main:4: error: Unsupported target for indexed assignment |