| -- Inferring locals/globals with simple types | |
| -- ------------------------------------------ | |
| [case testInferSimpleGvarType] | |
| class A: pass | |
| class B: pass | |
| 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 | |
| [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 (it only ever returns None) | |
| #b, c = g() # "g" does not return a value (it only ever returns None) 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: 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: 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: A | |
| bb: 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: A[int] | |
| a_s: 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: 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: 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 testClassObjectsNotUnpackableWithoutIterableMetaclass] | |
| from typing import Type | |
| class Foo: ... | |
| A: Type[Foo] = Foo | |
| a, b = Foo # E: "type[Foo]" object is not iterable | |
| c, d = A # E: "type[Foo]" object is not iterable | |
| class Meta(type): ... | |
| class Bar(metaclass=Meta): ... | |
| B: Type[Bar] = Bar | |
| e, f = Bar # E: "type[Bar]" object is not iterable | |
| g, h = B # E: "type[Bar]" object is not iterable | |
| reveal_type(a) # E: Cannot determine type of "a" # N: Revealed type is "Any" | |
| reveal_type(b) # E: Cannot determine type of "b" # N: Revealed type is "Any" | |
| reveal_type(c) # E: Cannot determine type of "c" # N: Revealed type is "Any" | |
| reveal_type(d) # E: Cannot determine type of "d" # N: Revealed type is "Any" | |
| reveal_type(e) # E: Cannot determine type of "e" # N: Revealed type is "Any" | |
| reveal_type(f) # E: Cannot determine type of "f" # N: Revealed type is "Any" | |
| reveal_type(g) # E: Cannot determine type of "g" # N: Revealed type is "Any" | |
| reveal_type(h) # E: Cannot determine type of "h" # N: Revealed type is "Any" | |
| [out] | |
| [case testInferringLvarTypesUnpackedFromIterableClassObject] | |
| from typing import Iterator, Type, TypeVar, Union, overload | |
| class Meta(type): | |
| def __iter__(cls) -> Iterator[int]: | |
| yield from [1, 2, 3] | |
| class Meta2(type): | |
| def __iter__(cls) -> Iterator[str]: | |
| yield from ["foo", "bar", "baz"] | |
| class Meta3(type): ... | |
| class Foo(metaclass=Meta): ... | |
| class Bar(metaclass=Meta2): ... | |
| class Baz(metaclass=Meta3): ... | |
| class Spam: ... | |
| class Eggs(metaclass=Meta): | |
| @overload | |
| def __init__(self, x: int) -> None: ... | |
| @overload | |
| def __init__(self, x: int, y: int, z: int) -> None: ... | |
| def __init__(self, x: int, y: int = ..., z: int = ...) -> None: ... | |
| A: Type[Foo] = Foo | |
| B: Type[Union[Foo, Bar]] = Foo | |
| C: Union[Type[Foo], Type[Bar]] = Foo | |
| D: Type[Union[Foo, Baz]] = Foo | |
| E: Type[Union[Foo, Spam]] = Foo | |
| F: Type[Eggs] = Eggs | |
| G: Type[Union[Foo, Eggs]] = Foo | |
| a, b, c = Foo | |
| d, e, f = A | |
| g, h, i = B | |
| j, k, l = C | |
| m, n, o = D # E: "type[Baz]" object is not iterable | |
| p, q, r = E # E: "type[Spam]" object is not iterable | |
| s, t, u = Eggs | |
| v, w, x = F | |
| y, z, aa = G | |
| for var in [a, b, c, d, e, f, s, t, u, v, w, x, y, z, aa]: | |
| reveal_type(var) # N: Revealed type is "builtins.int" | |
| for var2 in [g, h, i, j, k, l]: | |
| reveal_type(var2) # N: Revealed type is "builtins.int | builtins.str" | |
| for var3 in [m, n, o, p, q, r]: | |
| reveal_type(var3) # N: Revealed type is "builtins.int | Any" | |
| T = TypeVar("T", bound=Type[Foo]) | |
| def check(x: T) -> T: | |
| a, b, c = x | |
| for var in [a, b, c]: | |
| reveal_type(var) # N: Revealed type is "builtins.int" | |
| return x | |
| T2 = TypeVar("T2", bound=Type[Union[Foo, Bar]]) | |
| def check2(x: T2) -> T2: | |
| a, b, c = x | |
| for var in [a, b, c]: | |
| reveal_type(var) # N: Revealed type is "builtins.int | builtins.str" | |
| return x | |
| T3 = TypeVar("T3", bound=Union[Type[Foo], Type[Bar]]) | |
| def check3(x: T3) -> T3: | |
| a, b, c = x | |
| for var in [a, b, c]: | |
| reveal_type(var) # N: Revealed type is "builtins.int | builtins.str" | |
| return x | |
| [out] | |
| [case testInferringLvarTypesUnpackedFromIterableClassObjectWithGenericIter] | |
| from typing import Iterator, Type, TypeVar | |
| T = TypeVar("T") | |
| class Meta(type): | |
| def __iter__(self: Type[T]) -> Iterator[T]: ... | |
| class Foo(metaclass=Meta): ... | |
| A, B, C = Foo | |
| reveal_type(A) # N: Revealed type is "__main__.Foo" | |
| reveal_type(B) # N: Revealed type is "__main__.Foo" | |
| reveal_type(C) # N: Revealed type is "__main__.Foo" | |
| [out] | |
| [case testInferringLvarTypesInMultiDefWithInvalidTuple] | |
| from typing import Tuple | |
| t: 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() | |
| reveal_type(a) # N: Revealed type is "builtins.int" | |
| reveal_type(b) # N: Revealed type is "builtins.int" | |
| 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] | |
| [case testInferringTypesFromIterableStructuralSubtyping1] | |
| from typing import Iterator | |
| class Nums: | |
| def __iter__(self) -> Iterator[int]: pass | |
| a, b = Nums() | |
| reveal_type(a) # N: Revealed type is "builtins.int" | |
| reveal_type(b) # N: Revealed type is "builtins.int" | |
| 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] | |
| [case testInferringTypesFromIterableStructuralSubtyping2] | |
| from typing import Self | |
| class Nums: | |
| def __iter__(self) -> Self: pass | |
| def __next__(self) -> int: pass | |
| a, b = Nums() | |
| reveal_type(a) # N: Revealed type is "builtins.int" | |
| reveal_type(b) # N: Revealed type is "builtins.int" | |
| 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/tuple.pyi] | |
| -- Type variable inference for generic functions | |
| -- --------------------------------------------- | |
| [case testInferSimpleGenericFunction] | |
| from typing import Tuple, TypeVar | |
| T = TypeVar('T') | |
| a: A | |
| b: B | |
| c: Tuple[A, object] | |
| def id(a: T) -> T: pass | |
| 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) | |
| 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: int | |
| c: 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: A | |
| def ff() -> None: | |
| x = f() # E: Need type annotation for "x" | |
| reveal_type(x) # N: Revealed type is "Any" | |
| 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 | |
| g(None) # Ok | |
| f() # Ok because not used to infer local variable type | |
| g(a) | |
| [out] | |
| [case testInferenceWithMultipleConstraints] | |
| from typing import TypeVar | |
| class A: pass | |
| class B(A): pass | |
| T = TypeVar('T') | |
| a: A | |
| b: B | |
| def f(a: T, b: T) -> T: pass | |
| 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) | |
| [case testInferenceWithMultipleVariables] | |
| from typing import Tuple, TypeVar | |
| T = TypeVar('T') | |
| S = TypeVar('S') | |
| def f(a: T, b: S) -> Tuple[T, S]: pass | |
| class A: pass | |
| class B: pass | |
| a: A | |
| b: B | |
| taa: Tuple[A, A] | |
| tab: Tuple[A, B] | |
| tba: 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) | |
| [builtins fixtures/tuple.pyi] | |
| [case testConstraintSolvingWithSimpleGenerics] | |
| from typing import TypeVar, Generic | |
| T = TypeVar('T') | |
| ao: A[object] | |
| ab: A[B] | |
| ac: A[C] | |
| 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 | |
| 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) | |
| [case testConstraintSolvingFailureWithSimpleGenerics] | |
| from typing import TypeVar, Generic | |
| T = TypeVar('T') | |
| ao: A[object] | |
| ab: A[B] | |
| def f(a: 'A[T]', b: 'A[T]') -> None: pass | |
| class A(Generic[T]): pass | |
| class B: pass | |
| f(ao, ab) # E: Cannot infer value of type parameter "T" of "f" | |
| f(ab, ao) # E: Cannot infer value of type parameter "T" of "f" | |
| f(ao, ao) | |
| f(ab, ab) | |
| [case testTypeInferenceWithCalleeDefaultArgs] | |
| # flags: --no-strict-optional | |
| from typing import TypeVar | |
| T = TypeVar('T') | |
| a = None # type: A | |
| o = None # type: object | |
| def f(a: T = None) -> T: pass | |
| def g(a: T, b: T = None) -> T: pass | |
| class A: pass | |
| 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) | |
| -- 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 | |
| class A: pass | |
| class B(A, I, J): pass | |
| class C(A, I, J): pass | |
| def f(a: T, b: T) -> T: pass | |
| T = TypeVar('T') | |
| a: A | |
| i: I | |
| j: J | |
| a = f(B(), C()) | |
| class I(metaclass=ABCMeta): pass | |
| class J(metaclass=ABCMeta): 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: 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 = Never. 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[Never]" | |
| 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] | |
| 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[Never]", variable has type "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@k1]], list[T@k1 | int]]", variable has type "Callable[[S, list[T@k2]], list[T@k2 | 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: A | |
| b: 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: int | |
| x: 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 "def f(*, x: int) -> int"; expected "def g(*, y: int) -> int" | |
| list_2 = [f, h] | |
| [builtins fixtures/list.pyi] | |
| -- For statements | |
| -- -------------- | |
| [case testInferenceOfFor1] | |
| a: A | |
| b: B | |
| class A: pass | |
| class B: pass | |
| 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" | |
| [builtins fixtures/for.pyi] | |
| [case testInferenceOfFor2] | |
| class A: pass | |
| class B: pass | |
| class C: pass | |
| a: A | |
| b: B | |
| c: C | |
| for x, (y, z) in [(A(), (B(), C()))]: | |
| b = x # E: Incompatible types in assignment (expression has type "A", variable has type "B") | |
| c = y # E: Incompatible types in assignment (expression has type "B", variable has type "C") | |
| a = z # E: Incompatible types in assignment (expression has type "C", variable has type "A") | |
| a = x | |
| b = y | |
| c = z | |
| for xx, yy, zz in [(A(), B())]: # E: Need more than 2 values to unpack (3 expected) | |
| pass | |
| for xx, (yy, zz) in [(A(), B())]: # E: "B" object is not iterable | |
| pass | |
| for xxx, yyy in [(1, 2)]: | |
| pass | |
| [builtins fixtures/for.pyi] | |
| [case testInferenceOfFor3] | |
| class A: pass | |
| class B: pass | |
| a: A | |
| b: 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" | |
| [builtins fixtures/for.pyi] | |
| [case testForStatementInferenceWithVoid] | |
| def f() -> None: pass | |
| for x in f(): # E: "f" does not return a value (it only ever returns None) \ | |
| # E: "None" has no attribute "__iter__" (not iterable) | |
| pass | |
| [builtins fixtures/for.pyi] | |
| [case testReusingInferredForIndex] | |
| import typing | |
| class A: pass | |
| class B: pass | |
| 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") | |
| [builtins fixtures/for.pyi] | |
| [case testReusingInferredForIndex2] | |
| # flags: --allow-redefinition-old | |
| 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-old | |
| 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] | |
| [case testForStatementIndexNarrowing] | |
| from typing import TypedDict | |
| class X(TypedDict): | |
| hourly: int | |
| daily: int | |
| x: X | |
| for a in ("hourly", "daily"): | |
| reveal_type(a) # N: Revealed type is "Literal['hourly']? | Literal['daily']?" | |
| reveal_type(x[a]) # N: Revealed type is "builtins.int" | |
| reveal_type(a.upper()) # N: Revealed type is "builtins.str" | |
| c = a | |
| reveal_type(c) # N: Revealed type is "builtins.str" | |
| a = "monthly" | |
| reveal_type(a) # N: Revealed type is "builtins.str" | |
| a = "yearly" | |
| reveal_type(a) # N: Revealed type is "builtins.str" | |
| a = 1 # E: Incompatible types in assignment (expression has type "int", variable has type "str") | |
| reveal_type(a) # N: Revealed type is "builtins.str" | |
| d = a | |
| reveal_type(d) # N: Revealed type is "builtins.str" | |
| b: str | |
| for b in ("hourly", "daily"): | |
| reveal_type(b) # N: Revealed type is "builtins.str" | |
| reveal_type(b.upper()) # N: Revealed type is "builtins.str" | |
| [builtins fixtures/for.pyi] | |
| [typing fixtures/typing-full.pyi] | |
| -- Regression tests | |
| -- ---------------- | |
| [case testMultipleAssignmentWithPartialDefinition] | |
| a: 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: 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: 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] | |
| class A: pass | |
| class B: pass | |
| if int(): | |
| a = A() | |
| if int(): | |
| a = A() | |
| if int(): | |
| a = B() # E: Incompatible types in assignment (expression has type "B", variable has type "A") | |
| [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: Need type annotation for "y" | |
| [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) # E: Need type annotation for "y" \ | |
| # E: Argument 2 to "f" has incompatible type "int"; expected "str" | |
| [case testInferLambdaNone] | |
| # flags: --no-strict-optional | |
| 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] | |
| 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 parameter "a" (default has type "def (*a: Any, **k: Any) -> int", parameter 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 | |
| [case testLambdaJoinWithDynamicConstructor] | |
| from typing import Any, Union | |
| class Wrapper: | |
| def __init__(self, x: Any) -> None: ... | |
| def f(cond: bool) -> Any: | |
| f = Wrapper if cond else lambda x: x | |
| reveal_type(f) # N: Revealed type is "(def (x: Any) -> __main__.Wrapper) | (def (x: Any) -> Any)" | |
| return f(3) | |
| def g(cond: bool) -> Any: | |
| f = lambda x: x if cond else Wrapper | |
| reveal_type(f) # N: Revealed type is "def (x: Any) -> Any | (def (x: Any) -> __main__.Wrapper)" | |
| return f(3) | |
| def h(cond: bool) -> Any: | |
| f = (lambda x: x) if cond else Wrapper | |
| reveal_type(f) # N: Revealed type is "(def (x: Any) -> Any) | (def (x: Any) -> __main__.Wrapper)" | |
| return f(3) | |
| -- Boolean operators | |
| -- ----------------- | |
| [case testOrOperationWithGenericOperands] | |
| from typing import List | |
| a: List[A] | |
| o: 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" # E: Name "x" is used before definition | |
| x = object() | |
| x.y # E: "object" has no attribute "y" | |
| [case testAccessDataAttributeBeforeItsTypeIsAvailable] | |
| a: 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: 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: 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 testInferListInitializedToEmptyInClassBodyAndOverridden] | |
| 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): | |
| @property | |
| def x(self) -> List[int]: # E: Cannot override writeable attribute with read-only property | |
| 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 "SupportsKeysAndGetItem[Any, Any]" \ | |
| # N: "list" is missing following "SupportsKeysAndGetItem" protocol member: \ | |
| # N: keys | |
| 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] | |
| -- Parallel mode does not support --no-local-partial-types | |
| [case testInferDictInitializedToEmptyAndUpdatedFromMethod_no_parallel] | |
| # flags: --no-local-partial-types | |
| map = {} | |
| def add() -> None: | |
| map[1] = 2 | |
| [builtins fixtures/dict.pyi] | |
| -- Parallel mode does not support --no-local-partial-types | |
| [case testInferDictInitializedToEmptyAndUpdatedFromMethodUnannotated_no_parallel] | |
| # flags: --no-local-partial-types | |
| 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] list() -> list[T] \ | |
| # N: def [T] list(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] | |
| class C: | |
| def __init__(self) -> None: | |
| self.a = None | |
| if bool(): | |
| self.a = 1 | |
| reveal_type(C().a) # N: Revealed type is "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] | |
| 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] | |
| class C: | |
| a = None | |
| def __init__(self) -> None: | |
| self.a = 1 | |
| reveal_type(C().a) # N: Revealed type is "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] | |
| # flags: --no-strict-optional | |
| 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 testNoWrongUnreachableWarningWithNoStrictOptionalAndFinalInstance] | |
| # flags: --no-strict-optional --warn-unreachable | |
| from typing import final, Optional | |
| @final | |
| class C: ... | |
| x: Optional[C] | |
| if not x: | |
| x = C() | |
| [builtins fixtures/dict.pyi] | |
| [case testNoWrongUnreachableWarningWithNoStrictOptionalAndEnumLiteral] | |
| # flags: --no-strict-optional --warn-unreachable | |
| from enum import Enum | |
| from typing import Literal, Optional | |
| class E(Enum): | |
| a = 1 | |
| x: Optional[Literal[E.a]] | |
| if not x: | |
| x = E.a | |
| [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] | |
| # flags: --no-strict-optional | |
| 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 \ | |
| # E: "None" not callable | |
| [out] | |
| [case testLocalVariablePartiallyTwiceInitializedToNone] | |
| def f() -> None: | |
| if object(): | |
| x = None | |
| elif object(): | |
| x = None | |
| else: | |
| x = 1 | |
| x() # E: "int" not callable \ | |
| # E: "None" 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 \ | |
| # E: "None" 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() -> None: | |
| global a | |
| a = 42 | |
| reveal_type(a) # N: Revealed type is "builtins.int" | |
| reveal_type(a) # N: Revealed type is "builtins.int | None" | |
| b = None | |
| def unchecked(): | |
| global b | |
| b = 42 | |
| reveal_type(b) # N: Revealed type is "Any | None" | |
| [case testGlobalInitializedToNoneSetFromMethod] | |
| a = None | |
| class C: | |
| def m(self) -> None: | |
| global a | |
| a = 42 | |
| reveal_type(a) # N: Revealed type is "builtins.int | None" | |
| b = None | |
| class CC: | |
| def unchecked(self): | |
| global b | |
| b = 42 | |
| reveal_type(b) # N: Revealed type is "Any | None" | |
| [case testPartialTypeErrorSpecialCase1] | |
| # This used to crash. | |
| class A: | |
| x = None | |
| def f(self) -> None: | |
| for a in self.x: # E: "None" has no attribute "__iter__" (not iterable) | |
| pass | |
| [builtins fixtures/for.pyi] | |
| [case testPartialTypeErrorSpecialCase2] | |
| # This used to crash. | |
| class A: | |
| x = [] # E: Need type annotation for "x" (hint: "x: list[<type>] = ...") | |
| def f(self) -> None: | |
| for a in self.x: | |
| pass | |
| [builtins fixtures/for.pyi] | |
| [case testPartialTypeErrorSpecialCase3] | |
| class A: | |
| x = None | |
| def f(self) -> None: | |
| for a in A.x: # E: "None" has no attribute "__iter__" (not iterable) | |
| pass | |
| [builtins fixtures/for.pyi] | |
| [case testPartialTypeErrorSpecialCase4] | |
| # This used to crash. | |
| arr = [] | |
| arr.append(arr.append(1)) | |
| [builtins fixtures/list.pyi] | |
| [out] | |
| main:3: error: "append" of "list" does not return a value (it only ever returns None) | |
| main:3: error: Argument 1 to "append" of "list" has incompatible type "None"; expected "int" | |
| -- 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" # E: Name "x" is used before definition | |
| y() | |
| x = 1+int() | |
| [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() # E: "int" not callable | |
| x = 0 | |
| [file m.py] | |
| def g() -> None: | |
| y() # E: "int" not callable | |
| y = 0 | |
| [case testForwardReferenceToDecoratedClassMethod] | |
| from typing import TypeVar, Callable | |
| T = TypeVar('T') | |
| def dec() -> Callable[[T], T]: pass | |
| A.g # E: Cannot determine type of "g" # E: Name "A" is used before definition | |
| 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: Union[int, str] | |
| b: 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 "int | str | tuple[Any, ...]"; expected "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[T]]") | |
| 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] | |
| [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] | |
| [case testNoCrashOnPartialVariable2] | |
| from typing import Tuple, TypeVar | |
| T = TypeVar('T', bound=str) | |
| def f() -> Tuple[T]: | |
| ... | |
| x = None # E: Need type annotation for "x" | |
| if int(): | |
| (x,) = f() | |
| [builtins fixtures/tuple.pyi] | |
| [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] | |
| [case testRejectsPartialWithUninhabited] | |
| from typing import Generic, TypeVar | |
| T = TypeVar('T') | |
| class Foo(Generic[T]): ... | |
| def check() -> None: | |
| x = None # E: Need type annotation for "x" | |
| if int(): | |
| x = Foo() | |
| reveal_type(x) # N: Revealed type is "__main__.Foo[Any]" | |
| reveal_type(x) # N: Revealed type is "__main__.Foo[Any] | None" | |
| [case testRejectsPartialWithUninhabited2] | |
| from typing import Generic, TypeVar | |
| T = TypeVar('T') | |
| class Foo(Generic[T]): ... | |
| x = None # E: Need type annotation for "x" | |
| def check() -> None: | |
| global x | |
| x = Foo() | |
| reveal_type(x) # N: Revealed type is "__main__.Foo[Any]" | |
| reveal_type(x) # N: Revealed type is "__main__.Foo[Any] | None" | |
| [case testRejectsPartialWithUninhabited3] | |
| # Without force-rejecting Partial<None>, this crashes: | |
| # https://github.com/python/mypy/issues/16573 | |
| from typing import Generic, TypeVar | |
| T = TypeVar('T') | |
| class Foo(Generic[T]): ... | |
| def check() -> None: | |
| client = None # E: Need type annotation for "client" | |
| if client := Foo(): | |
| reveal_type(client) # N: Revealed type is "__main__.Foo[Any]" | |
| reveal_type(client) # N: Revealed type is "__main__.Foo[Any] | None" | |
| client = 0 # E: Incompatible types in assignment (expression has type "int", variable has type "Foo[Any] | None") | |
| reveal_type(client) # N: Revealed type is "__main__.Foo[Any] | None" | |
| [case testRejectsPartialWithUninhabitedIndependently] | |
| from typing import Generic, TypeVar | |
| T = TypeVar('T') | |
| class Foo(Generic[T]): ... | |
| client = None # E: Need type annotation for "client" | |
| def bad() -> None: | |
| global client | |
| client = Foo() | |
| reveal_type(client) # N: Revealed type is "__main__.Foo[Any]" | |
| def good() -> None: | |
| global client | |
| client = 1 # E: Incompatible types in assignment (expression has type "int", variable has type "Foo[Any] | None") | |
| reveal_type(client) # N: Revealed type is "__main__.Foo[Any] | None" | |
| def bad2() -> None: | |
| global client | |
| client = Foo() | |
| reveal_type(client) # N: Revealed type is "__main__.Foo[Any]" | |
| [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] | |
| [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] | |
| 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 | |
| def f() -> None: | |
| global x | |
| x = 1 | |
| reveal_type(x) # N: Revealed type is "builtins.int | None" | |
| [case testLocalPartialTypesWithGlobalInitializedToNone2] | |
| # flags: --local-partial-types | |
| x = None | |
| def f(): | |
| global x | |
| x = 1 | |
| reveal_type(x) # N: Revealed type is "Any | None" | |
| [case testLocalPartialTypesWithGlobalInitializedToNone3] | |
| # flags: --local-partial-types --no-strict-optional | |
| x = None | |
| def f() -> None: | |
| global x | |
| x = 1 | |
| x = '' # E: Incompatible types in assignment (expression has type "str", variable has type "int") | |
| reveal_type(x) # N: Revealed type is "builtins.int" | |
| [case testLocalPartialTypesWithGlobalInitializedToNoneStrictOptional] | |
| # flags: --local-partial-types | |
| x = None | |
| def f() -> None: | |
| global x | |
| x = 1 | |
| x = '' # E: Incompatible types in assignment (expression has type "str", variable has type "int | None") | |
| def g() -> None: | |
| reveal_type(x) # N: Revealed type is "builtins.int | None" | |
| [case testLocalPartialTypesWithGlobalInitializedToNone4] | |
| # flags: --local-partial-types --no-strict-optional | |
| a = None | |
| def f() -> None: | |
| reveal_type(a) # N: Revealed type is "builtins.str" | |
| reveal_type(a) # N: Revealed type is "None" | |
| a = '' | |
| reveal_type(a) # N: Revealed type is "builtins.str" | |
| [builtins fixtures/list.pyi] | |
| [case testLocalPartialTypesWithGlobalInitializedToNone5] | |
| # flags: --local-partial-types | |
| a = None | |
| def f() -> None: | |
| reveal_type(a) # N: Revealed type is "builtins.str | None" | |
| 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 | |
| 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 | |
| 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 | |
| from typing import Any | |
| A: Any | |
| class B(A): | |
| x = None | |
| class C(B): | |
| y = None | |
| [case testLocalPartialTypesInMultipleMroItems] | |
| # flags: --local-partial-types | |
| 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 "__main__.Y | None" | |
| [case testLocalPartialTypesBinderSpecialCase] | |
| # flags: --local-partial-types | |
| from typing import List | |
| def f(x): pass | |
| class A: | |
| x = None | |
| 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 | |
| def f(self, x) -> None: | |
| C.a.y # E: "None" has no attribute "y" | |
| [case testLocalPartialTypesAccessPartialNoneAttribute2] | |
| # flags: --local-partial-types | |
| class C: | |
| a = None | |
| def f(self, x) -> None: | |
| self.a.y # E: "None" has no attribute "y" | |
| [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-old | |
| class C: | |
| _, _ = 0, 0 | |
| _ = '' | |
| reveal_type(C._) # N: Revealed type is "builtins.str" | |
| [case testUnusedTargetNotClass2] | |
| # flags: --disallow-redefinition-old | |
| 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 "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] | |
| 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) -> Never" | |
| [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 | |
| class A: ... | |
| class B(A): ... | |
| T = TypeVar('T', bound=A) | |
| class Z(Generic[T]): | |
| def __init__(self, y: T) -> None: | |
| self.y = y | |
| 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] | |
| 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] | |
| 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] | |
| 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] | |
| # 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 "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 testAllowPlainNoneForPartialAtModuleScope] | |
| # flags: --local-partial-types | |
| x = None | |
| reveal_type(x) # N: Revealed type is "None" | |
| [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 testUseSupertypeAsInferenceContext] | |
| from typing import List, Optional | |
| class B: | |
| x: List[Optional[int]] | |
| class C(B): | |
| x = [1] | |
| reveal_type(C().x) # N: Revealed type is "builtins.list[builtins.int | None]" | |
| [builtins fixtures/list.pyi] | |
| [case testUseSupertypeAsInferenceContextInvalidType] | |
| from typing import List | |
| class P: | |
| x: List[int] | |
| class C(P): | |
| x = ['a'] # E: List item 0 has incompatible type "str"; expected "int" | |
| [builtins fixtures/list.pyi] | |
| [case testUseSupertypeAsInferenceContextPartial] | |
| from typing import List | |
| class A: | |
| x: List[str] | |
| class B(A): | |
| x = [] | |
| reveal_type(B().x) # N: Revealed type is "builtins.list[builtins.str]" | |
| [builtins fixtures/list.pyi] | |
| [case testUseSupertypeAsInferenceContextPartialError] | |
| class A: | |
| x = ['a', 'b'] | |
| class B(A): | |
| x = [] | |
| x.append(2) # E: Argument 1 to "append" of "list" has incompatible type "int"; expected "str" | |
| [builtins fixtures/list.pyi] | |
| [case testUseSupertypeAsInferenceContextPartialErrorProperty] | |
| from typing import List | |
| class P: | |
| @property | |
| def x(self) -> List[int]: ... | |
| class C(P): | |
| x = [] | |
| C.x.append("no") # E: Argument 1 to "append" of "list" has incompatible type "str"; expected "int" | |
| [builtins fixtures/list.pyi] | |
| [case testUseSupertypeAsInferenceContextConflict] | |
| from typing import List | |
| class P: | |
| x: List[int] | |
| class M: | |
| x: List[str] | |
| class C(P, M): | |
| x = [] # E: Need type annotation for "x" (hint: "x: list[<type>] = ...") | |
| reveal_type(C.x) # N: Revealed type is "builtins.list[Any]" | |
| [builtins fixtures/list.pyi] | |
| [case testNoPartialInSupertypeAsContext] | |
| class A: | |
| args = {} # E: Need type annotation for "args" (hint: "args: dict[<type>, <type>] = ...") | |
| def f(self) -> None: | |
| value = {1: "Hello"} | |
| class B(A): | |
| args = value | |
| [builtins fixtures/dict.pyi] | |
| [case testInferSimpleLiteralInClassBodyCycle] | |
| import a | |
| [file a.py] | |
| import b | |
| reveal_type(b.B.x) # N: Revealed type is "builtins.int" | |
| class A: | |
| x = 42 | |
| [file b.py] | |
| import a | |
| reveal_type(a.A.x) # N: Revealed type is "builtins.int" | |
| class B: | |
| x = 42 | |
| [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" | |
| [case testUpperBoundAsInferenceFallback] | |
| from typing import Callable, TypeVar, Any, Mapping, Optional | |
| T = TypeVar("T", bound=Mapping[str, Any]) | |
| def raises(opts: Optional[T]) -> T: pass | |
| def assertRaises(cb: Callable[..., object]) -> None: pass | |
| assertRaises(raises) # OK | |
| [builtins fixtures/dict.pyi] | |
| [case testJoinWithAnyFallback] | |
| from unknown import X # type: ignore[import] | |
| class A: ... | |
| class B(X, A): ... | |
| class C(B): ... | |
| class D(C): ... | |
| class E(D): ... | |
| reveal_type([E(), D()]) # N: Revealed type is "builtins.list[__main__.D]" | |
| reveal_type([D(), E()]) # N: Revealed type is "builtins.list[__main__.D]" | |
| [case testCallableInferenceAgainstCallablePosVsStar] | |
| from typing import TypeVar, Callable, Tuple | |
| T = TypeVar('T') | |
| S = TypeVar('S') | |
| def f(x: Callable[[T, S], None]) -> Tuple[T, S]: ... | |
| def g(*x: int) -> None: ... | |
| reveal_type(f(g)) # N: Revealed type is "tuple[builtins.int, builtins.int]" | |
| [builtins fixtures/list.pyi] | |
| [case testCallableInferenceAgainstCallableStarVsPos] | |
| from typing import TypeVar, Callable, Tuple, Protocol | |
| T = TypeVar('T', contravariant=True) | |
| S = TypeVar('S', contravariant=True) | |
| class Call(Protocol[T, S]): | |
| def __call__(self, __x: T, *args: S) -> None: ... | |
| def f(x: Call[T, S]) -> Tuple[T, S]: ... | |
| def g(*x: int) -> None: ... | |
| reveal_type(f(g)) # N: Revealed type is "tuple[builtins.int, builtins.int]" | |
| [builtins fixtures/list.pyi] | |
| [case testCallableInferenceAgainstCallableNamedVsStar] | |
| from typing import TypeVar, Callable, Tuple, Protocol | |
| T = TypeVar('T', contravariant=True) | |
| S = TypeVar('S', contravariant=True) | |
| class Call(Protocol[T, S]): | |
| def __call__(self, *, x: T, y: S) -> None: ... | |
| def f(x: Call[T, S]) -> Tuple[T, S]: ... | |
| def g(**kwargs: int) -> None: ... | |
| reveal_type(f(g)) # N: Revealed type is "tuple[builtins.int, builtins.int]" | |
| [builtins fixtures/list.pyi] | |
| [case testCallableInferenceAgainstCallableStarVsNamed] | |
| from typing import TypeVar, Callable, Tuple, Protocol | |
| T = TypeVar('T', contravariant=True) | |
| S = TypeVar('S', contravariant=True) | |
| class Call(Protocol[T, S]): | |
| def __call__(self, *, x: T, **kwargs: S) -> None: ... | |
| def f(x: Call[T, S]) -> Tuple[T, S]: ... | |
| def g(**kwargs: int) -> None: pass | |
| reveal_type(f(g)) # N: Revealed type is "tuple[builtins.int, builtins.int]" | |
| [builtins fixtures/list.pyi] | |
| [case testCallableInferenceAgainstCallableNamedVsNamed] | |
| from typing import TypeVar, Callable, Tuple, Protocol | |
| T = TypeVar('T', contravariant=True) | |
| S = TypeVar('S', contravariant=True) | |
| class Call(Protocol[T, S]): | |
| def __call__(self, *, x: T, y: S) -> None: ... | |
| def f(x: Call[T, S]) -> Tuple[T, S]: ... | |
| # Note: order of names is different w.r.t. protocol | |
| def g(*, y: int, x: str) -> None: pass | |
| reveal_type(f(g)) # N: Revealed type is "tuple[builtins.str, builtins.int]" | |
| [builtins fixtures/list.pyi] | |
| [case testCallableInferenceAgainstCallablePosOnlyVsNamed] | |
| from typing import TypeVar, Callable, Tuple, Protocol | |
| T = TypeVar('T', contravariant=True) | |
| S = TypeVar('S', contravariant=True) | |
| class Call(Protocol[T]): | |
| def __call__(self, *, x: T) -> None: ... | |
| def f(x: Call[T]) -> Tuple[T, T]: ... | |
| def g(__x: str) -> None: pass | |
| reveal_type(f(g)) # N: Revealed type is "tuple[Never, Never]" \ | |
| # E: Argument 1 to "f" has incompatible type "Callable[[str], None]"; expected "Call[Never]" \ | |
| # N: "Call[Never].__call__" has type "def __call__(self, *, x: Never) -> None" | |
| [builtins fixtures/list.pyi] | |
| [case testCallableInferenceAgainstCallableNamedVsPosOnly] | |
| from typing import TypeVar, Callable, Tuple, Protocol | |
| T = TypeVar('T', contravariant=True) | |
| S = TypeVar('S', contravariant=True) | |
| class Call(Protocol[T]): | |
| def __call__(self, __x: T) -> None: ... | |
| def f(x: Call[T]) -> Tuple[T, T]: ... | |
| def g(*, x: str) -> None: pass | |
| reveal_type(f(g)) # N: Revealed type is "tuple[Never, Never]" \ | |
| # E: Argument 1 to "f" has incompatible type "def g(*, x: str) -> None"; expected "Call[Never]" \ | |
| # N: "Call[Never].__call__" has type "Callable[[Never], None]" | |
| [builtins fixtures/list.pyi] | |
| [case testCallableInferenceAgainstCallablePosOnlyVsKwargs] | |
| from typing import TypeVar, Callable, Tuple, Protocol | |
| T = TypeVar('T', contravariant=True) | |
| S = TypeVar('S', contravariant=True) | |
| class Call(Protocol[T]): | |
| def __call__(self, __x: T) -> None: ... | |
| def f(x: Call[T]) -> Tuple[T, T]: ... | |
| def g(**x: str) -> None: pass | |
| reveal_type(f(g)) # N: Revealed type is "tuple[Never, Never]" \ | |
| # E: Argument 1 to "f" has incompatible type "def g(**x: str) -> None"; expected "Call[Never]" \ | |
| # N: "Call[Never].__call__" has type "Callable[[Never], None]" | |
| [builtins fixtures/list.pyi] | |
| [case testCallableInferenceAgainstCallableNamedVsArgs] | |
| from typing import TypeVar, Callable, Tuple, Protocol | |
| T = TypeVar('T', contravariant=True) | |
| S = TypeVar('S', contravariant=True) | |
| class Call(Protocol[T]): | |
| def __call__(self, *, x: T) -> None: ... | |
| def f(x: Call[T]) -> Tuple[T, T]: ... | |
| def g(*args: str) -> None: pass | |
| reveal_type(f(g)) # N: Revealed type is "tuple[Never, Never]" \ | |
| # E: Argument 1 to "f" has incompatible type "def g(*args: str) -> None"; expected "Call[Never]" \ | |
| # N: "Call[Never].__call__" has type "def __call__(self, *, x: Never) -> None" | |
| [builtins fixtures/list.pyi] | |
| [case testInferenceAgainstTypeVarActualBound] | |
| from typing import Callable, TypeVar | |
| T = TypeVar("T") | |
| S = TypeVar("S") | |
| def test(f: Callable[[T], S]) -> Callable[[T], S]: ... | |
| F = TypeVar("F", bound=Callable[..., object]) | |
| def dec(f: F) -> F: | |
| reveal_type(test(f)) # N: Revealed type is "def (Any) -> builtins.object" | |
| return f | |
| [case testInferenceAgainstTypeVarActualUnionBound] | |
| from typing import Protocol, TypeVar, Union | |
| T_co = TypeVar("T_co", covariant=True) | |
| class SupportsFoo(Protocol[T_co]): | |
| def foo(self) -> T_co: ... | |
| class A: | |
| def foo(self) -> A: ... | |
| class B: | |
| def foo(self) -> B: ... | |
| def foo(f: SupportsFoo[T_co]) -> T_co: ... | |
| ABT = TypeVar("ABT", bound=Union[A, B]) | |
| def simpler(k: ABT): | |
| foo(k) | |
| [case testInferenceWorksWithEmptyCollectionsNested] | |
| from typing import List, TypeVar, NoReturn | |
| T = TypeVar('T') | |
| def f(a: List[T], b: List[T]) -> T: pass | |
| x = ["yes"] | |
| reveal_type(f(x, [])) # N: Revealed type is "builtins.str" | |
| reveal_type(f(["yes"], [])) # N: Revealed type is "builtins.str" | |
| empty: List[NoReturn] | |
| f(x, empty) # E: Cannot infer value of type parameter "T" of "f" | |
| f(["no"], empty) # E: Cannot infer value of type parameter "T" of "f" | |
| [builtins fixtures/list.pyi] | |
| [case testInferenceWorksWithEmptyCollectionsUnion] | |
| from typing import Any, Dict, NoReturn, NoReturn, Union | |
| def foo() -> Union[Dict[str, Any], Dict[int, Any]]: | |
| return {} | |
| [builtins fixtures/dict.pyi] | |
| [case testExistingEmptyCollectionDoesNotUpcast] | |
| from typing import Any, Dict, NoReturn, NoReturn, Union | |
| empty: Dict[NoReturn, NoReturn] | |
| def foo() -> Dict[str, Any]: | |
| return empty # E: Incompatible return value type (got "dict[Never, Never]", expected "dict[str, Any]") | |
| def bar() -> Union[Dict[str, Any], Dict[int, Any]]: | |
| return empty # E: Incompatible return value type (got "dict[Never, Never]", expected "dict[str, Any] | dict[int, Any]") | |
| [builtins fixtures/dict.pyi] | |
| [case testUpperBoundInferenceFallbackNotOverused] | |
| from typing import TypeVar, Protocol, List | |
| S = TypeVar("S", covariant=True) | |
| class Foo(Protocol[S]): | |
| def foo(self) -> S: ... | |
| def foo(x: Foo[S]) -> S: ... | |
| T = TypeVar("T", bound="Base") | |
| class Base: | |
| def foo(self: T) -> T: ... | |
| class C(Base): | |
| pass | |
| def f(values: List[T]) -> T: ... | |
| x = foo(f([C()])) | |
| reveal_type(x) # N: Revealed type is "__main__.C" | |
| [builtins fixtures/list.pyi] | |
| [case testInferenceAgainstGenericCallableUnion] | |
| from typing import Callable, TypeVar, List, Union | |
| T = TypeVar("T") | |
| S = TypeVar("S") | |
| def dec(f: Callable[[S], T]) -> Callable[[S], List[T]]: ... | |
| @dec | |
| def func(arg: T) -> Union[T, str]: | |
| ... | |
| reveal_type(func) # N: Revealed type is "def [S] (S`1) -> builtins.list[S`1 | builtins.str]" | |
| reveal_type(func(42)) # N: Revealed type is "builtins.list[builtins.int | builtins.str]" | |
| def dec2(f: Callable[[S], List[T]]) -> Callable[[S], T]: ... | |
| @dec2 | |
| def func2(arg: T) -> List[Union[T, str]]: | |
| ... | |
| reveal_type(func2) # N: Revealed type is "def [S] (S`4) -> S`4 | builtins.str" | |
| reveal_type(func2(42)) # N: Revealed type is "builtins.int | builtins.str" | |
| [builtins fixtures/list.pyi] | |
| [case testInferenceAgainstGenericCallbackProtoMultiple] | |
| from typing import Callable, Protocol, TypeVar | |
| from typing_extensions import Concatenate, ParamSpec | |
| V_co = TypeVar("V_co", covariant=True) | |
| class Metric(Protocol[V_co]): | |
| def __call__(self) -> V_co: ... | |
| T = TypeVar("T") | |
| P = ParamSpec("P") | |
| def simple_metric(func: Callable[Concatenate[int, P], T]) -> Callable[P, T]: ... | |
| @simple_metric | |
| def Negate(count: int, /, metric: Metric[float]) -> float: ... | |
| @simple_metric | |
| def Combine(count: int, m1: Metric[T], m2: Metric[T], /, *more: Metric[T]) -> T: ... | |
| reveal_type(Negate) # N: Revealed type is "def (metric: __main__.Metric[builtins.float]) -> builtins.float" | |
| reveal_type(Combine) # N: Revealed type is "def [T] (def () -> T`5, def () -> T`5, *more: def () -> T`5) -> T`5" | |
| def m1() -> float: ... | |
| def m2() -> float: ... | |
| reveal_type(Combine(m1, m2)) # N: Revealed type is "builtins.float" | |
| [builtins fixtures/list.pyi] | |
| [case testInferenceWithUninhabitedType] | |
| from typing import Dict, Generic, List, Never, TypeVar | |
| T = TypeVar("T") | |
| class A(Generic[T]): ... | |
| class B(Dict[T, T]): ... | |
| def func1(a: A[T], b: T) -> T: ... | |
| def func2(a: T, b: A[T]) -> T: ... | |
| def a1(a: A[Dict[str, int]]) -> None: | |
| reveal_type(func1(a, {})) # N: Revealed type is "builtins.dict[builtins.str, builtins.int]" | |
| reveal_type(func2({}, a)) # N: Revealed type is "builtins.dict[builtins.str, builtins.int]" | |
| def a2(check: bool, a: B[str]) -> None: | |
| reveal_type(a if check else {}) # N: Revealed type is "builtins.dict[builtins.str, builtins.str]" | |
| def a3() -> None: | |
| a = {} # E: Need type annotation for "a" (hint: "a: dict[<type>, <type>] = ...") | |
| b = {1: {}} # E: Need type annotation for "b" | |
| c = {1: {}, 2: {"key": {}}} # E: Need type annotation for "c" | |
| reveal_type(a) # N: Revealed type is "builtins.dict[Any, Any]" | |
| reveal_type(b) # N: Revealed type is "builtins.dict[builtins.int, builtins.dict[Any, Any]]" | |
| reveal_type(c) # N: Revealed type is "builtins.dict[builtins.int, builtins.dict[builtins.str, builtins.dict[Any, Any]]]" | |
| def a4(x: List[str], y: List[Never]) -> None: | |
| z1 = [x, y] | |
| z2 = [y, x] | |
| reveal_type(z1) # N: Revealed type is "builtins.list[builtins.object]" | |
| reveal_type(z2) # N: Revealed type is "builtins.list[builtins.object]" | |
| z1[1].append("asdf") # E: "object" has no attribute "append" | |
| [builtins fixtures/dict.pyi] | |
| [case testDeterminismCommutativityWithJoinInvolvingProtocolBaseAndPromotableType] | |
| # flags: --python-version 3.11 | |
| # Regression test for https://github.com/python/mypy/issues/16979#issuecomment-1982246306 | |
| from __future__ import annotations | |
| from typing import Any, Generic, Protocol, TypeVar, overload, cast | |
| from typing_extensions import Never | |
| T = TypeVar("T") | |
| U = TypeVar("U") | |
| class _SupportsCompare(Protocol): | |
| def __lt__(self, other: Any, /) -> bool: | |
| return True | |
| class Comparable(_SupportsCompare): | |
| pass | |
| comparable: Comparable = Comparable() | |
| from typing import _promote | |
| class floatlike: | |
| def __lt__(self, other: floatlike, /) -> bool: ... | |
| @_promote(floatlike) | |
| class intlike: | |
| def __lt__(self, other: intlike, /) -> bool: ... | |
| class A(Generic[T, U]): | |
| @overload | |
| def __init__(self: A[T, T], a: T, b: T, /) -> None: ... # type: ignore[overload-overlap] | |
| @overload | |
| def __init__(self: A[T, U], a: T, b: U, /) -> Never: ... | |
| def __init__(self, *a) -> None: ... | |
| def join(a: T, b: T) -> T: ... | |
| reveal_type(join(intlike(), comparable)) # N: Revealed type is "__main__._SupportsCompare" | |
| reveal_type(join(comparable, intlike())) # N: Revealed type is "__main__._SupportsCompare" | |
| reveal_type(A(intlike(), comparable)) # N: Revealed type is "__main__.A[__main__._SupportsCompare, __main__._SupportsCompare]" | |
| reveal_type(A(comparable, intlike())) # N: Revealed type is "__main__.A[__main__._SupportsCompare, __main__._SupportsCompare]" | |
| [builtins fixtures/tuple.pyi] | |
| [typing fixtures/typing-medium.pyi] | |
| [case testTupleJoinFallbackInference] | |
| foo = [ | |
| (1, ("a", "b")), | |
| (2, []), | |
| ] | |
| reveal_type(foo) # N: Revealed type is "builtins.list[tuple[builtins.int, typing.Sequence[builtins.str]]]" | |
| [builtins fixtures/tuple.pyi] | |
| [case testForLoopIndexVaribaleNarrowing1] | |
| # flags: --local-partial-types | |
| from typing import Union | |
| x: Union[int, str] | |
| x = "abc" | |
| for x in list[int](): | |
| reveal_type(x) # N: Revealed type is "builtins.int" | |
| reveal_type(x) # N: Revealed type is "builtins.int | builtins.str" | |
| [case testForLoopIndexVaribaleNarrowing2] | |
| # flags: --enable-error-code=redundant-expr | |
| from typing import Union | |
| x: Union[int, str] | |
| x = "abc" | |
| for x in list[int](): | |
| reveal_type(x) # N: Revealed type is "builtins.int" | |
| reveal_type(x) # N: Revealed type is "builtins.int | builtins.str" | |
| [case testNarrowInFunctionDefer] | |
| from typing import Optional, Callable, TypeVar | |
| def top() -> None: | |
| x: Optional[int] | |
| assert x is not None | |
| def foo() -> None: | |
| defer() | |
| reveal_type(x) # N: Revealed type is "builtins.int" | |
| T = TypeVar("T") | |
| def deco(fn: Callable[[], T]) -> Callable[[], T]: ... | |
| @deco | |
| def defer() -> int: ... | |
| [case testDeferMethodOfNestedClass] | |
| from typing import Optional, Callable, TypeVar | |
| class Out: | |
| def meth(self) -> None: | |
| class In: | |
| def meth(self) -> None: | |
| reveal_type(defer()) # N: Revealed type is "builtins.int" | |
| T = TypeVar("T") | |
| def deco(fn: Callable[[], T]) -> Callable[[], T]: ... | |
| @deco | |
| def defer() -> int: ... | |
| [case testVariableDeferredWithNestedFunction] | |
| from typing import Callable, TypeVar | |
| T = TypeVar("T") | |
| def deco(fn: Callable[[], T]) -> Callable[[], T]: ... | |
| @deco | |
| def f() -> None: | |
| x = 1 | |
| f() # defer current node | |
| x = x | |
| def nested() -> None: | |
| ... | |
| # The type below should not be Any. | |
| reveal_type(x) # N: Revealed type is "builtins.int" | |
| [case testInferenceMappingTypeVarGet] | |
| from typing import Generic, TypeVar, Union | |
| _T = TypeVar("_T") | |
| _K = TypeVar("_K") | |
| _V = TypeVar("_V") | |
| class Mapping(Generic[_K, _V]): | |
| def get(self, key: _K, default: Union[_V, _T]) -> Union[_V, _T]: ... | |
| def check(mapping: Mapping[str, _T]) -> None: | |
| ok1 = mapping.get("", "") | |
| reveal_type(ok1) # N: Revealed type is "_T`-1 | builtins.str" | |
| ok2: Union[_T, str] = mapping.get("", "") | |
| [builtins fixtures/tuple.pyi] | |
| [case testInferWalrusAssignmentAttrInCondition] | |
| class Foo: | |
| def __init__(self, value: bool) -> None: | |
| self.value = value | |
| def check_and(maybe: bool) -> None: | |
| foo = None | |
| if maybe and (foo := Foo(True)).value: | |
| reveal_type(foo) # N: Revealed type is "__main__.Foo" | |
| else: | |
| reveal_type(foo) # N: Revealed type is "__main__.Foo | None" | |
| def check_and_nested(maybe: bool) -> None: | |
| foo = None | |
| bar = None | |
| baz = None | |
| if maybe and (foo := (bar := (baz := Foo(True)))).value: | |
| reveal_type(foo) # N: Revealed type is "__main__.Foo" | |
| reveal_type(bar) # N: Revealed type is "__main__.Foo" | |
| reveal_type(baz) # N: Revealed type is "__main__.Foo" | |
| else: | |
| reveal_type(foo) # N: Revealed type is "__main__.Foo | None" | |
| reveal_type(bar) # N: Revealed type is "__main__.Foo | None" | |
| reveal_type(baz) # N: Revealed type is "__main__.Foo | None" | |
| def check_or(maybe: bool) -> None: | |
| foo = None | |
| if maybe or (foo := Foo(True)).value: | |
| reveal_type(foo) # N: Revealed type is "__main__.Foo | None" | |
| else: | |
| reveal_type(foo) # N: Revealed type is "__main__.Foo" | |
| def check_or_nested(maybe: bool) -> None: | |
| foo = None | |
| bar = None | |
| baz = None | |
| if maybe and (foo := (bar := (baz := Foo(True)))).value: | |
| reveal_type(foo) # N: Revealed type is "__main__.Foo" | |
| reveal_type(bar) # N: Revealed type is "__main__.Foo" | |
| reveal_type(baz) # N: Revealed type is "__main__.Foo" | |
| else: | |
| reveal_type(foo) # N: Revealed type is "__main__.Foo | None" | |
| reveal_type(bar) # N: Revealed type is "__main__.Foo | None" | |
| reveal_type(baz) # N: Revealed type is "__main__.Foo | None" | |
| [case testInferWalrusAssignmentIndexInCondition] | |
| def check_and(maybe: bool) -> None: | |
| foo = None | |
| bar = None | |
| if maybe and (foo := [1])[(bar := 0)]: | |
| reveal_type(foo) # N: Revealed type is "builtins.list[builtins.int]" | |
| reveal_type(bar) # N: Revealed type is "builtins.int" | |
| else: | |
| reveal_type(foo) # N: Revealed type is "builtins.list[builtins.int] | None" | |
| reveal_type(bar) # N: Revealed type is "builtins.int | None" | |
| def check_and_nested(maybe: bool) -> None: | |
| foo = None | |
| bar = None | |
| baz = None | |
| if maybe and (foo := (bar := (baz := [1])))[0]: | |
| reveal_type(foo) # N: Revealed type is "builtins.list[builtins.int]" | |
| reveal_type(bar) # N: Revealed type is "builtins.list[builtins.int]" | |
| reveal_type(baz) # N: Revealed type is "builtins.list[builtins.int]" | |
| else: | |
| reveal_type(foo) # N: Revealed type is "builtins.list[builtins.int] | None" | |
| reveal_type(bar) # N: Revealed type is "builtins.list[builtins.int] | None" | |
| reveal_type(baz) # N: Revealed type is "builtins.list[builtins.int] | None" | |
| def check_or(maybe: bool) -> None: | |
| foo = None | |
| bar = None | |
| if maybe or (foo := [1])[(bar := 0)]: | |
| reveal_type(foo) # N: Revealed type is "builtins.list[builtins.int] | None" | |
| reveal_type(bar) # N: Revealed type is "builtins.int | None" | |
| else: | |
| reveal_type(foo) # N: Revealed type is "builtins.list[builtins.int]" | |
| reveal_type(bar) # N: Revealed type is "builtins.int" | |
| def check_or_nested(maybe: bool) -> None: | |
| foo = None | |
| bar = None | |
| baz = None | |
| if maybe or (foo := (bar := (baz := [1])))[0]: | |
| reveal_type(foo) # N: Revealed type is "builtins.list[builtins.int] | None" | |
| reveal_type(bar) # N: Revealed type is "builtins.list[builtins.int] | None" | |
| reveal_type(baz) # N: Revealed type is "builtins.list[builtins.int] | None" | |
| else: | |
| reveal_type(foo) # N: Revealed type is "builtins.list[builtins.int]" | |
| reveal_type(bar) # N: Revealed type is "builtins.list[builtins.int]" | |
| reveal_type(baz) # N: Revealed type is "builtins.list[builtins.int]" | |
| [case testInferOptionalAgainstAny] | |
| from typing import Any, Optional, TypeVar | |
| a: Any | |
| oa: Optional[Any] | |
| T = TypeVar("T") | |
| def f(x: Optional[T]) -> T: ... | |
| reveal_type(f(a)) # N: Revealed type is "Any" | |
| reveal_type(f(oa)) # N: Revealed type is "Any" | |
| [case testNoCrashOnPartialTypeAsContext] | |
| from typing import overload, TypeVar, Optional, Protocol | |
| T = TypeVar("T") | |
| class DbManager(Protocol): | |
| @overload | |
| def get(self, key: str) -> Optional[T]: | |
| pass | |
| @overload | |
| def get(self, key: str, default: T) -> T: | |
| pass | |
| class Foo: | |
| def __init__(self, db: DbManager, bar: bool) -> None: | |
| if bar: | |
| self.qux = db.get("qux") | |
| else: | |
| self.qux = {} # E: Need type annotation for "qux" (hint: "qux: dict[<type>, <type>] = ...") | |
| [builtins fixtures/dict.pyi] | |
| [case testConstraintSolvingFailureShowsCorrectArgument] | |
| from typing import Callable, TypeVar | |
| T1 = TypeVar('T1') | |
| T2 = TypeVar('T2') | |
| def foo( | |
| a: T1, | |
| b: T2, | |
| c: Callable[[T2], T2], | |
| ) -> tuple[T1, T2]: ... | |
| def bar(y: float) -> float: ... | |
| foo(1, None, bar) # E: Cannot infer value of type parameter "T2" of "foo" | |
| [builtins fixtures/tuple.pyi] | |
| [case testGlobalVariableNoneInitMultipleFuncs] | |
| x = None | |
| def f() -> None: | |
| global x | |
| reveal_type(x) # N: Revealed type is "None" | |
| x = 1 | |
| reveal_type(x) # N: Revealed type is "builtins.int" | |
| def g() -> None: | |
| global x | |
| reveal_type(x) # N: Revealed type is "builtins.int | None" | |
| x = "" # E: Incompatible types in assignment (expression has type "str", variable has type "int | None") | |
| reveal_type(x) # N: Revealed type is "builtins.int | None" | |
| reveal_type(x) # N: Revealed type is "builtins.int | None" | |
| [case testGlobalVariableNoneInitMultipleFuncsRedefine] | |
| # flags: --allow-redefinition | |
| # Widening None is supported, as a special case | |
| x = None | |
| def f() -> None: | |
| global x | |
| reveal_type(x) # N: Revealed type is "None" | |
| x = 1 | |
| reveal_type(x) # N: Revealed type is "builtins.int" | |
| def g() -> None: | |
| global x | |
| reveal_type(x) # N: Revealed type is "None | builtins.int" | |
| x = "" # E: Incompatible types in assignment (expression has type "str", variable has type "int | None") | |
| reveal_type(x) # N: Revealed type is "None | builtins.int" | |
| [case testLocalPartialTypesWithGlobalInitializedToEmptyListAndRedefine1] | |
| # flags: --allow-redefinition | |
| 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]" | |
| [builtins fixtures/list.pyi] | |
| [case testLocalPartialTypesWithGlobalInitializedToEmptyListAndRedefine2] | |
| # flags: --allow-redefinition | |
| x = [] # E: Need type annotation for "x" (hint: "x: list[<type>] = ...") | |
| # This used to crash. | |
| def f() -> None: | |
| global x | |
| x | |
| [case testPerFileNoLocalPartialTypesForcesSinglePhase_no_parallel] | |
| # mypy: no-local-partial-types | |
| x = [] | |
| def func() -> None: | |
| x.append(1) | |
| reveal_type(x) # N: Revealed type is "builtins.list[builtins.int]" | |
| [builtins fixtures/list.pyi] | |
| [case testPerFileNoLocalPartialTypesForcesSinglePhase_parallel_only] | |
| # mypy: no-local-partial-types | |
| x = [] | |
| def func() -> None: | |
| x.append(1) | |
| [builtins fixtures/list.pyi] | |
| [out] | |
| main:1: error: --local-partial-types must be enabled in parallel mode | |
| main:3: error: Need type annotation for "x" (hint: "x: list[<type>] = ...") |