| -- Inferring locals/globals with simple types |
| -- ------------------------------------------ |
| |
| |
| [case testInferSimpleGvarType] |
| import typing |
| x = A() |
| y = B() |
| if int(): |
| x = B() # E: Incompatible types in assignment (expression has type "B", variable has type "A") |
| if int(): |
| x = A() |
| if int(): |
| x = y # E: Incompatible types in assignment (expression has type "B", variable has type "A") |
| if int(): |
| x = x |
| class A: pass |
| class B: pass |
| |
| [case testInferSimpleLvarType] |
| import typing |
| def f() -> None: |
| x = A() |
| y = B() |
| if int(): |
| x = B() # E: Incompatible types in assignment (expression has type "B", variable has type "A") |
| x = A() |
| x = y # E: Incompatible types in assignment (expression has type "B", variable has type "A") |
| x = x |
| class A: pass |
| class B: pass |
| [out] |
| |
| [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 |
| if int(): |
| 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 |
| if int(): |
| 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 |
| if int(): |
| 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 |
| b = None, A() |
| |
| 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 |
| if 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() |
| if int(): |
| 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 |
| if int(): |
| 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 |
| [builtins fixtures/tuple.pyi] |
| [out] |
| |
| [case testInferringLvarTypesInNestedTupleAssignment1] |
| from typing import Tuple |
| def f() -> None: |
| t = None # type: Tuple[A, B] |
| a1, (a, b) = A(), t |
| if int(): |
| 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 |
| [builtins fixtures/tuple.pyi] |
| [out] |
| |
| [case testInferringLvarTypesInNestedTupleAssignment2] |
| import typing |
| def f() -> None: |
| a, (b, c) = A(), (B(), C()) |
| if int(): |
| 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()] |
| if int(): |
| 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 |
| c, d = None, A() |
| |
| class A: pass |
| [out] |
| |
| [case testInferringLvarTypesInNestedTupleAssignmentWithNoneTypes] |
| import typing |
| def f() -> None: |
| a1, (a2, b) = A(), (A(), None) |
| |
| 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: "Callable[[], None]" object is not iterable |
| c, d = A() # E: "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: "Callable[[], None]" object is not iterable |
| a3, (c, d) = A(), A() # E: "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 |
| if int(): |
| 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 |
| if int(): |
| 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() |
| if int(): |
| a = b = 1 |
| if int(): |
| a = '' # E: Incompatible types in assignment (expression has type "str", variable has type "int") |
| if 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] |
| |
| if int(): |
| 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") |
| if int(): |
| a = id(c) # E: Incompatible types in assignment (expression has type "Tuple[A, object]", variable has type "A") |
| |
| if int(): |
| 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 |
| if int(): |
| 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] |
| # flags: --no-strict-optional |
| from typing import TypeVar |
| T = TypeVar('T') |
| class A: pass |
| a = None # type: A |
| |
| def ff() -> None: |
| x = f() # E: Need type annotation for "x" |
| reveal_type(x) # N: Revealed type is "Any" |
| |
| g(None) # Ok |
| f() # Ok because not used to infer local variable type |
| g(a) |
| |
| def f() -> T: pass # E: A function returning TypeVar should receive at least one argument containing the same Typevar |
| def g(a: T) -> None: pass |
| [out] |
| |
| [case testInferenceWithMultipleConstraints] |
| from typing import TypeVar |
| T = TypeVar('T') |
| a = None # type: A |
| b = None # type: B |
| |
| if int(): |
| b = f(a, b) # E: Incompatible types in assignment (expression has type "A", variable has type "B") |
| if int(): |
| b = f(b, a) # E: Incompatible types in assignment (expression has type "A", variable has type "B") |
| if int(): |
| a = f(a, b) |
| if int(): |
| 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] |
| |
| if int(): |
| taa = f(a, b) # E: Argument 2 to "f" has incompatible type "B"; expected "A" |
| if int(): |
| taa = f(b, a) # E: Argument 1 to "f" has incompatible type "B"; expected "A" |
| if int(): |
| tba = f(a, b) # E: Argument 1 to "f" has incompatible type "A"; expected "B" \ |
| # E: Argument 2 to "f" has incompatible type "B"; expected "A" |
| |
| if int(): |
| tab = f(a, b) |
| if int(): |
| tba = f(b, a) |
| |
| def f(a: T, b: S) -> Tuple[T, S]: pass |
| |
| class A: pass |
| class B: pass |
| [builtins fixtures/tuple.pyi] |
| |
| [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] |
| |
| if int(): |
| 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]" |
| if int(): |
| ab = f(ac) # E: Argument 1 to "f" has incompatible type "A[C]"; expected "A[B]" |
| if int(): |
| 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]" |
| |
| if int(): |
| ab = f(ab) |
| ac = f(ac) |
| ao = f(ao) |
| |
| if int(): |
| 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 |
| |
| if int(): |
| a = f(o) # E: Incompatible types in assignment (expression has type "object", variable has type "A") |
| if int(): |
| a = g(a, o) # E: Incompatible types in assignment (expression has type "object", variable has type "A") |
| |
| if int(): |
| o = f() |
| if int(): |
| o = f(o) |
| if int(): |
| a = f(a) |
| if int(): |
| 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 |
| [builtins fixtures/tuple.pyi] |
| |
| |
| -- 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]) |
| if int(): |
| l = [A()] |
| lb = [b] |
| if int(): |
| l = lb # E: Incompatible types in assignment (expression has type "List[bool]", variable has type "List[A]") |
| [builtins fixtures/for.pyi] |
| |
| [case testGenericFunctionWithTypeTypeAsCallable] |
| from typing import Callable, Type, TypeVar |
| T = TypeVar('T') |
| def f(x: Callable[..., T]) -> T: return x() |
| class A: pass |
| x = None # type: Type[A] |
| y = f(x) |
| reveal_type(y) # N: Revealed type is "__main__.A" |
| |
| -- 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 = <nothing>. 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[<nothing>]" |
| |
| 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 testCallableListJoinInference] |
| from typing import Any, Callable |
| |
| def fun() -> None: |
| callbacks = [ |
| callback1, |
| callback2, |
| ] |
| |
| for c in callbacks: |
| call(c, 1234) # this must not fail |
| |
| def callback1(i: int) -> int: |
| return i |
| def callback2(i: int) -> str: |
| return 'hello' |
| def call(c: Callable[[int], Any], i: int) -> None: |
| c(i) |
| [builtins fixtures/list.pyi] |
| [out] |
| |
| [case testCallableMeetAndJoin] |
| # flags: --python-version 3.6 |
| from typing import Callable, Any, TypeVar |
| |
| class A: ... |
| class B(A): ... |
| |
| def f(c: Callable[[B], int]) -> None: ... |
| |
| c: Callable[[A], int] |
| d: Callable[[B], int] |
| |
| lst = [c, d] |
| reveal_type(lst) # N: Revealed type is "builtins.list[def (__main__.B) -> builtins.int]" |
| |
| T = TypeVar('T') |
| def meet_test(x: Callable[[T], int], y: Callable[[T], int]) -> T: ... |
| |
| CA = Callable[[A], A] |
| CB = Callable[[B], B] |
| |
| ca: Callable[[CA], int] |
| cb: Callable[[CB], int] |
| reveal_type(meet_test(ca, cb)) # N: Revealed type is "def (__main__.A) -> __main__.B" |
| [builtins fixtures/list.pyi] |
| [out] |
| |
| [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: Value of type variable "AnyStr" of "f" cannot be "Sequence[object]" |
| f(1) |
| f(1, 'foo') |
| f(1, 'foo', b'bar') # E: Value of type variable "AnyStr" of "f" cannot be "Sequence[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[<nothing>]", 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 |
| if int(): |
| a = k2 |
| if int(): |
| 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 |
| if int(): |
| b = k1 |
| if int(): |
| b = k2 |
| [builtins fixtures/list.pyi] |
| |
| [case testAmbiguousUnionContextAndMultipleInheritance] |
| from typing import TypeVar, Union, Generic |
| |
| _T = TypeVar('_T') |
| |
| class T(Generic[_T]): pass |
| class U(Generic[_T]): pass |
| class V(T[_T], U[_T]): pass |
| |
| def wait_for(fut: Union[T[_T], U[_T]]) -> _T: ... |
| |
| reveal_type(wait_for(V[str]())) # N: Revealed type is "builtins.str" |
| |
| [case testAmbiguousUnionContextAndMultipleInheritance2] |
| from typing import TypeVar, Union, Generic |
| |
| _T = TypeVar('_T') |
| _S = TypeVar('_S') |
| |
| class T(Generic[_T, _S]): pass |
| class U(Generic[_T, _S]): pass |
| class V(T[_T, _S], U[_T, _S]): pass |
| |
| def wait_for(fut: Union[T[_T, _S], U[_T, _S]]) -> T[_T, _S]: ... |
| |
| reveal_type(wait_for(V[int, str]())) \ |
| # N: Revealed type is "__main__.T[builtins.int, builtins.str]" |
| |
| |
| -- 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} |
| if int(): |
| d = d_ab() |
| if int(): |
| 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} |
| if int(): |
| s = {x} |
| if int(): |
| s = s_i() |
| if int(): |
| s = s_s() # E: Incompatible types in assignment (expression has type "Set[str]", variable has type "Set[int]") |
| [builtins fixtures/set.pyi] |
| |
| [case testSetWithStarExpr] |
| s = {1, 2, *(3, 4)} |
| t = {1, 2, *s} |
| reveal_type(s) # N: Revealed type is "builtins.set[builtins.int]" |
| reveal_type(t) # N: Revealed type is "builtins.set[builtins.int]" |
| [builtins fixtures/set.pyi] |
| |
| [case testListLiteralWithFunctionsErasesNames] |
| def f1(x: int) -> int: ... |
| def g1(y: int) -> int: ... |
| def h1(x: int) -> int: ... |
| |
| list_1 = [f1, g1] |
| list_2 = [f1, h1] |
| reveal_type(list_1) # N: Revealed type is "builtins.list[def (builtins.int) -> builtins.int]" |
| reveal_type(list_2) # N: Revealed type is "builtins.list[def (x: builtins.int) -> builtins.int]" |
| |
| def f2(x: int, z: str) -> int: ... |
| def g2(y: int, z: str) -> int: ... |
| def h2(x: int, z: str) -> int: ... |
| |
| list_3 = [f2, g2] |
| list_4 = [f2, h2] |
| reveal_type(list_3) # N: Revealed type is "builtins.list[def (builtins.int, z: builtins.str) -> builtins.int]" |
| reveal_type(list_4) # N: Revealed type is "builtins.list[def (x: builtins.int, z: builtins.str) -> builtins.int]" |
| [builtins fixtures/list.pyi] |
| |
| [case testListLiteralWithSimilarFunctionsErasesName] |
| from typing import Union |
| |
| class A: ... |
| class B(A): ... |
| class C: ... |
| class D: ... |
| |
| def f(x: Union[A, C], y: B) -> A: ... |
| def g(z: Union[B, D], y: A) -> B: ... |
| def h(x: Union[B, D], y: A) -> B: ... |
| |
| list_1 = [f, g] |
| list_2 = [f, h] |
| reveal_type(list_1) # N: Revealed type is "builtins.list[def (__main__.B, y: __main__.B) -> __main__.A]" |
| reveal_type(list_2) # N: Revealed type is "builtins.list[def (x: __main__.B, y: __main__.B) -> __main__.A]" |
| [builtins fixtures/list.pyi] |
| |
| [case testListLiteralWithNameOnlyArgsDoesNotEraseNames] |
| def f(*, x: int) -> int: ... |
| def g(*, y: int) -> int: ... |
| def h(*, x: int) -> int: ... |
| |
| list_1 = [f, g] # E: List item 0 has incompatible type "Callable[[NamedArg(int, 'x')], int]"; expected "Callable[[NamedArg(int, 'y')], int]" |
| list_2 = [f, h] |
| [builtins fixtures/list.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 "y" |
| a = y |
| reveal_type(y) # N: Revealed type is "Any" |
| |
| 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)]: |
| 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: "B" object is not iterable |
| |
| [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 "e" \ |
| # E: Need type annotation for "f" |
| reveal_type(e) # N: Revealed type is "Any" |
| reveal_type(f) # N: Revealed type is "Any" |
| |
| 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() |
| if int(): |
| 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] |
| # flags: --allow-redefinition |
| |
| def f() -> None: |
| for a in [A()]: pass |
| a = A() |
| a |
| if int(): |
| a = B() \ |
| # E: Incompatible types in assignment (expression has type "B", variable has type "A") |
| for a in []: pass # E: Need type annotation for "a" |
| a = A() |
| if int(): |
| 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] |
| |
| [case testReusingInferredForIndex3] |
| # flags: --disallow-redefinition |
| def f() -> None: |
| for a in [A()]: pass |
| a = A() |
| a |
| if int(): |
| a = B() \ |
| # E: Incompatible types in assignment (expression has type "B", variable has type "A") |
| for a in []: pass |
| a = A() |
| if int(): |
| 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 |
| if int(): |
| x, a = a, a |
| if int(): |
| x = a |
| a = x |
| if int(): |
| 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 |
| if int(): |
| a, x = [a, a] |
| if int(): |
| x = a |
| a = x |
| if int(): |
| 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, cast |
| a = None # type: A |
| if int(): |
| x, a = cast(Any, a) |
| if int(): |
| x = a |
| a = x |
| if int(): |
| 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() |
| if int(): |
| a = A() |
| if int(): |
| a = B() # E: Incompatible types in assignment (expression has type "B", variable has type "A") |
| class A: pass |
| class B: pass |
| |
| [case testAssigningAnyStrToNone] |
| from typing import Tuple, TypeVar |
| AnyStr = TypeVar('AnyStr', str, bytes) |
| |
| def f(x: AnyStr) -> Tuple[AnyStr]: pass |
| x = None |
| (x,) = f('') |
| reveal_type(x) # N: Revealed type is "builtins.str" |
| [builtins fixtures/tuple.pyi] |
| |
| |
| -- 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) |
| b = lambda: None # type: Callable[[], None] |
| f(b) |
| g(b) |
| |
| [case testLambdaDefaultContext] |
| # flags: --strict-optional |
| from typing import Callable |
| def f(a: Callable[..., None] = lambda *a, **k: None): |
| pass |
| |
| def g(a: Callable[..., None] = lambda *a, **k: 1): # E: Incompatible default for argument "a" (default has type "Callable[[VarArg(Any), KwArg(Any)], int]", argument has type "Callable[..., None]") |
| pass |
| [builtins fixtures/dict.pyi] |
| |
| [case testLambdaVarargContext] |
| # Should not crash |
| from typing import Callable |
| def f(a: Callable[[int, int, int], int] = lambda *a, **k: 1): |
| pass |
| [builtins fixtures/dict.pyi] |
| |
| [case testLambdaDeferredSpecialCase] |
| from typing import Callable |
| |
| class A: |
| def f(self) -> None: |
| h(lambda: self.x) |
| |
| def g(self) -> None: |
| self.x = 1 |
| |
| def h(x: Callable[[], int]) -> None: |
| pass |
| |
| |
| -- Boolean operators |
| -- ----------------- |
| |
| |
| [case testOrOperationWithGenericOperands] |
| from typing import List |
| a = None # type: List[A] |
| o = None # type: List[object] |
| a2 = a or [] |
| if int(): |
| 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()] |
| if int(): |
| a = x1 |
| if int(): |
| a = x2 |
| if int(): |
| a = x3 \ |
| # E: Incompatible types in assignment (expression has type "List[B]", variable has type "List[A]") \ |
| # N: "List" is invariant -- see https://mypy.readthedocs.io/en/stable/common_issues.html#variance \ |
| # N: Consider using "Sequence" instead, which is covariant |
| [builtins fixtures/list.pyi] |
| [typing fixtures/typing-medium.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()] |
| if int(): |
| a = x1 |
| if int(): |
| a = x2 |
| if int(): |
| a = x3 \ |
| # E: Incompatible types in assignment (expression has type "List[B]", variable has type "List[A]") \ |
| # N: "List" is invariant -- see https://mypy.readthedocs.io/en/stable/common_issues.html#variance \ |
| # N: Consider using "Sequence" instead, which is covariant |
| [builtins fixtures/list.pyi] |
| [typing fixtures/typing-medium.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] |
| |
| [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] |
| |
| [case testInferListInitializedToEmptyAndNotAnnotated] |
| a = [] # E: Need type annotation for "a" (hint: "a: List[<type>] = ...") |
| [builtins fixtures/list.pyi] |
| |
| [case testInferListInitializedToEmptyAndReadBeforeAppend] |
| a = [] # E: Need type annotation for "a" (hint: "a: List[<type>] = ...") |
| if a: pass |
| a.xyz # E: "List[Any]" has no attribute "xyz" |
| a.append('') |
| [builtins fixtures/list.pyi] |
| |
| [case testInferListInitializedToEmptyAndIncompleteTypeInAppend] |
| a = [] # E: Need type annotation for "a" (hint: "a: List[<type>] = ...") |
| a.append([]) |
| a() # E: "List[Any]" not callable |
| [builtins fixtures/list.pyi] |
| |
| [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] |
| |
| [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] |
| |
| [case testInferListInitializedToEmptyAndNotAnnotatedInFunction] |
| def f() -> None: |
| a = [] # E: Need type annotation for "a" (hint: "a: List[<type>] = ...") |
| |
| def g() -> None: pass |
| |
| a = [] |
| a.append(1) |
| [builtins fixtures/list.pyi] |
| |
| [case testInferListInitializedToEmptyAndReadBeforeAppendInFunction] |
| def f() -> None: |
| a = [] # E: Need type annotation for "a" (hint: "a: List[<type>] = ...") |
| if a: pass |
| a.xyz # E: "List[Any]" has no attribute "xyz" |
| a.append('') |
| [builtins fixtures/list.pyi] |
| |
| [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] |
| |
| [case testInferListInitializedToEmptyAndNotAnnotatedInClassBody] |
| class A: |
| a = [] # E: Need type annotation for "a" (hint: "a: List[<type>] = ...") |
| |
| class B: |
| a = [] |
| a.append(1) |
| [builtins fixtures/list.pyi] |
| |
| [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] |
| |
| [case testInferListInitializedToEmptyAndNotAnnotatedInMethod] |
| class A: |
| def f(self) -> None: |
| a = [] # E: Need type annotation for "a" (hint: "a: List[<type>] = ...") |
| [builtins fixtures/list.pyi] |
| |
| [case testInferListInitializedToEmptyInMethodViaAttribute] |
| class A: |
| def f(self) -> None: |
| # Attributes aren't supported right now. |
| self.a = [] |
| self.a.append(1) |
| self.a.append('') # E: Argument 1 to "append" of "list" has incompatible type "str"; expected "int" |
| [builtins fixtures/list.pyi] |
| |
| [case testInferListInitializedToEmptyInClassBodyAndOverriden] |
| from typing import List |
| |
| class A: |
| def __init__(self) -> None: |
| self.x = [] # E: Need type annotation for "x" (hint: "x: List[<type>] = ...") |
| |
| class B(A): |
| # TODO?: This error is kind of a false positive, unfortunately |
| @property |
| def x(self) -> List[int]: # E: Signature of "x" incompatible with supertype "A" |
| return [123] |
| [builtins fixtures/list.pyi] |
| |
| [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] |
| |
| [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] |
| |
| [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] |
| |
| [case testInferDictInitializedToEmpty] |
| a = {} |
| a[1] = '' |
| a() # E: "Dict[int, str]" not callable |
| [builtins fixtures/dict.pyi] |
| |
| [case testInferDictInitializedToEmptyUsingUpdate] |
| a = {} |
| a.update({'': 42}) |
| a() # E: "Dict[str, int]" not callable |
| [builtins fixtures/dict.pyi] |
| |
| [case testInferDictInitializedToEmptyUsingUpdateError] |
| a = {} # E: Need type annotation for "a" (hint: "a: Dict[<type>, <type>] = ...") |
| a.update([1, 2]) # E: Argument 1 to "update" of "dict" has incompatible type "List[int]"; expected "Mapping[Any, Any]" |
| a() # E: "Dict[Any, Any]" not callable |
| [builtins fixtures/dict.pyi] |
| |
| [case testInferDictInitializedToEmptyAndIncompleteTypeInUpdate] |
| a = {} # E: Need type annotation for "a" (hint: "a: Dict[<type>, <type>] = ...") |
| a[1] = {} |
| b = {} # E: Need type annotation for "b" (hint: "b: Dict[<type>, <type>] = ...") |
| b[{}] = 1 |
| [builtins fixtures/dict.pyi] |
| |
| [case testInferDictInitializedToEmptyAndUpdatedFromMethod] |
| map = {} |
| def add() -> None: |
| map[1] = 2 |
| [builtins fixtures/dict.pyi] |
| |
| [case testInferDictInitializedToEmptyAndUpdatedFromMethodUnannotated] |
| map = {} |
| def add(): |
| map[1] = 2 |
| [builtins fixtures/dict.pyi] |
| |
| [case testSpecialCaseEmptyListInitialization] |
| def f(blocks: Any): # E: Name "Any" is not defined \ |
| # N: Did you forget to import it from "typing"? (Suggestion: "from typing import Any") |
| to_process = [] |
| to_process = list(blocks) |
| [builtins fixtures/list.pyi] |
| |
| [case testSpecialCaseEmptyListInitialization2] |
| def f(blocks: object): |
| to_process = [] |
| to_process = list(blocks) # E: No overload variant of "list" matches argument type "object" \ |
| # N: Possible overload variants: \ |
| # N: def [T] __init__(self) -> List[T] \ |
| # N: def [T] __init__(self, x: Iterable[T]) -> List[T] |
| [builtins fixtures/list.pyi] |
| |
| [case testInferListInitializedToEmptyAndAssigned] |
| a = [] |
| if bool(): |
| a = [1] |
| reveal_type(a) # N: Revealed type is "builtins.list[builtins.int]" |
| |
| def f(): |
| return [1] |
| b = [] |
| if bool(): |
| b = f() |
| reveal_type(b) # N: Revealed type is "builtins.list[Any]" |
| |
| d = {} |
| if bool(): |
| d = {1: 'x'} |
| reveal_type(d) # N: Revealed type is "builtins.dict[builtins.int, builtins.str]" |
| |
| dd = {} # E: Need type annotation for "dd" (hint: "dd: Dict[<type>, <type>] = ...") |
| if bool(): |
| dd = [1] # E: Incompatible types in assignment (expression has type "List[int]", variable has type "Dict[Any, Any]") |
| reveal_type(dd) # N: Revealed type is "builtins.dict[Any, Any]" |
| [builtins fixtures/dict.pyi] |
| |
| [case testInferOrderedDictInitializedToEmpty] |
| from collections import OrderedDict |
| |
| o = OrderedDict() |
| o[1] = 'x' |
| reveal_type(o) # N: Revealed type is "collections.OrderedDict[builtins.int, builtins.str]" |
| |
| d = {1: 'x'} |
| oo = OrderedDict() |
| oo.update(d) |
| reveal_type(oo) # N: Revealed type is "collections.OrderedDict[builtins.int, builtins.str]" |
| [builtins fixtures/dict.pyi] |
| |
| [case testEmptyCollectionAssignedToVariableTwiceIncremental] |
| x = [] # E: Need type annotation for "x" (hint: "x: List[<type>] = ...") |
| y = x |
| x = [] |
| reveal_type(x) # N: Revealed type is "builtins.list[Any]" |
| d = {} # E: Need type annotation for "d" (hint: "d: Dict[<type>, <type>] = ...") |
| z = d |
| d = {} |
| reveal_type(d) # N: Revealed type is "builtins.dict[Any, Any]" |
| [builtins fixtures/dict.pyi] |
| [out2] |
| main:1: error: Need type annotation for "x" (hint: "x: List[<type>] = ...") |
| main:4: note: Revealed type is "builtins.list[Any]" |
| main:5: error: Need type annotation for "d" (hint: "d: Dict[<type>, <type>] = ...") |
| main:8: note: Revealed type is "builtins.dict[Any, Any]" |
| |
| [case testEmptyCollectionAssignedToVariableTwiceNoReadIncremental] |
| x = [] # E: Need type annotation for "x" (hint: "x: List[<type>] = ...") |
| x = [] |
| [builtins fixtures/list.pyi] |
| [out2] |
| main:1: error: Need type annotation for "x" (hint: "x: List[<type>] = ...") |
| |
| [case testInferAttributeInitializedToEmptyAndAssigned] |
| class C: |
| def __init__(self) -> None: |
| self.a = [] |
| if bool(): |
| self.a = [1] |
| reveal_type(C().a) # N: Revealed type is "builtins.list[builtins.int]" |
| [builtins fixtures/list.pyi] |
| |
| [case testInferAttributeInitializedToEmptyAndAppended] |
| class C: |
| def __init__(self) -> None: |
| self.a = [] |
| if bool(): |
| self.a.append(1) |
| reveal_type(C().a) # N: Revealed type is "builtins.list[builtins.int]" |
| [builtins fixtures/list.pyi] |
| |
| [case testInferAttributeInitializedToEmptyAndAssignedItem] |
| class C: |
| def __init__(self) -> None: |
| self.a = {} |
| if bool(): |
| self.a[0] = 'yes' |
| reveal_type(C().a) # N: Revealed type is "builtins.dict[builtins.int, builtins.str]" |
| [builtins fixtures/dict.pyi] |
| |
| [case testInferAttributeInitializedToNoneAndAssigned] |
| # flags: --strict-optional |
| class C: |
| def __init__(self) -> None: |
| self.a = None |
| if bool(): |
| self.a = 1 |
| reveal_type(C().a) # N: Revealed type is "Union[builtins.int, None]" |
| |
| [case testInferAttributeInitializedToEmptyNonSelf] |
| class C: |
| def __init__(self) -> None: |
| self.a = [] # E: Need type annotation for "a" (hint: "a: List[<type>] = ...") |
| if bool(): |
| a = self |
| a.a = [1] |
| a.a.append(1) |
| reveal_type(C().a) # N: Revealed type is "builtins.list[Any]" |
| [builtins fixtures/list.pyi] |
| |
| [case testInferAttributeInitializedToEmptyAndAssignedOtherMethod] |
| class C: |
| def __init__(self) -> None: |
| self.a = [] # E: Need type annotation for "a" (hint: "a: List[<type>] = ...") |
| def meth(self) -> None: |
| self.a = [1] |
| reveal_type(C().a) # N: Revealed type is "builtins.list[Any]" |
| [builtins fixtures/list.pyi] |
| |
| [case testInferAttributeInitializedToEmptyAndAppendedOtherMethod] |
| class C: |
| def __init__(self) -> None: |
| self.a = [] # E: Need type annotation for "a" (hint: "a: List[<type>] = ...") |
| def meth(self) -> None: |
| self.a.append(1) |
| reveal_type(C().a) # N: Revealed type is "builtins.list[Any]" |
| [builtins fixtures/list.pyi] |
| |
| [case testInferAttributeInitializedToEmptyAndAssignedItemOtherMethod] |
| class C: |
| def __init__(self) -> None: |
| self.a = {} # E: Need type annotation for "a" (hint: "a: Dict[<type>, <type>] = ...") |
| def meth(self) -> None: |
| self.a[0] = 'yes' |
| reveal_type(C().a) # N: Revealed type is "builtins.dict[Any, Any]" |
| [builtins fixtures/dict.pyi] |
| |
| [case testInferAttributeInitializedToNoneAndAssignedOtherMethod] |
| # flags: --strict-optional |
| class C: |
| def __init__(self) -> None: |
| self.a = None |
| def meth(self) -> None: |
| self.a = 1 # E: Incompatible types in assignment (expression has type "int", variable has type "None") |
| reveal_type(C().a) # N: Revealed type is "None" |
| |
| [case testInferAttributeInitializedToEmptyAndAssignedClassBody] |
| class C: |
| a = [] # E: Need type annotation for "a" (hint: "a: List[<type>] = ...") |
| def __init__(self) -> None: |
| self.a = [1] |
| reveal_type(C().a) # N: Revealed type is "builtins.list[Any]" |
| [builtins fixtures/list.pyi] |
| |
| [case testInferAttributeInitializedToEmptyAndAppendedClassBody] |
| class C: |
| a = [] # E: Need type annotation for "a" (hint: "a: List[<type>] = ...") |
| def __init__(self) -> None: |
| self.a.append(1) |
| reveal_type(C().a) # N: Revealed type is "builtins.list[Any]" |
| [builtins fixtures/list.pyi] |
| |
| [case testInferAttributeInitializedToEmptyAndAssignedItemClassBody] |
| class C: |
| a = {} # E: Need type annotation for "a" (hint: "a: Dict[<type>, <type>] = ...") |
| def __init__(self) -> None: |
| self.a[0] = 'yes' |
| reveal_type(C().a) # N: Revealed type is "builtins.dict[Any, Any]" |
| [builtins fixtures/dict.pyi] |
| |
| [case testInferAttributeInitializedToNoneAndAssignedClassBody] |
| # flags: --strict-optional |
| class C: |
| a = None |
| def __init__(self) -> None: |
| self.a = 1 |
| reveal_type(C().a) # N: Revealed type is "Union[builtins.int, None]" |
| |
| [case testInferListTypeFromEmptyListAndAny] |
| def f(): |
| return [] |
| |
| def g() -> None: |
| x = [] |
| if bool(): |
| x = f() |
| reveal_type(x) # N: Revealed type is "builtins.list[Any]" |
| |
| y = [] |
| y.extend(f()) |
| reveal_type(y) # N: Revealed type is "builtins.list[Any]" |
| [builtins fixtures/list.pyi] |
| |
| [case testInferFromEmptyDictWhenUsingIn] |
| d = {} |
| if 'x' in d: |
| d['x'] = 1 |
| reveal_type(d) # N: Revealed type is "builtins.dict[builtins.str, builtins.int]" |
| |
| dd = {} |
| if 'x' not in dd: |
| dd['x'] = 1 |
| reveal_type(dd) # N: Revealed type is "builtins.dict[builtins.str, builtins.int]" |
| [builtins fixtures/dict.pyi] |
| |
| [case testInferFromEmptyDictWhenUsingInSpecialCase] |
| d = None |
| if 'x' in d: # E: "None" has no attribute "__iter__" (not iterable) |
| pass |
| reveal_type(d) # N: Revealed type is "None" |
| [builtins fixtures/dict.pyi] |
| |
| [case testInferFromEmptyListWhenUsingInWithStrictEquality] |
| # flags: --strict-equality |
| def f() -> None: |
| a = [] |
| if 1 in a: # TODO: This should be an error |
| a.append('x') |
| [builtins fixtures/list.pyi] |
| [typing fixtures/typing-full.pyi] |
| |
| [case testInferListTypeFromInplaceAdd] |
| a = [] |
| a += [1] |
| reveal_type(a) # N: Revealed type is "builtins.list[builtins.int]" |
| [builtins fixtures/list.pyi] |
| |
| [case testInferSetTypeFromInplaceOr] |
| a = set() |
| a |= {'x'} |
| reveal_type(a) # N: Revealed type is "builtins.set[builtins.str]" |
| [builtins fixtures/set.pyi] |
| |
| |
| -- 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 |
| 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 "x" (hint: "x: List[<type>] = ...") |
| 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 "x" (hint: "x: List[<type>] = ...") |
| [builtins fixtures/list.pyi] |
| [out] |
| |
| [case testPartiallyInitializedToNoneAndThenToIncompleteType-skip] |
| # TODO(ddfisher): fix partial type bug and re-enable |
| from typing import TypeVar, Dict |
| T = TypeVar('T') |
| def f(*x: T) -> Dict[int, T]: pass |
| x = None # E: Need type annotation for "x" |
| if object(): |
| x = f() |
| [builtins fixtures/dict.pyi] |
| |
| [case testPartiallyInitializedVariableDoesNotEscapeScope1] |
| def f() -> None: |
| x = None |
| reveal_type(x) # N: Revealed type is "None" |
| x = 1 |
| [out] |
| |
| [case testPartiallyInitializedVariableDoesNotEscapeScope2] |
| x = None |
| 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:6: error: Incompatible types in assignment (expression has type "int", variable has type "None") |
| main:7: error: "None" 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:5: error: "None" has no attribute "__iter__" (not iterable) |
| |
| [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 "x" (hint: "x: List[<type>] = ...") |
| |
| [case testPartialTypeErrorSpecialCase3] |
| class A: |
| x = None |
| def f(self) -> None: |
| for a in A.x: |
| pass |
| [builtins fixtures/for.pyi] |
| [out] |
| main:4: error: "None" has no attribute "__iter__" (not iterable) |
| |
| |
| -- 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 "x" (hint: "x: Dict[<type>, <type>] = ...") |
| y = o |
| z = {} # E: Need type annotation for "z" (hint: "z: Dict[<type>, <type>] = ...") |
| 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 |
| |
| [case testForwardReferenceToDecoratedClassMethod] |
| from typing import TypeVar, Callable |
| |
| T = TypeVar('T') |
| def dec() -> Callable[[T], T]: pass |
| |
| A.g # E: Cannot determine type of "g" |
| |
| class A: |
| @classmethod |
| def f(cls) -> None: |
| reveal_type(cls.g) # N: Revealed type is "def (x: builtins.str)" |
| |
| @classmethod |
| @dec() |
| def g(cls, x: str) -> None: |
| pass |
| |
| @classmethod |
| def h(cls) -> None: |
| reveal_type(cls.g) # N: Revealed type is "def (x: builtins.str)" |
| |
| reveal_type(A.g) # N: Revealed type is "def (x: builtins.str)" |
| [builtins fixtures/classmethod.pyi] |
| |
| |
| -- 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[Any, ...]]"; expected "Union[int, str]" |
| [builtins fixtures/tuple.pyi] |
| |
| [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: Unsupported target for indexed assignment ("Type[C[Any]]") |
| main:4: error: Invalid type: try using Literal[0] instead? |
| |
| [case testNoCrashOnPartialMember] |
| class C: |
| x = None |
| def __init__(self) -> None: |
| self.x = [] # E: Need type annotation for "x" (hint: "x: List[<type>] = ...") |
| [builtins fixtures/list.pyi] |
| [out] |
| |
| [case testNoCrashOnPartialVariable] |
| from typing import Tuple, TypeVar |
| T = TypeVar('T', bound=str) |
| |
| def f(x: T) -> Tuple[T]: |
| ... |
| x = None |
| (x,) = f('') |
| reveal_type(x) # N: Revealed type is "builtins.str" |
| [builtins fixtures/tuple.pyi] |
| [out] |
| |
| [case testNoCrashOnPartialVariable2] |
| from typing import Tuple, TypeVar |
| T = TypeVar('T', bound=str) |
| |
| def f() -> Tuple[T]: |
| ... |
| x = None |
| if int(): |
| (x,) = f() |
| [builtins fixtures/tuple.pyi] |
| [out] |
| |
| [case testNoCrashOnPartialVariable3] |
| from typing import Tuple, TypeVar |
| T = TypeVar('T') |
| |
| def f(x: T) -> Tuple[T, T]: |
| ... |
| x = None |
| (x, x) = f('') |
| reveal_type(x) # N: Revealed type is "builtins.str" |
| [builtins fixtures/tuple.pyi] |
| [out] |
| |
| [case testInferenceNestedTuplesFromGenericIterable] |
| from typing import Tuple, TypeVar |
| |
| T = TypeVar('T') |
| |
| def make_tuple(elem: T) -> Tuple[T]: |
| return (elem,) |
| |
| def main() -> None: |
| ((a, b),) = make_tuple((1, 2)) |
| reveal_type(a) # N: Revealed type is "builtins.int" |
| reveal_type(b) # N: Revealed type is "builtins.int" |
| [builtins fixtures/tuple.pyi] |
| [out] |
| |
| [case testDontMarkUnreachableAfterInferenceUninhabited] |
| from typing import TypeVar |
| T = TypeVar('T') |
| def f() -> T: pass # E: A function returning TypeVar should receive at least one argument containing the same Typevar |
| |
| class C: |
| x = f() # E: Need type annotation for "x" |
| def m(self) -> str: |
| return 42 # E: Incompatible return value type (got "int", expected "str") |
| |
| if bool(): |
| f() |
| 1() # E: "int" not callable |
| [builtins fixtures/list.pyi] |
| [out] |
| |
| [case testDontMarkUnreachableAfterInferenceUninhabited2] |
| # flags: --strict-optional |
| from typing import TypeVar, Optional |
| T = TypeVar('T') |
| def f(x: Optional[T] = None) -> T: pass |
| |
| class C: |
| x = f() # E: Need type annotation for "x" |
| def m(self) -> str: |
| return 42 # E: Incompatible return value type (got "int", expected "str") |
| |
| if bool(): |
| f() |
| 1() # E: "int" not callable |
| [builtins fixtures/list.pyi] |
| [out] |
| |
| [case testDontMarkUnreachableAfterInferenceUninhabited3] |
| from typing import TypeVar, List |
| T = TypeVar('T') |
| def f(x: List[T]) -> T: pass |
| |
| class C: |
| x = f([]) # E: Need type annotation for "x" |
| def m(self) -> str: |
| return 42 # E: Incompatible return value type (got "int", expected "str") |
| |
| if bool(): |
| f([]) |
| 1() # E: "int" not callable |
| [builtins fixtures/list.pyi] |
| [out] |
| |
| |
| -- --local-partial-types |
| -- --------------------- |
| |
| |
| [case testLocalPartialTypesWithGlobalInitializedToNone] |
| # flags: --local-partial-types |
| x = None # E: Need type annotation for "x" |
| |
| def f() -> None: |
| global x |
| x = 1 |
| |
| # TODO: "Any" could be a better type here to avoid multiple error messages |
| reveal_type(x) # N: Revealed type is "None" |
| |
| [case testLocalPartialTypesWithGlobalInitializedToNone2] |
| # flags: --local-partial-types |
| x = None # E: Need type annotation for "x" |
| |
| def f(): |
| global x |
| x = 1 |
| |
| # TODO: "Any" could be a better type here to avoid multiple error messages |
| reveal_type(x) # N: Revealed type is "None" |
| |
| [case testLocalPartialTypesWithGlobalInitializedToNone3] |
| # flags: --local-partial-types --no-strict-optional |
| x = None |
| |
| def f() -> None: |
| global x |
| x = 1 # E: Incompatible types in assignment (expression has type "int", variable has type "str") |
| |
| x = '' |
| reveal_type(x) # N: Revealed type is "builtins.str" |
| |
| [case testLocalPartialTypesWithGlobalInitializedToNoneStrictOptional] |
| # flags: --local-partial-types --strict-optional |
| x = None |
| |
| def f() -> None: |
| global x |
| x = 1 # E: Incompatible types in assignment (expression has type "int", variable has type "Optional[str]") |
| |
| x = '' |
| def g() -> None: |
| reveal_type(x) # N: Revealed type is "Union[builtins.str, None]" |
| |
| [case testLocalPartialTypesWithGlobalInitializedToNone4] |
| # flags: --local-partial-types --no-strict-optional |
| a = None |
| |
| def f() -> None: |
| reveal_type(a) # N: Revealed type is "builtins.str" |
| |
| # TODO: This should probably be 'builtins.str', since there could be a |
| # call that causes a non-None value to be assigned |
| reveal_type(a) # N: Revealed type is "None" |
| a = '' |
| reveal_type(a) # N: Revealed type is "builtins.str" |
| [builtins fixtures/list.pyi] |
| |
| [case testLocalPartialTypesWithClassAttributeInitializedToNone] |
| # flags: --local-partial-types |
| class A: |
| x = None # E: Need type annotation for "x" |
| |
| def f(self) -> None: |
| self.x = 1 |
| |
| [case testLocalPartialTypesWithClassAttributeInitializedToEmptyDict] |
| # flags: --local-partial-types |
| class A: |
| x = {} # E: Need type annotation for "x" (hint: "x: Dict[<type>, <type>] = ...") |
| |
| def f(self) -> None: |
| self.x[0] = '' |
| |
| reveal_type(A().x) # N: Revealed type is "builtins.dict[Any, Any]" |
| reveal_type(A.x) # N: Revealed type is "builtins.dict[Any, Any]" |
| [builtins fixtures/dict.pyi] |
| |
| [case testLocalPartialTypesWithGlobalInitializedToEmptyList] |
| # flags: --local-partial-types |
| a = [] |
| |
| def f() -> None: |
| a[0] |
| reveal_type(a) # N: Revealed type is "builtins.list[builtins.int]" |
| |
| a.append(1) |
| reveal_type(a) # N: Revealed type is "builtins.list[builtins.int]" |
| [builtins fixtures/list.pyi] |
| |
| [case testLocalPartialTypesWithGlobalInitializedToEmptyList2] |
| # flags: --local-partial-types |
| a = [] # E: Need type annotation for "a" (hint: "a: List[<type>] = ...") |
| |
| def f() -> None: |
| a.append(1) |
| reveal_type(a) # N: Revealed type is "builtins.list[Any]" |
| |
| reveal_type(a) # N: Revealed type is "builtins.list[Any]" |
| [builtins fixtures/list.pyi] |
| |
| [case testLocalPartialTypesWithGlobalInitializedToEmptyList3] |
| # flags: --local-partial-types |
| a = [] # E: Need type annotation for "a" (hint: "a: List[<type>] = ...") |
| |
| def f(): |
| a.append(1) |
| |
| reveal_type(a) # N: Revealed type is "builtins.list[Any]" |
| [builtins fixtures/list.pyi] |
| |
| [case testLocalPartialTypesWithGlobalInitializedToEmptyDict] |
| # flags: --local-partial-types |
| a = {} |
| |
| def f() -> None: |
| a[0] |
| reveal_type(a) # N: Revealed type is "builtins.dict[builtins.int, builtins.str]" |
| |
| a[0] = '' |
| reveal_type(a) # N: Revealed type is "builtins.dict[builtins.int, builtins.str]" |
| [builtins fixtures/dict.pyi] |
| |
| [case testLocalPartialTypesWithGlobalInitializedToEmptyDict2] |
| # flags: --local-partial-types |
| a = {} # E: Need type annotation for "a" (hint: "a: Dict[<type>, <type>] = ...") |
| |
| def f() -> None: |
| a[0] = '' |
| reveal_type(a) # N: Revealed type is "builtins.dict[Any, Any]" |
| |
| reveal_type(a) # N: Revealed type is "builtins.dict[Any, Any]" |
| [builtins fixtures/dict.pyi] |
| |
| [case testLocalPartialTypesWithGlobalInitializedToEmptyDict3] |
| # flags: --local-partial-types |
| a = {} # E: Need type annotation for "a" (hint: "a: Dict[<type>, <type>] = ...") |
| |
| def f(): |
| a[0] = '' |
| |
| reveal_type(a) # N: Revealed type is "builtins.dict[Any, Any]" |
| [builtins fixtures/dict.pyi] |
| |
| [case testLocalPartialTypesWithNestedFunction] |
| # flags: --local-partial-types |
| def f() -> None: |
| a = {} |
| def g() -> None: |
| a[0] = '' |
| reveal_type(a) # N: Revealed type is "builtins.dict[builtins.int, builtins.str]" |
| [builtins fixtures/dict.pyi] |
| |
| [case testLocalPartialTypesWithNestedFunction2] |
| # flags: --local-partial-types |
| def f() -> None: |
| a = [] |
| def g() -> None: |
| a.append(1) |
| reveal_type(a) # N: Revealed type is "builtins.list[builtins.int]" |
| [builtins fixtures/list.pyi] |
| |
| [case testLocalPartialTypesWithNestedFunction3] |
| # flags: --local-partial-types --no-strict-optional |
| def f() -> None: |
| a = None |
| def g() -> None: |
| nonlocal a |
| a = '' |
| reveal_type(a) # N: Revealed type is "builtins.str" |
| [builtins fixtures/dict.pyi] |
| |
| [case testLocalPartialTypesWithInheritance] |
| # flags: --local-partial-types |
| from typing import Optional |
| |
| class A: |
| x: Optional[str] |
| |
| class B(A): |
| x = None |
| |
| reveal_type(B.x) # N: Revealed type is "None" |
| |
| [case testLocalPartialTypesWithInheritance2] |
| # flags: --local-partial-types --strict-optional |
| class A: |
| x: str |
| |
| class B(A): |
| x = None # E: Incompatible types in assignment (expression has type "None", base class "A" defined the type as "str") |
| |
| [case testLocalPartialTypesWithAnyBaseClass] |
| # flags: --local-partial-types --strict-optional |
| from typing import Any |
| |
| A: Any |
| |
| class B(A): |
| x = None |
| |
| class C(B): |
| y = None |
| |
| [case testLocalPartialTypesInMultipleMroItems] |
| # flags: --local-partial-types --strict-optional |
| from typing import Optional |
| |
| class A: |
| x: Optional[str] |
| |
| class B(A): |
| x = None |
| |
| class C(B): |
| x = None |
| |
| # TODO: Inferring None below is unsafe (https://github.com/python/mypy/issues/3208) |
| reveal_type(B.x) # N: Revealed type is "None" |
| reveal_type(C.x) # N: Revealed type is "None" |
| |
| [case testLocalPartialTypesWithInheritance3] |
| # flags: --local-partial-types |
| from typing import Optional |
| |
| class X: pass |
| class Y(X): pass |
| |
| class A: |
| x: Optional[X] |
| |
| class B(A): |
| x = None |
| x = Y() |
| |
| reveal_type(B.x) # N: Revealed type is "Union[__main__.Y, None]" |
| |
| [case testLocalPartialTypesBinderSpecialCase] |
| # flags: --local-partial-types |
| from typing import List |
| |
| def f(x): pass |
| |
| class A: |
| x = None # E: Need type annotation for "x" |
| |
| def f(self, p: List[str]) -> None: |
| self.x = f(p) |
| f(z for z in p) |
| [builtins fixtures/list.pyi] |
| |
| [case testLocalPartialTypesAccessPartialNoneAttribute] |
| # flags: --local-partial-types |
| class C: |
| a = None # E: Need type annotation for "a" |
| |
| def f(self, x) -> None: |
| C.a.y # E: Item "None" of "Optional[Any]" has no attribute "y" |
| |
| [case testLocalPartialTypesAccessPartialNoneAttribute2] |
| # flags: --local-partial-types |
| class C: |
| a = None # E: Need type annotation for "a" |
| |
| def f(self, x) -> None: |
| self.a.y # E: Item "None" of "Optional[Any]" has no attribute "y" |
| |
| -- Special case for assignment to '_' |
| -- ---------------------------------- |
| |
| [case testUnusedTargetLocal] |
| def foo() -> None: |
| _ = 0 |
| _ = '' |
| |
| [case testUnusedTargetNotGlobal] |
| _ = 0 |
| _ = '' # E: Incompatible types in assignment (expression has type "str", variable has type "int") |
| |
| [case testUnusedTargetNotClass] |
| # flags: --allow-redefinition |
| class C: |
| _, _ = 0, 0 |
| _ = '' |
| reveal_type(C._) # N: Revealed type is "builtins.str" |
| |
| [case testUnusedTargetNotClass2] |
| # flags: --disallow-redefinition |
| class C: |
| _, _ = 0, 0 |
| _ = '' # E: Incompatible types in assignment (expression has type "str", variable has type "int") |
| reveal_type(C._) # N: Revealed type is "builtins.int" |
| |
| [case testUnusedTargetTupleUnpacking] |
| def foo() -> None: |
| _, _ = (0, '') |
| _ = 0 |
| _ = '' |
| def bar() -> None: |
| t = (0, '') |
| _, _ = t |
| _ = 0 |
| _ = '' |
| [builtins fixtures/tuple.pyi] |
| |
| [case testUnusedTargetMultipleTargets] |
| def foo() -> None: |
| _ = x = 0 |
| _ = y = '' |
| _ = 0 |
| _ = '' |
| def bar() -> None: |
| x = _ = 0 |
| y = _ = '' |
| _ = 0 |
| _ = '' |
| x + 0 |
| y + '' |
| x + '' # E: Unsupported operand types for + ("int" and "str") |
| y + 0 # E: Unsupported operand types for + ("str" and "int") |
| [builtins fixtures/primitives.pyi] |
| |
| [case testUnusedTargetNotImport] |
| import d, c, b, a |
| [file _.py] |
| def f(): pass |
| [file m.py] |
| def f(): pass |
| _ = f |
| _ = 0 # E: Incompatible types in assignment (expression has type "int", variable has type "Callable[[], Any]") |
| [file a.py] |
| def foo() -> None: |
| import _ |
| _.f() |
| _ = 0 # E: Incompatible types in assignment (expression has type "int", variable has type Module) |
| [file b.py] |
| def foo() -> None: |
| import m as _ |
| _.f() |
| _ = 0 # E: Incompatible types in assignment (expression has type "int", variable has type Module) |
| [file c.py] |
| def foo() -> None: |
| from m import _ |
| _() |
| _ = '' # E: Incompatible types in assignment (expression has type "str", variable has type "Callable[[], Any]") |
| [file d.py] |
| def foo() -> None: |
| from m import f as _ |
| _() |
| _ = 0 # E: Incompatible types in assignment (expression has type "int", variable has type "Callable[[], Any]") |
| [builtins fixtures/module.pyi] |
| |
| [case testUnderscoreClass] |
| def foo() -> None: |
| class _: |
| pass |
| _().method() # E: "_" has no attribute "method" |
| |
| [case testUnusedTargetForLoop] |
| def f() -> None: |
| a = [(0, '', 0)] |
| for _, _, x in a: |
| x = 0 |
| x = '' # E: Incompatible types in assignment (expression has type "str", variable has type "int") |
| _ = 0 |
| _ = '' |
| [builtins fixtures/list.pyi] |
| |
| [case testUnusedTargetWithClause] |
| class C: |
| def __enter__(self) -> int: pass |
| def __exit__(self, *args): pass |
| def f() -> None: |
| with C() as _: pass |
| _ = 0 |
| _ = '' |
| [builtins fixtures/tuple.pyi] |
| |
| [case testUnusedTargetNotExceptClause] |
| # Things don't work for except clauses. |
| # This is due to the implementation, but it's just as well. |
| def f() -> None: |
| try: pass |
| except BaseException as _: |
| _ = 0 # E: Incompatible types in assignment (expression has type "int", variable has type "BaseException") |
| _ = '' # E: Incompatible types in assignment (expression has type "str", variable has type "BaseException") |
| [builtins fixtures/exception.pyi] |
| |
| -- Tests for permissive toplevel checking |
| -- -------------- |
| |
| [case testPermissiveAttributeOverride1] |
| # flags: --allow-untyped-globals |
| |
| class A: |
| x = None |
| |
| class B(A): |
| x = 12 |
| |
| class C(A): |
| x = '12' |
| |
| reveal_type(A.x) # N: Revealed type is "Union[Any, None]" |
| reveal_type(B.x) # N: Revealed type is "builtins.int" |
| reveal_type(C.x) # N: Revealed type is "builtins.str" |
| |
| [case testPermissiveAttributeOverride2] |
| # flags: --allow-untyped-globals |
| |
| class A: |
| x = [] |
| |
| class B(A): |
| x = [12] |
| |
| class C(A): |
| x = ['12'] |
| |
| reveal_type(A.x) # N: Revealed type is "builtins.list[Any]" |
| reveal_type(B.x) # N: Revealed type is "builtins.list[builtins.int]" |
| reveal_type(C.x) # N: Revealed type is "builtins.list[builtins.str]" |
| |
| [builtins fixtures/list.pyi] |
| |
| [case testPermissiveAttribute] |
| # flags: --allow-untyped-globals |
| |
| class A: |
| x = [] |
| def f(self) -> None: |
| reveal_type(self.x) # N: Revealed type is "builtins.list[Any]" |
| |
| [builtins fixtures/list.pyi] |
| |
| [case testPermissiveGlobalContainer1] |
| # flags: --allow-untyped-globals --local-partial-types |
| |
| import a |
| |
| [file b.py] |
| x = [] |
| y = {} |
| |
| def foo() -> None: |
| reveal_type(x) # N: Revealed type is "builtins.list[Any]" |
| reveal_type(y) # N: Revealed type is "builtins.dict[Any, Any]" |
| |
| [file a.py] |
| from b import x, y |
| reveal_type(x) # N: Revealed type is "builtins.list[Any]" |
| reveal_type(y) # N: Revealed type is "builtins.dict[Any, Any]" |
| |
| [builtins fixtures/dict.pyi] |
| |
| [case testPermissiveGlobalContainer2] |
| # flags: --allow-untyped-globals |
| |
| import a |
| |
| [file b.py] |
| x = [] |
| y = {} |
| |
| def foo() -> None: |
| reveal_type(x) # N: Revealed type is "builtins.list[Any]" |
| reveal_type(y) # N: Revealed type is "builtins.dict[Any, Any]" |
| |
| [file a.py] |
| from b import x, y |
| reveal_type(x) # N: Revealed type is "builtins.list[Any]" |
| reveal_type(y) # N: Revealed type is "builtins.dict[Any, Any]" |
| |
| [builtins fixtures/dict.pyi] |
| |
| [case testPermissiveGlobalContainer3] |
| # flags: --allow-untyped-globals --local-partial-types |
| |
| import a |
| |
| [file b.py] |
| x = [] |
| y = {} |
| z = y |
| |
| |
| [file a.py] |
| from b import x, y |
| reveal_type(x) # N: Revealed type is "builtins.list[Any]" |
| reveal_type(y) # N: Revealed type is "builtins.dict[Any, Any]" |
| |
| [builtins fixtures/dict.pyi] |
| [case testPermissiveGlobalContainer4] |
| # flags: --allow-untyped-globals |
| |
| import a |
| |
| [file b.py] |
| x = [] |
| y = {} |
| z = y |
| |
| |
| [file a.py] |
| from b import x, y |
| reveal_type(x) # N: Revealed type is "builtins.list[Any]" |
| reveal_type(y) # N: Revealed type is "builtins.dict[Any, Any]" |
| |
| [builtins fixtures/dict.pyi] |
| |
| [case testInheritedAttributeNoStrictOptional] |
| # flags: --no-strict-optional |
| class A: |
| x: str |
| |
| class B(A): |
| x = None |
| x = '' |
| reveal_type(x) # N: Revealed type is "builtins.str" |
| |
| [case testIncompatibleInheritedAttributeNoStrictOptional] |
| # flags: --no-strict-optional |
| class A: |
| x: str |
| |
| class B(A): |
| x = None |
| x = 2 # E: Incompatible types in assignment (expression has type "int", base class "A" defined the type as "str") |
| |
| [case testInheritedAttributeStrictOptional] |
| # flags: --strict-optional |
| class A: |
| x: str |
| |
| class B(A): |
| x = None # E: Incompatible types in assignment (expression has type "None", base class "A" defined the type as "str") |
| x = '' |
| |
| [case testNeedAnnotationForCallable] |
| from typing import TypeVar, Optional, Callable |
| |
| T = TypeVar('T') |
| |
| def f(x: Optional[T] = None) -> Callable[..., T]: ... |
| |
| x = f() # E: Need type annotation for "x" |
| y = x |
| |
| [case testDontNeedAnnotationForCallable] |
| from typing import TypeVar, Optional, Callable, NoReturn |
| |
| T = TypeVar('T') |
| |
| def f() -> Callable[..., NoReturn]: ... |
| |
| x = f() |
| reveal_type(x) # N: Revealed type is "def (*Any, **Any) -> <nothing>" |
| |
| [case testDeferralInNestedScopes] |
| |
| |
| def g() -> None: |
| def f() -> None: |
| x + 'no way' # E: Unsupported operand types for + ("int" and "str") |
| x = int() |
| f() |
| |
| [case testDeferralOfMemberNested] |
| from typing import Tuple |
| |
| def f() -> None: |
| c: C |
| t: Tuple[str, Tuple[str, str]] |
| x, (y, c.a) = t # E: Incompatible types in assignment (expression has type "str", variable has type "int") |
| |
| class C: |
| def __init__(self, a: int) -> None: |
| self.a = a |
| [builtins fixtures/tuple.pyi] |
| |
| [case testUnionGenericWithBoundedVariable] |
| from typing import Generic, TypeVar, Union |
| |
| T = TypeVar('T', bound=A) |
| class Z(Generic[T]): |
| def __init__(self, y: T) -> None: |
| self.y = y |
| |
| class A: ... |
| class B(A): ... |
| F = TypeVar('F', bound=A) |
| |
| def q1(x: Union[F, Z[F]]) -> F: |
| if isinstance(x, Z): |
| return x.y |
| else: |
| return x |
| |
| def q2(x: Union[Z[F], F]) -> F: |
| if isinstance(x, Z): |
| return x.y |
| else: |
| return x |
| |
| b: B |
| reveal_type(q1(b)) # N: Revealed type is "__main__.B" |
| reveal_type(q2(b)) # N: Revealed type is "__main__.B" |
| |
| z: Z[B] |
| reveal_type(q1(z)) # N: Revealed type is "__main__.B" |
| reveal_type(q2(z)) # N: Revealed type is "__main__.B" |
| |
| reveal_type(q1(Z(b))) # N: Revealed type is "__main__.B" |
| reveal_type(q2(Z(b))) # N: Revealed type is "__main__.B" |
| [builtins fixtures/isinstancelist.pyi] |
| |
| [case testUnionInvariantSubClassAndCovariantBase] |
| from typing import Union, Generic, TypeVar |
| |
| T = TypeVar('T') |
| T_co = TypeVar('T_co', covariant=True) |
| |
| class Cov(Generic[T_co]): ... |
| class Inv(Cov[T]): ... |
| |
| X = Union[Cov[T], Inv[T]] |
| |
| def f(x: X[T]) -> T: ... |
| x: Inv[int] |
| reveal_type(f(x)) # N: Revealed type is "builtins.int" |
| |
| [case testOptionalTypeVarAgainstOptional] |
| # flags: --strict-optional |
| from typing import Optional, TypeVar, Iterable, Iterator, List |
| |
| _T = TypeVar('_T') |
| |
| def filter(__function: None, __iterable: Iterable[Optional[_T]]) -> List[_T]: ... |
| |
| x: Optional[str] |
| |
| y = filter(None, [x]) |
| reveal_type(y) # N: Revealed type is "builtins.list[builtins.str]" |
| [builtins fixtures/list.pyi] |
| |
| [case testPartialDefaultDict] |
| from collections import defaultdict |
| x = defaultdict(int) |
| x[''] = 1 |
| reveal_type(x) # N: Revealed type is "collections.defaultdict[builtins.str, builtins.int]" |
| |
| y = defaultdict(int) # E: Need type annotation for "y" |
| |
| z = defaultdict(int) # E: Need type annotation for "z" |
| z[''] = '' |
| reveal_type(z) # N: Revealed type is "collections.defaultdict[Any, Any]" |
| [builtins fixtures/dict.pyi] |
| |
| [case testPartialDefaultDictInconsistentValueTypes] |
| from collections import defaultdict |
| a = defaultdict(int) # E: Need type annotation for "a" |
| a[''] = '' |
| a[''] = 1 |
| reveal_type(a) # N: Revealed type is "collections.defaultdict[builtins.str, builtins.int]" |
| [builtins fixtures/dict.pyi] |
| |
| [case testPartialDefaultDictListValue] |
| # flags: --no-strict-optional |
| from collections import defaultdict |
| a = defaultdict(list) |
| a['x'].append(1) |
| reveal_type(a) # N: Revealed type is "collections.defaultdict[builtins.str, builtins.list[builtins.int]]" |
| |
| b = defaultdict(lambda: []) |
| b[1].append('x') |
| reveal_type(b) # N: Revealed type is "collections.defaultdict[builtins.int, builtins.list[builtins.str]]" |
| [builtins fixtures/dict.pyi] |
| |
| [case testPartialDefaultDictListValueStrictOptional] |
| # flags: --strict-optional |
| from collections import defaultdict |
| a = defaultdict(list) |
| a['x'].append(1) |
| reveal_type(a) # N: Revealed type is "collections.defaultdict[builtins.str, builtins.list[builtins.int]]" |
| |
| b = defaultdict(lambda: []) |
| b[1].append('x') |
| reveal_type(b) # N: Revealed type is "collections.defaultdict[builtins.int, builtins.list[builtins.str]]" |
| [builtins fixtures/dict.pyi] |
| |
| [case testPartialDefaultDictSpecialCases] |
| from collections import defaultdict |
| class A: |
| def f(self) -> None: |
| self.x = defaultdict(list) |
| self.x['x'].append(1) |
| reveal_type(self.x) # N: Revealed type is "collections.defaultdict[builtins.str, builtins.list[builtins.int]]" |
| self.y = defaultdict(list) # E: Need type annotation for "y" |
| s = self |
| s.y['x'].append(1) |
| |
| x = {} # E: Need type annotation for "x" (hint: "x: Dict[<type>, <type>] = ...") |
| x['x'].append(1) |
| |
| y = defaultdict(list) # E: Need type annotation for "y" |
| y[[]].append(1) |
| [builtins fixtures/dict.pyi] |
| |
| [case testPartialDefaultDictSpecialCases2] |
| from collections import defaultdict |
| |
| x = defaultdict(lambda: [1]) # E: Need type annotation for "x" |
| x[1].append('') # E: Argument 1 to "append" of "list" has incompatible type "str"; expected "int" |
| reveal_type(x) # N: Revealed type is "collections.defaultdict[Any, builtins.list[builtins.int]]" |
| |
| xx = defaultdict(lambda: {'x': 1}) # E: Need type annotation for "xx" |
| xx[1]['z'] = 3 |
| reveal_type(xx) # N: Revealed type is "collections.defaultdict[Any, builtins.dict[builtins.str, builtins.int]]" |
| |
| y = defaultdict(dict) # E: Need type annotation for "y" |
| y['x'][1] = [3] |
| |
| z = defaultdict(int) # E: Need type annotation for "z" |
| z[1].append('') |
| reveal_type(z) # N: Revealed type is "collections.defaultdict[Any, Any]" |
| [builtins fixtures/dict.pyi] |
| |
| [case testPartialDefaultDictSpecialCase3] |
| from collections import defaultdict |
| |
| x = defaultdict(list) |
| x['a'] = [1, 2, 3] |
| reveal_type(x) # N: Revealed type is "collections.defaultdict[builtins.str, builtins.list[builtins.int]]" |
| |
| y = defaultdict(list) # E: Need type annotation for "y" |
| y['a'] = [] |
| reveal_type(y) # N: Revealed type is "collections.defaultdict[Any, Any]" |
| [builtins fixtures/dict.pyi] |
| |
| [case testInferCallableReturningNone1] |
| # flags: --no-strict-optional |
| from typing import Callable, TypeVar |
| |
| T = TypeVar("T") |
| |
| def f(x: Callable[[], T]) -> T: |
| return x() |
| |
| reveal_type(f(lambda: None)) # N: Revealed type is "None" |
| reveal_type(f(lambda: 1)) # N: Revealed type is "builtins.int" |
| |
| def g() -> None: pass |
| |
| reveal_type(f(g)) # N: Revealed type is "None" |
| |
| [case testInferCallableReturningNone2] |
| # flags: --strict-optional |
| from typing import Callable, TypeVar |
| |
| T = TypeVar("T") |
| |
| def f(x: Callable[[], T]) -> T: |
| return x() |
| |
| reveal_type(f(lambda: None)) # N: Revealed type is "None" |
| reveal_type(f(lambda: 1)) # N: Revealed type is "builtins.int" |
| |
| def g() -> None: pass |
| |
| reveal_type(f(g)) # N: Revealed type is "None" |
| |
| [case testInferredTypeIsSimpleNestedList] |
| from typing import Any, Union, List |
| |
| y: Union[List[Any], Any] |
| x: Union[List[Any], Any] |
| x = [y] |
| reveal_type(x) # N: Revealed type is "builtins.list[Any]" |
| [builtins fixtures/list.pyi] |
| |
| [case testInferredTypeIsSimpleNestedIterable] |
| from typing import Any, Union, Iterable |
| |
| y: Union[Iterable[Any], Any] |
| x: Union[Iterable[Any], Any] |
| x = [y] |
| reveal_type(x) # N: Revealed type is "builtins.list[Any]" |
| [builtins fixtures/list.pyi] |
| |
| [case testInferredTypeIsSimpleNestedListLoop] |
| from typing import Any, Union, List |
| |
| def test(seq: List[Union[List, Any]]) -> None: |
| k: Union[List, Any] |
| for k in seq: |
| if bool(): |
| k = [k] |
| reveal_type(k) # N: Revealed type is "builtins.list[Any]" |
| [builtins fixtures/list.pyi] |
| |
| [case testInferredTypeIsSimpleNestedIterableLoop] |
| from typing import Any, Union, List, Iterable |
| |
| def test(seq: List[Union[Iterable, Any]]) -> None: |
| k: Union[Iterable, Any] |
| for k in seq: |
| if bool(): |
| k = [k] |
| reveal_type(k) # N: Revealed type is "builtins.list[Any]" |
| [builtins fixtures/list.pyi] |
| |
| [case testErasedTypeRuntimeCoverage] |
| # https://github.com/python/mypy/issues/11913 |
| from typing import TypeVar, Type, Generic, Callable, Iterable |
| |
| class DataType: ... |
| |
| T1 = TypeVar('T1') |
| T2 = TypeVar("T2", bound=DataType) |
| |
| def map(__func: T1) -> None: ... |
| |
| def collection_from_dict_value(model: Type[T2]) -> None: |
| map(lambda i: i if isinstance(i, model) else i) |
| [builtins fixtures/isinstancelist.pyi] |
| |
| [case testRegression11705_Strict] |
| # flags: --strict-optional |
| # See: https://github.com/python/mypy/issues/11705 |
| from typing import Dict, Optional, NamedTuple |
| class C(NamedTuple): |
| x: int |
| |
| t: Optional[C] |
| d: Dict[C, bytes] |
| x = t and d[t] |
| reveal_type(x) # N: Revealed type is "Union[None, builtins.bytes]" |
| if x: |
| reveal_type(x) # N: Revealed type is "builtins.bytes" |
| [builtins fixtures/dict.pyi] |
| |
| [case testRegression11705_NoStrict] |
| # flags: --no-strict-optional |
| # See: https://github.com/python/mypy/issues/11705 |
| from typing import Dict, Optional, NamedTuple |
| class C(NamedTuple): |
| x: int |
| |
| t: Optional[C] |
| d: Dict[C, bytes] |
| x = t and d[t] |
| reveal_type(x) # N: Revealed type is "builtins.bytes" |
| if x: |
| reveal_type(x) # N: Revealed type is "builtins.bytes" |
| [builtins fixtures/dict.pyi] |
| |
| [case testTupleContextFromIterable] |
| from typing import TypeVar, Iterable, List, Union |
| |
| T = TypeVar("T") |
| |
| def foo(x: List[T]) -> List[T]: ... |
| x: Iterable[List[Union[int, str]]] = (foo([1]), foo(["a"])) |
| [builtins fixtures/tuple.pyi] |
| |
| [case testTupleContextFromIterable2] |
| from typing import Dict, Iterable, Tuple, Union |
| |
| def foo(x: Union[Tuple[str, Dict[str, int], str], Iterable[object]]) -> None: ... |
| foo(("a", {"a": "b"}, "b")) |
| [builtins fixtures/dict.pyi] |
| |
| [case testUnionTypeCallableInference] |
| from typing import Callable, Type, TypeVar, Union |
| |
| class A: |
| def __init__(self, x: str) -> None: ... |
| |
| T = TypeVar("T") |
| def type_or_callable(value: T, tp: Union[Type[T], Callable[[int], T]]) -> T: ... |
| reveal_type(type_or_callable(A("test"), A)) # N: Revealed type is "__main__.A" |