| |
| |
| -- Basic test cases |
| -- ---------------- |
| |
| |
| [case testBasicContextInference] |
| from typing import TypeVar, Generic |
| T = TypeVar('T') |
| ab = None # type: A[B] |
| ao = None # type: A[object] |
| b = None # type: B |
| |
| if int(): |
| ao = f() |
| if int(): |
| ab = f() |
| if int(): |
| b = f() # E: Incompatible types in assignment (expression has type "A[<nothing>]", variable has type "B") |
| |
| def f() -> 'A[T]': pass |
| |
| class A(Generic[T]): pass |
| class B: pass |
| |
| [case testBasicContextInferenceForConstructor] |
| from typing import TypeVar, Generic |
| T = TypeVar('T') |
| ab = None # type: A[B] |
| ao = None # type: A[object] |
| b = None # type: B |
| |
| if int(): |
| ao = A() |
| if int(): |
| ab = A() |
| if int(): |
| b = A() # E: Incompatible types in assignment (expression has type "A[<nothing>]", variable has type "B") |
| |
| class A(Generic[T]): pass |
| class B: pass |
| |
| [case testIncompatibleContextInference] |
| from typing import TypeVar, Generic |
| T = TypeVar('T') |
| b = None # type: B |
| c = None # type: C |
| ab = None # type: A[B] |
| ao = None # type: A[object] |
| ac = None # type: A[C] |
| |
| if int(): |
| ac = f(b) # E: Argument 1 to "f" has incompatible type "B"; expected "C" |
| if int(): |
| ab = f(c) # E: Argument 1 to "f" has incompatible type "C"; expected "B" |
| |
| if int(): |
| ao = f(b) |
| if int(): |
| ab = f(b) |
| if int(): |
| ao = f(c) |
| if int(): |
| ac = f(c) |
| |
| def f(a: T) -> 'A[T]': |
| pass |
| |
| class A(Generic[T]): pass |
| |
| class B: pass |
| class C: pass |
| |
| |
| -- Local variables |
| -- --------------- |
| |
| |
| [case testInferGenericLocalVariableTypeWithEmptyContext] |
| from typing import TypeVar, Generic |
| T = TypeVar('T') |
| def g() -> None: |
| ao = None # type: A[object] |
| ab = None # type: A[B] |
| o = None # type: object |
| b = None # type: B |
| |
| x = f(o) |
| if int(): |
| ab = x # E: Incompatible types in assignment (expression has type "A[object]", variable has type "A[B]") |
| ao = x |
| y = f(b) |
| if int(): |
| ao = y # E: Incompatible types in assignment (expression has type "A[B]", variable has type "A[object]") |
| ab = y |
| |
| def f(a: T) -> 'A[T]': pass |
| |
| class A(Generic[T]): pass |
| class B: pass |
| [out] |
| |
| [case testInferLocalVariableTypeWithUnderspecifiedGenericType] |
| from typing import TypeVar, Generic |
| T = TypeVar('T') |
| def g() -> None: |
| x = f() # E: Need type annotation for "x" |
| |
| def f() -> 'A[T]': pass |
| class A(Generic[T]): pass |
| [out] |
| |
| [case testInferMultipleLocalVariableTypesWithTupleRvalue] |
| from typing import TypeVar, Generic |
| T = TypeVar('T') |
| def g() -> None: |
| ao = None # type: A[object] |
| ab = None # type: A[B] |
| b = None # type: B |
| x, y = f(b), f(b) |
| if int(): |
| ao = x # E: Incompatible types in assignment (expression has type "A[B]", variable has type "A[object]") |
| ao = y # E: Incompatible types in assignment (expression has type "A[B]", variable has type "A[object]") |
| ab = x |
| ab = y |
| |
| def f(a: T) -> 'A[T]': pass |
| class A(Generic[T]): pass |
| class B: pass |
| [out] |
| |
| [case testInferMultipleLocalVariableTypesWithArrayRvalueAndNesting] |
| from typing import TypeVar, List, Generic |
| T = TypeVar('T') |
| def h() -> None: |
| ao = None # type: A[object] |
| ab = None # type: A[B] |
| b = None # type: B |
| x, y = g(f(b)) |
| if int(): |
| ao = x # E: Incompatible types in assignment (expression has type "A[B]", variable has type "A[object]") |
| ao = y # E: Incompatible types in assignment (expression has type "A[B]", variable has type "A[object]") |
| ab = x |
| ab = y |
| |
| def f(a: T) -> 'A[T]': pass |
| def g(a: T) -> List[T]: pass |
| |
| class A(Generic[T]): pass |
| class B: pass |
| [builtins fixtures/for.pyi] |
| [out] |
| |
| |
| -- Return types with multiple tvar instances |
| -- ----------------------------------------- |
| |
| |
| [case testInferenceWithTypeVariableTwiceInReturnType] |
| from typing import TypeVar, Tuple, Generic |
| T = TypeVar('T') |
| b = None # type: B |
| o = None # type: object |
| ab = None # type: A[B] |
| ao = None # type: A[object] |
| |
| if int(): |
| ab, ao = f(b) # E: Incompatible types in assignment (expression has type "A[B]", variable has type "A[object]") |
| if int(): |
| ao, ab = f(b) # E: Incompatible types in assignment (expression has type "A[B]", variable has type "A[object]") |
| |
| if int(): |
| ao, ao = f(b) |
| if int(): |
| ab, ab = f(b) |
| if int(): |
| ao, ao = f(o) |
| |
| def f(a: T) -> 'Tuple[A[T], A[T]]': pass |
| |
| class A(Generic[T]): pass |
| class B: pass |
| [builtins fixtures/tuple.pyi] |
| |
| [case testInferenceWithTypeVariableTwiceInReturnTypeAndMultipleVariables] |
| from typing import TypeVar, Tuple, Generic |
| S = TypeVar('S') |
| T = TypeVar('T') |
| b = None # type: B |
| o = None # type: object |
| ab = None # type: A[B] |
| ao = None # type: A[object] |
| |
| if int(): |
| ao, ao, ab = f(b, b) # E: Incompatible types in assignment (expression has type "A[B]", variable has type "A[object]") |
| if int(): |
| ao, ab, ao = g(b, b) # E: Incompatible types in assignment (expression has type "A[B]", variable has type "A[object]") |
| if int(): |
| ao, ab, ab, ab = h(b, b) # E: Incompatible types in assignment (expression has type "A[B]", variable has type "A[object]") |
| if int(): |
| ab, ab, ao, ab = h(b, b) # E: Incompatible types in assignment (expression has type "A[B]", variable has type "A[object]") |
| |
| if int(): |
| ao, ab, ab = f(b, b) |
| if int(): |
| ab, ab, ao = g(b, b) |
| if int(): |
| ab, ab, ab, ab = h(b, b) |
| |
| def f(a: S, b: T) -> 'Tuple[A[S], A[T], A[T]]': pass |
| def g(a: S, b: T) -> 'Tuple[A[S], A[S], A[T]]': pass |
| def h(a: S, b: T) -> 'Tuple[A[S], A[S], A[T], A[T]]': pass |
| |
| class A(Generic[T]): pass |
| class B: pass |
| [builtins fixtures/tuple.pyi] |
| |
| |
| -- Multiple tvar instances in arguments |
| -- ------------------------------------ |
| |
| |
| [case testMultipleTvatInstancesInArgs] |
| from typing import TypeVar, Generic |
| T = TypeVar('T') |
| ac = None # type: A[C] |
| ab = None # type: A[B] |
| ao = None # type: A[object] |
| b = None # type: B |
| c = None # type: C |
| o = None # type: object |
| |
| if int(): |
| ab = f(b, o) # E: Argument 2 to "f" has incompatible type "object"; expected "B" |
| if int(): |
| ab = f(o, b) # E: Argument 1 to "f" has incompatible type "object"; expected "B" |
| if int(): |
| ac = f(b, c) # E: Argument 1 to "f" has incompatible type "B"; expected "C" |
| if int(): |
| ac = f(c, b) # E: Argument 2 to "f" has incompatible type "B"; expected "C" |
| |
| if int(): |
| ao = f(b, c) |
| if int(): |
| ao = f(c, b) |
| if int(): |
| ab = f(c, b) |
| |
| def f(a: T, b: T) -> 'A[T]': pass |
| |
| class A(Generic[T]): pass |
| class B: pass |
| class C(B): pass |
| |
| |
| -- Nested generic function calls |
| -- ----------------------------- |
| |
| |
| [case testNestedGenericFunctionCall1] |
| from typing import TypeVar, Generic |
| T = TypeVar('T') |
| aab = None # type: A[A[B]] |
| aao = None # type: A[A[object]] |
| ao = None # type: A[object] |
| b = None # type: B |
| o = None # type: object |
| |
| if int(): |
| aab = f(f(o)) # E: Argument 1 to "f" has incompatible type "object"; expected "B" |
| |
| if int(): |
| aab = f(f(b)) |
| aao = f(f(b)) |
| ao = f(f(b)) |
| |
| def f(a: T) -> 'A[T]': pass |
| |
| class A(Generic[T]): pass |
| class B: pass |
| |
| [case testNestedGenericFunctionCall2] |
| from typing import TypeVar, Generic |
| T = TypeVar('T') |
| ab = None # type: A[B] |
| ao = None # type: A[object] |
| b = None # type: B |
| o = None # type: object |
| |
| if int(): |
| ab = f(g(o)) # E: Argument 1 to "g" has incompatible type "object"; expected "B" |
| |
| if int(): |
| ab = f(g(b)) |
| ao = f(g(b)) |
| |
| def f(a: T) -> T: pass |
| |
| def g(a: T) -> 'A[T]': pass |
| |
| class A(Generic[T]): pass |
| class B: pass |
| |
| [case testNestedGenericFunctionCall3] |
| from typing import TypeVar, Generic |
| T = TypeVar('T') |
| ab = None # type: A[B] |
| ao = None # type: A[object] |
| b = None # type: B |
| o = None # type: object |
| |
| if int(): |
| ab = f(g(o), g(b)) # E: Argument 1 to "g" has incompatible type "object"; expected "B" |
| if int(): |
| ab = f(g(b), g(o)) # E: Argument 1 to "g" has incompatible type "object"; expected "B" |
| |
| if int(): |
| ab = f(g(b), g(b)) |
| ao = f(g(b), g(o)) |
| if int(): |
| ao = f(g(o), g(b)) |
| |
| def f(a: T, b: T) -> T: |
| pass |
| |
| def g(a: T) -> 'A[T]': pass |
| |
| class A(Generic[T]): pass |
| class B: pass |
| |
| |
| -- Method calls |
| -- ------------ |
| |
| |
| [case testMethodCallWithContextInference] |
| from typing import TypeVar, Generic |
| T = TypeVar('T') |
| o = None # type: object |
| b = None # type: B |
| c = None # type: C |
| ao = None # type: A[object] |
| ab = None # type: A[B] |
| ac = None # type: A[C] |
| |
| ab.g(f(o)) # E: Argument 1 to "f" has incompatible type "object"; expected "B" |
| if int(): |
| ac = f(b).g(f(c)) # E: Incompatible types in assignment (expression has type "A[B]", variable has type "A[C]") |
| if int(): |
| ac = f(c).g(f(b)) # E: Argument 1 to "f" has incompatible type "B"; expected "C" |
| |
| if int(): |
| ab = f(b).g(f(c)) |
| ab.g(f(c)) |
| |
| def f(a: T) -> 'A[T]': pass |
| |
| class A(Generic[T]): |
| def g(self, a: 'A[T]') -> 'A[T]': pass |
| |
| class B: pass |
| class C(B): pass |
| |
| |
| -- List expressions |
| -- ---------------- |
| |
| |
| [case testEmptyListExpression] |
| from typing import List |
| aa = None # type: List[A] |
| ao = None # type: List[object] |
| a = None # type: A |
| def f(): a, aa, ao # Prevent redefinition |
| |
| a = [] # E: Incompatible types in assignment (expression has type "List[<nothing>]", variable has type "A") |
| |
| aa = [] |
| ao = [] |
| |
| class A: pass |
| [builtins fixtures/list.pyi] |
| |
| [case testSingleItemListExpressions] |
| from typing import List |
| aa = None # type: List[A] |
| ab = None # type: List[B] |
| ao = None # type: List[object] |
| a = None # type: A |
| b = None # type: B |
| def f(): aa, ab, ao # Prevent redefinition |
| |
| aa = [b] # E: List item 0 has incompatible type "B"; expected "A" |
| ab = [a] # E: List item 0 has incompatible type "A"; expected "B" |
| |
| aa = [a] |
| ab = [b] |
| ao = [a] |
| aa = [None] |
| ao = [None] |
| |
| class A: pass |
| class B: pass |
| [builtins fixtures/list.pyi] |
| |
| [case testMultiItemListExpressions] |
| from typing import List |
| aa = None # type: List[A] |
| ab = None # type: List[B] |
| ao = None # type: List[object] |
| a = None # type: A |
| b = None # type: B |
| def f(): ab, aa, ao # Prevent redefinition |
| |
| ab = [b, a] # E: List item 1 has incompatible type "A"; expected "B" |
| ab = [a, b] # E: List item 0 has incompatible type "A"; expected "B" |
| |
| aa = [a, b, a] |
| ao = [a, b] |
| |
| class A: pass |
| class B(A): pass |
| [builtins fixtures/list.pyi] |
| |
| [case testLocalVariableInferenceFromEmptyList] |
| import typing |
| def f() -> None: |
| a = [] # E: Need type annotation for "a" (hint: "a: List[<type>] = ...") |
| b = [None] |
| c = [B()] |
| if int(): |
| c = [object()] # E: List item 0 has incompatible type "object"; expected "B" |
| c = [B()] |
| class B: pass |
| [builtins fixtures/list.pyi] |
| [out] |
| |
| [case testNestedListExpressions] |
| from typing import List |
| aao = None # type: List[List[object]] |
| aab = None # type: List[List[B]] |
| ab = None # type: List[B] |
| b = None # type: B |
| o = None # type: object |
| def f(): aao, aab # Prevent redefinition |
| |
| aao = [[o], ab] # E: List item 1 has incompatible type "List[B]"; expected "List[object]" |
| aab = [[], [o]] # E: List item 0 has incompatible type "object"; expected "B" |
| |
| aao = [[None], [b], [], [o]] |
| aab = [[None], [b], []] |
| aab = [ab, []] |
| |
| class B: pass |
| [builtins fixtures/list.pyi] |
| |
| |
| -- Complex context |
| -- --------------- |
| |
| |
| [case testParenthesesAndContext] |
| from typing import List |
| l = ([A()]) # type: List[object] |
| class A: pass |
| [builtins fixtures/list.pyi] |
| |
| [case testComplexTypeInferenceWithTuple] |
| from typing import TypeVar, Tuple, Generic |
| k = TypeVar('k') |
| t = TypeVar('t') |
| v = TypeVar('v') |
| def f(x: Tuple[k]) -> 'A[k]': pass |
| |
| d = f((A(),)) # type: A[A[B]] |
| |
| class A(Generic[t]): pass |
| class B: pass |
| class C: pass |
| class D(Generic[k, v]): pass |
| [builtins fixtures/list.pyi] |
| |
| |
| -- Dictionary literals |
| -- ------------------- |
| |
| |
| [case testDictionaryLiteralInContext] |
| from typing import Dict, TypeVar, Generic |
| t = TypeVar('t') |
| class A(Generic[t]): pass |
| class B: pass |
| class C: pass |
| a_b = A() # type: A[B] |
| a_c = A() # type: A[C] |
| d = {A() : a_c, |
| a_b : A()} # type: Dict[A[B], A[C]] |
| [builtins fixtures/dict.pyi] |
| |
| |
| -- Special cases (regression tests etc.) |
| -- ------------------------------------- |
| |
| |
| [case testInitializationWithInferredGenericType] |
| from typing import TypeVar, Generic |
| T = TypeVar('T') |
| c = f(A()) # type: C[A] # E: Argument 1 to "f" has incompatible type "A"; expected "C[A]" |
| |
| def f(x: T) -> T: pass |
| class C(Generic[T]): pass |
| class A: pass |
| |
| [case testInferredGenericTypeAsReturnValue] |
| from typing import TypeVar, Generic |
| T = TypeVar('T') |
| def t() -> 'A[B]': |
| return f(D()) # E: Argument 1 to "f" has incompatible type "D"; expected "B" |
| return A() |
| return f(C()) |
| |
| def f(a: T) -> 'A[T]': pass |
| class A(Generic[T]): pass |
| class B: pass |
| class C(B): pass |
| class D: pass |
| [out] |
| |
| [case testIntersectionWithInferredGenericArgument] |
| from foo import * |
| [file foo.pyi] |
| from typing import overload, TypeVar, Generic |
| T = TypeVar('T') |
| f(A()) |
| |
| @overload |
| def f(x: 'A[B]') -> None: pass |
| @overload |
| def f(x: 'B') -> None: pass |
| class A(Generic[T]): pass |
| class B: pass |
| |
| [case testInferenceWithAbstractClassContext] |
| from typing import TypeVar, Generic |
| from abc import abstractmethod, ABCMeta |
| t = TypeVar('t') |
| x = A() # type: I[int] |
| a_object = A() # type: A[object] |
| y = a_object # type: I[int] # E: Incompatible types in assignment (expression has type "A[object]", variable has type "I[int]") |
| |
| class I(Generic[t]): |
| @abstractmethod |
| def f(self): pass |
| class A(I[t], Generic[t]): |
| def f(self): pass |
| |
| [case testInferenceWithAbstractClassContext2] |
| from typing import TypeVar, Generic |
| from abc import abstractmethod, ABCMeta |
| t = TypeVar('t') |
| a = f(A()) # type: A[int] |
| a_int = A() # type: A[int] |
| aa = f(a_int) |
| class I(Generic[t]): pass |
| class A(I[t], Generic[t]): pass |
| def f(i: I[t]) -> A[t]: pass |
| |
| [case testInferenceWithAbstractClassContext3] |
| from typing import TypeVar, Generic, Iterable |
| t = TypeVar('t') |
| class set(Generic[t]): |
| def __init__(self, iterable: Iterable[t]) -> None: pass |
| b = bool() |
| l = set([b]) |
| if int(): |
| l = set([object()]) # E: List item 0 has incompatible type "object"; expected "bool" |
| [builtins fixtures/for.pyi] |
| |
| |
| -- Infer generic type in 'Any' context |
| -- ----------------------------------- |
| |
| |
| [case testInferGenericTypeInAnyContext] |
| from typing import Any, TypeVar, Generic |
| s = TypeVar('s') |
| t = TypeVar('t') |
| x = [] # type: Any |
| y = C() # type: Any |
| class C(Generic[s, t]): pass |
| [builtins fixtures/list.pyi] |
| |
| |
| -- Lambdas |
| -- ------- |
| |
| |
| [case testInferLambdaArgumentTypeUsingContext] |
| from typing import Callable |
| f = None # type: Callable[[B], A] |
| if int(): |
| f = lambda x: x.o |
| f = lambda x: x.x # E: "B" has no attribute "x" |
| class A: pass |
| class B: |
| o = None # type: A |
| |
| [case testInferLambdaReturnTypeUsingContext] |
| from typing import List, Callable |
| f = None # type: Callable[[], List[A]] |
| if int(): |
| f = lambda: [] |
| f = lambda: [B()] # E: List item 0 has incompatible type "B"; expected "A" |
| class A: pass |
| class B: pass |
| [builtins fixtures/list.pyi] |
| |
| [case testInferLambdaTypeUsingContext] |
| x : str = (lambda x: x + 1)(1) # E: Incompatible types in assignment (expression has type "int", variable has type "str") |
| reveal_type((lambda x, y: x + y)(1, 2)) # N: Revealed type is 'builtins.int' |
| (lambda x, y: x + y)(1, "") # E: Unsupported operand types for + ("int" and "str") |
| (lambda *, x, y: x + y)(x=1, y="") # E: Unsupported operand types for + ("int" and "str") |
| reveal_type((lambda s, i: s)(i=0, s='x')) # N: Revealed type is 'Literal['x']?' |
| reveal_type((lambda s, i: i)(i=0, s='x')) # N: Revealed type is 'Literal[0]?' |
| reveal_type((lambda x, s, i: x)(1.0, i=0, s='x')) # N: Revealed type is 'builtins.float' |
| (lambda x, s, i: x)() # E: Too few arguments |
| (lambda: 0)(1) # E: Too many arguments |
| -- varargs are not handled, but it should not crash |
| reveal_type((lambda *k, s, i: i)(type, i=0, s='x')) # N: Revealed type is 'Any' |
| reveal_type((lambda s, *k, i: i)(i=0, s='x')) # N: Revealed type is 'Any' |
| reveal_type((lambda s, i, **k: i)(i=0, s='x')) # N: Revealed type is 'Any' |
| [builtins fixtures/dict.pyi] |
| |
| [case testInferLambdaAsGenericFunctionArgument] |
| from typing import TypeVar, List, Any, Callable |
| t = TypeVar('t') |
| class A: |
| x = None # type: A |
| def f(a: List[t], fn: Callable[[t], Any]) -> None: pass |
| list_a = [] # type: List[A] |
| f(list_a, lambda a: a.x) |
| [builtins fixtures/list.pyi] |
| |
| [case testLambdaWithoutContext] |
| reveal_type(lambda x: x) # N: Revealed type is 'def (x: Any) -> Any' |
| reveal_type(lambda x: 1) # N: Revealed type is 'def (x: Any) -> Literal[1]?' |
| |
| [case testLambdaContextVararg] |
| from typing import Callable |
| def f(t: Callable[[str], str]) -> str: '' |
| f(lambda *_: '') |
| [builtins fixtures/tuple.pyi] |
| |
| [case testInvalidContextForLambda] |
| from typing import Callable |
| f = lambda x: A() # type: Callable[[], A] |
| f2 = lambda: A() # type: Callable[[A], A] |
| class A: pass |
| [out] |
| main:2: error: Cannot infer type of lambda |
| main:2: error: Incompatible types in assignment (expression has type "Callable[[Any], A]", variable has type "Callable[[], A]") |
| main:3: error: Cannot infer type of lambda |
| main:3: error: Incompatible types in assignment (expression has type "Callable[[], A]", variable has type "Callable[[A], A]") |
| |
| [case testEllipsisContextForLambda] |
| from typing import Callable |
| f1 = lambda x: 1 # type: Callable[..., int] |
| f2 = lambda: 1 # type: Callable[..., int] |
| f3 = lambda *args, **kwargs: 1 # type: Callable[..., int] |
| f4 = lambda x: x # type: Callable[..., int] |
| g = lambda x: 1 # type: Callable[..., str] |
| [builtins fixtures/dict.pyi] |
| [out] |
| main:6: error: Incompatible types in assignment (expression has type "Callable[[Any], int]", variable has type "Callable[..., str]") |
| main:6: error: Incompatible return value type (got "int", expected "str") |
| |
| [case testEllipsisContextForLambda2] |
| from typing import TypeVar, Callable |
| T = TypeVar('T') |
| def foo(arg: Callable[..., T]) -> None: pass |
| foo(lambda: 1) |
| |
| [case testLambdaNoneInContext] |
| from typing import Callable |
| def f(x: Callable[[], None]) -> None: pass |
| def g(x: Callable[[], int]) -> None: pass |
| f(lambda: None) |
| g(lambda: None) |
| |
| [case testIsinstanceInInferredLambda] |
| from typing import TypeVar, Callable |
| T = TypeVar('T') |
| S = TypeVar('S') |
| class A: pass |
| class B(A): pass |
| class C(A): pass |
| def f(func: Callable[[T], S], *z: T, r: S = None) -> S: pass |
| f(lambda x: 0 if isinstance(x, B) else 1) # E: Cannot infer type argument 1 of "f" |
| f(lambda x: 0 if isinstance(x, B) else 1, A())() # E: "int" not callable |
| f(lambda x: x if isinstance(x, B) else B(), A(), r=B())() # E: "B" not callable |
| f( |
| lambda x: # E: Argument 1 to "f" has incompatible type "Callable[[A], A]"; expected "Callable[[A], B]" |
| B() if isinstance(x, B) else x, # E: Incompatible return value type (got "A", expected "B") |
| A(), r=B()) |
| [builtins fixtures/isinstance.pyi] |
| |
| |
| -- Overloads + generic functions |
| -- ----------------------------- |
| |
| |
| [case testMapWithOverloadedFunc] |
| from foo import * |
| [file foo.pyi] |
| from typing import TypeVar, Callable, List, overload, Any |
| t = TypeVar('t') |
| s = TypeVar('s') |
| def map(f: Callable[[t], s], seq: List[t]) -> List[s]: pass |
| |
| @overload |
| def g(o: object) -> 'B': pass |
| @overload |
| def g(o: 'A', x: Any = None) -> 'B': pass |
| |
| class A: pass |
| class B: pass |
| |
| m = map(g, [A()]) |
| b = m # type: List[B] |
| a = m # type: List[A] # E: Incompatible types in assignment (expression has type "List[B]", variable has type "List[A]") |
| [builtins fixtures/list.pyi] |
| |
| |
| -- Boolean operators |
| -- ----------------- |
| |
| |
| [case testOrOperationInferredFromContext] |
| from typing import List |
| a, b, c = None, None, None # type: (List[A], List[B], List[C]) |
| if int(): |
| a = a or [] |
| if int(): |
| a = [] or a |
| if int(): |
| b = b or [C()] |
| if int(): |
| a = a or b # E: Incompatible types in assignment (expression has type "Union[List[A], List[B]]", variable has type "List[A]") |
| if int(): |
| b = b or c # E: Incompatible types in assignment (expression has type "Union[List[B], List[C]]", variable has type "List[B]") |
| |
| class A: pass |
| class B: pass |
| class C(B): pass |
| [builtins fixtures/list.pyi] |
| |
| |
| -- Special cases |
| -- ------------- |
| |
| |
| [case testSomeTypeVarsInferredFromContext] |
| from typing import List, TypeVar |
| t = TypeVar('t') |
| s = TypeVar('s') |
| # Some type variables can be inferred using context, but not all of them. |
| a = None # type: List[A] |
| if int(): |
| a = f(A(), B()) |
| if int(): |
| a = f(B(), B()) # E: Argument 1 to "f" has incompatible type "B"; expected "A" |
| def f(a: s, b: t) -> List[s]: pass |
| class A: pass |
| class B: pass |
| [builtins fixtures/list.pyi] |
| |
| [case testSomeTypeVarsInferredFromContext2] |
| from typing import List, TypeVar |
| s = TypeVar('s') |
| t = TypeVar('t') |
| # Like testSomeTypeVarsInferredFromContext, but tvars in different order. |
| a = None # type: List[A] |
| if int(): |
| a = f(A(), B()) |
| if int(): |
| a = f(B(), B()) # E: Argument 1 to "f" has incompatible type "B"; expected "A" |
| def f(a: s, b: t) -> List[s]: pass |
| class A: pass |
| class B: pass |
| [builtins fixtures/list.pyi] |
| |
| [case testLambdaInListAndHigherOrderFunction] |
| from typing import TypeVar, Callable, List |
| t = TypeVar('t') |
| s = TypeVar('s') |
| map( |
| [lambda x: x], []) |
| def map(f: List[Callable[[t], s]], a: List[t]) -> List[s]: pass |
| class A: pass |
| [builtins fixtures/list.pyi] |
| [out] |
| |
| [case testChainedAssignmentInferenceContexts] |
| from typing import List |
| i = None # type: List[int] |
| s = None # type: List[str] |
| if int(): |
| i = i = [] |
| if int(): |
| i = s = [] # E: Incompatible types in assignment (expression has type "List[str]", variable has type "List[int]") |
| [builtins fixtures/list.pyi] |
| |
| [case testContextForAttributeDeclaredInInit] |
| from typing import List |
| class A: |
| def __init__(self): |
| self.x = [] # type: List[int] |
| a = A() |
| a.x = [] |
| a.x = [1] |
| a.x = [''] # E: List item 0 has incompatible type "str"; expected "int" |
| [builtins fixtures/list.pyi] |
| |
| [case testListMultiplyInContext] |
| from typing import List |
| a = None # type: List[int] |
| if int(): |
| a = [None] * 3 |
| a = [''] * 3 # E: List item 0 has incompatible type "str"; expected "int" |
| [builtins fixtures/list.pyi] |
| |
| [case testUnionTypeContext] |
| from typing import Union, List, TypeVar |
| T = TypeVar('T') |
| def f(x: Union[List[T], str]) -> None: pass |
| f([1]) |
| f('') |
| f(1) # E: Argument 1 to "f" has incompatible type "int"; expected "Union[List[<nothing>], str]" |
| [builtins fixtures/isinstancelist.pyi] |
| |
| [case testIgnoringInferenceContext] |
| from typing import TypeVar, List |
| T = TypeVar('T') |
| def f(x: List[T]) -> T: pass |
| def g(y: object) -> None: pass |
| a = [1] |
| g(f(a)) |
| [builtins fixtures/list.pyi] |
| |
| [case testStar2Context] |
| from typing import Any, Dict, Tuple, Iterable |
| def f1(iterable: Iterable[Tuple[str, Any]] = None) -> None: |
| f2(**dict(iterable)) |
| def f2(iterable: Iterable[Tuple[str, Any]], **kw: Any) -> None: |
| pass |
| [builtins fixtures/dict.pyi] |
| [out] |
| |
| [case testInferenceInGenericFunction] |
| from typing import TypeVar, List |
| T = TypeVar('T') |
| def f(a: T) -> None: |
| l = [] # type: List[T] |
| l.append(a) |
| l.append(1) # E: Argument 1 to "append" of "list" has incompatible type "int"; expected "T" |
| [builtins fixtures/list.pyi] |
| [out] |
| |
| [case testInferenceInGenericClass] |
| from typing import TypeVar, Generic, List |
| S = TypeVar('S') |
| T = TypeVar('T') |
| class A(Generic[S]): |
| def f(self, a: T, b: S) -> None: |
| l = [] # type: List[T] |
| l.append(a) |
| l.append(b) # E: Argument 1 to "append" of "list" has incompatible type "S"; expected "T" |
| [builtins fixtures/list.pyi] |
| [out] |
| |
| [case testLambdaInGenericFunction] |
| from typing import TypeVar, Callable |
| T = TypeVar('T') |
| S = TypeVar('S') |
| def f(a: T, b: S) -> None: |
| c = lambda x: x # type: Callable[[T], S] |
| [out] |
| main:5: error: Incompatible types in assignment (expression has type "Callable[[T], T]", variable has type "Callable[[T], S]") |
| main:5: error: Incompatible return value type (got "T", expected "S") |
| |
| [case testLambdaInGenericClass] |
| from typing import TypeVar, Callable, Generic |
| T = TypeVar('T') |
| S = TypeVar('S') |
| class A(Generic[T]): |
| def f(self, b: S) -> None: |
| c = lambda x: x # type: Callable[[T], S] |
| [out] |
| main:6: error: Incompatible types in assignment (expression has type "Callable[[T], T]", variable has type "Callable[[T], S]") |
| main:6: error: Incompatible return value type (got "T", expected "S") |
| |
| [case testRevealTypeContext] |
| from typing import TypeVar, Callable, Generic |
| T = TypeVar('T') |
| class A(Generic[T]): |
| pass |
| reveal_type(A()) # N: Revealed type is '__main__.A[<nothing>]' |
| b = reveal_type(A()) # type: A[int] # N: Revealed type is '__main__.A[builtins.int]' |
| |
| [case testUnionWithGenericTypeItemContext] |
| from typing import TypeVar, Union, List |
| |
| T = TypeVar('T') |
| |
| def f(x: Union[T, List[int]]) -> Union[T, List[int]]: pass |
| reveal_type(f(1)) # N: Revealed type is 'Union[builtins.int*, builtins.list[builtins.int]]' |
| reveal_type(f([])) # N: Revealed type is 'builtins.list[builtins.int]' |
| reveal_type(f(None)) # N: Revealed type is 'builtins.list[builtins.int]' |
| [builtins fixtures/list.pyi] |
| |
| [case testUnionWithGenericTypeItemContextAndStrictOptional] |
| # flags: --strict-optional |
| from typing import TypeVar, Union, List |
| |
| T = TypeVar('T') |
| |
| def f(x: Union[T, List[int]]) -> Union[T, List[int]]: pass |
| reveal_type(f(1)) # N: Revealed type is 'Union[builtins.int*, builtins.list[builtins.int]]' |
| reveal_type(f([])) # N: Revealed type is 'builtins.list[builtins.int]' |
| reveal_type(f(None)) # N: Revealed type is 'Union[None, builtins.list[builtins.int]]' |
| [builtins fixtures/list.pyi] |
| |
| [case testUnionWithGenericTypeItemContextInMethod] |
| from typing import TypeVar, Union, List, Generic |
| |
| T = TypeVar('T') |
| S = TypeVar('S') |
| |
| class C(Generic[T]): |
| def f(self, x: Union[T, S]) -> Union[T, S]: pass |
| |
| c = C[List[int]]() |
| reveal_type(c.f('')) # N: Revealed type is 'Union[builtins.list[builtins.int], builtins.str*]' |
| reveal_type(c.f([1])) # N: Revealed type is 'builtins.list[builtins.int]' |
| reveal_type(c.f([])) # N: Revealed type is 'builtins.list[builtins.int]' |
| reveal_type(c.f(None)) # N: Revealed type is 'builtins.list[builtins.int]' |
| [builtins fixtures/list.pyi] |
| |
| [case testGenericMethodCalledInGenericContext] |
| # flags: --strict-optional |
| from typing import TypeVar, Generic |
| |
| _KT = TypeVar('_KT') |
| _VT = TypeVar('_VT') |
| _T = TypeVar('_T') |
| |
| class M(Generic[_KT, _VT]): |
| def get(self, k: _KT, default: _T) -> _T: ... |
| |
| def f(d: M[_KT, _VT], k: _KT) -> _VT: |
| return d.get(k, None) # E: Incompatible return value type (got "None", expected "_VT") |
| |
| [case testGenericMethodCalledInGenericContext2] |
| from typing import TypeVar, Generic, Union |
| |
| _KT = TypeVar('_KT') |
| _VT = TypeVar('_VT') |
| _T = TypeVar('_T') |
| |
| class M(Generic[_KT, _VT]): |
| def get(self, k: _KT, default: _T) -> Union[_VT, _T]: ... |
| |
| def f(d: M[_KT, _VT], k: _KT) -> Union[_VT, None]: |
| return d.get(k, None) |
| |
| [case testLambdaDeferredCrash] |
| from typing import Callable |
| |
| class C: |
| def f(self) -> None: |
| g: Callable[[], int] = lambda: 1 or self.x |
| self.x = int() |
| |
| [case testInferTypeVariableFromTwoGenericTypes1] |
| from typing import TypeVar, List, Sequence |
| |
| T = TypeVar('T') |
| |
| class C: ... |
| class D(C): ... |
| |
| def f(x: Sequence[T], y: Sequence[T]) -> List[T]: ... |
| |
| reveal_type(f([C()], [D()])) # N: Revealed type is 'builtins.list[__main__.C*]' |
| [builtins fixtures/list.pyi] |
| |
| [case testInferTypeVariableFromTwoGenericTypes2] |
| from typing import TypeVar, List |
| |
| T = TypeVar('T') |
| |
| class C: ... |
| class D(C): ... |
| |
| def f(x: List[T], y: List[T]) -> List[T]: ... |
| |
| f([C()], [D()]) # E: Cannot infer type argument 1 of "f" |
| [builtins fixtures/list.pyi] |
| |
| [case testInferTypeVariableFromTwoGenericTypes3] |
| from typing import Generic, TypeVar |
| |
| T = TypeVar('T') |
| T_contra = TypeVar('T_contra', contravariant=True) |
| |
| class A(Generic[T_contra]): pass |
| class B(A[T]): pass |
| |
| class C: ... |
| class D(C): ... |
| |
| def f(x: A[T], y: A[T]) -> B[T]: ... |
| |
| c: B[C] |
| d: B[D] |
| reveal_type(f(c, d)) # N: Revealed type is '__main__.B[__main__.D*]' |
| |
| [case testInferTypeVariableFromTwoGenericTypes4] |
| from typing import Generic, TypeVar, Callable, List |
| |
| T = TypeVar('T') |
| T_contra = TypeVar('T_contra', contravariant=True) |
| |
| class A(Generic[T_contra]): pass |
| class B(A[T_contra]): pass |
| |
| class C: ... |
| class D(C): ... |
| |
| def f(x: Callable[[B[T]], None], |
| y: Callable[[B[T]], None]) -> List[T]: ... |
| |
| def gc(x: A[C]) -> None: pass # B[C] |
| def gd(x: A[D]) -> None: pass # B[C] |
| |
| reveal_type(f(gc, gd)) # N: Revealed type is 'builtins.list[__main__.C*]' |
| [builtins fixtures/list.pyi] |
| |
| [case testWideOuterContextSubClassBound] |
| from typing import TypeVar |
| |
| class A: ... |
| class B(A): ... |
| |
| T = TypeVar('T', bound=B) |
| def f(x: T) -> T: ... |
| def outer(x: A) -> None: ... |
| |
| outer(f(B())) |
| x: A = f(B()) |
| |
| [case testWideOuterContextSubClassBoundGenericReturn] |
| from typing import TypeVar, Iterable, List |
| |
| class A: ... |
| class B(A): ... |
| |
| T = TypeVar('T', bound=B) |
| def f(x: T) -> List[T]: ... |
| def outer(x: Iterable[A]) -> None: ... |
| |
| outer(f(B())) |
| x: Iterable[A] = f(B()) |
| [builtins fixtures/list.pyi] |
| |
| [case testWideOuterContextSubClassValues] |
| from typing import TypeVar |
| |
| class A: ... |
| class B(A): ... |
| |
| T = TypeVar('T', B, int) |
| def f(x: T) -> T: ... |
| def outer(x: A) -> None: ... |
| |
| outer(f(B())) |
| x: A = f(B()) |
| |
| [case testWideOuterContextSubClassValuesGenericReturn] |
| from typing import TypeVar, Iterable, List |
| |
| class A: ... |
| class B(A): ... |
| |
| T = TypeVar('T', B, int) |
| def f(x: T) -> List[T]: ... |
| def outer(x: Iterable[A]) -> None: ... |
| |
| outer(f(B())) |
| x: Iterable[A] = f(B()) |
| [builtins fixtures/list.pyi] |
| |
| [case testWideOuterContextSubclassBoundGeneric] |
| from typing import TypeVar, Generic |
| |
| S = TypeVar('S') |
| class A(Generic[S]): ... |
| class B(A[S]): ... |
| |
| T = TypeVar('T', bound=B[int]) |
| def f(x: T) -> T: ... |
| def outer(x: A[int]) -> None: ... |
| |
| y: B[int] |
| outer(f(y)) |
| x: A[int] = f(y) |
| |
| [case testWideOuterContextSubclassBoundGenericCovariant] |
| from typing import TypeVar, Generic |
| |
| S_co = TypeVar('S_co', covariant=True) |
| class A(Generic[S_co]): ... |
| class B(A[S_co]): ... |
| |
| T = TypeVar('T', bound=B[int]) |
| def f(x: T) -> T: ... |
| def outer(x: A[int]) -> None: ... |
| |
| y: B[int] |
| outer(f(y)) |
| x: A[int] = f(y) |
| |
| [case testWideOuterContextSubclassValuesGeneric] |
| from typing import TypeVar, Generic |
| |
| S = TypeVar('S') |
| class A(Generic[S]): ... |
| class B(A[S]): ... |
| |
| T = TypeVar('T', B[int], int) |
| def f(x: T) -> T: ... |
| def outer(x: A[int]) -> None: ... |
| |
| y: B[int] |
| outer(f(y)) |
| x: A[int] = f(y) |
| |
| [case testWideOuterContextSubclassValuesGenericCovariant] |
| from typing import TypeVar, Generic |
| |
| S_co = TypeVar('S_co', covariant=True) |
| class A(Generic[S_co]): ... |
| class B(A[S_co]): ... |
| |
| T = TypeVar('T', B[int], int) |
| def f(x: T) -> T: ... |
| def outer(x: A[int]) -> None: ... |
| |
| y: B[int] |
| outer(f(y)) |
| x: A[int] = f(y) |
| |
| [case testWideOuterContextUnionBound] |
| from typing import TypeVar, Union |
| |
| class A: ... |
| class B: ... |
| |
| T = TypeVar('T', bound=B) |
| def f(x: T) -> T: ... |
| def outer(x: Union[A, B]) -> None: ... |
| |
| outer(f(B())) |
| x: Union[A, B] = f(B()) |
| |
| [case testWideOuterContextUnionBoundGenericReturn] |
| from typing import TypeVar, Union, Iterable, List |
| |
| class A: ... |
| class B: ... |
| |
| T = TypeVar('T', bound=B) |
| def f(x: T) -> List[T]: ... |
| def outer(x: Iterable[Union[A, B]]) -> None: ... |
| |
| outer(f(B())) |
| x: Iterable[Union[A, B]] = f(B()) |
| [builtins fixtures/list.pyi] |
| |
| [case testWideOuterContextUnionValues] |
| from typing import TypeVar, Union |
| |
| class A: ... |
| class B: ... |
| |
| T = TypeVar('T', B, int) |
| def f(x: T) -> T: ... |
| def outer(x: Union[A, B]) -> None: ... |
| |
| outer(f(B())) |
| x: Union[A, B] = f(B()) |
| |
| [case testWideOuterContextUnionValuesGenericReturn] |
| from typing import TypeVar, Union, Iterable, List |
| |
| class A: ... |
| class B: ... |
| |
| T = TypeVar('T', B, int) |
| def f(x: T) -> List[T]: ... |
| def outer(x: Iterable[Union[A, B]]) -> None: ... |
| |
| outer(f(B())) |
| x: Iterable[Union[A, B]] = f(B()) |
| [builtins fixtures/list.pyi] |
| |
| [case testWideOuterContextOptional] |
| # flags: --strict-optional |
| from typing import Optional, Type, TypeVar |
| |
| class Custom: |
| pass |
| |
| T = TypeVar('T', bound=Custom) |
| |
| def a(x: T) -> Optional[T]: ... |
| |
| def b(x: T) -> Optional[T]: |
| return a(x) |
| |
| [case testWideOuterContextOptionalGenericReturn] |
| # flags: --strict-optional |
| from typing import Optional, Type, TypeVar, Iterable |
| |
| class Custom: |
| pass |
| |
| T = TypeVar('T', bound=Custom) |
| |
| def a(x: T) -> Iterable[Optional[T]]: ... |
| |
| def b(x: T) -> Iterable[Optional[T]]: |
| return a(x) |
| |
| [case testWideOuterContextOptionalMethod] |
| # flags: --strict-optional |
| from typing import Optional, Type, TypeVar |
| |
| class A: pass |
| class B: pass |
| |
| T = TypeVar('T', A, B) |
| class C: |
| def meth_a(self) -> Optional[A]: |
| return self.meth(A) |
| |
| def meth(self, cls: Type[T]) -> Optional[T]: ... |
| |
| [case testWideOuterContextValuesOverlapping] |
| from typing import TypeVar, List |
| |
| class A: |
| pass |
| class B(A): |
| pass |
| class C: |
| pass |
| |
| T = TypeVar('T', A, B, C) |
| def foo(xs: List[T]) -> T: ... |
| |
| S = TypeVar('S', B, C) |
| def bar(xs: List[S]) -> S: |
| foo(xs) |
| return xs[0] |
| [builtins fixtures/list.pyi] |
| |
| [case testWideOuterContextOptionalTypeVarReturn] |
| # flags: --strict-optional |
| from typing import Callable, Iterable, List, Optional, TypeVar |
| |
| class C: |
| x: str |
| |
| T = TypeVar('T') |
| def f(i: Iterable[T], c: Callable[[T], str]) -> Optional[T]: ... |
| |
| def g(l: List[C], x: str) -> Optional[C]: |
| def pred(c: C) -> str: |
| return c.x |
| return f(l, pred) |
| [builtins fixtures/list.pyi] |
| |
| [case testWideOuterContextOptionalTypeVarReturnLambda] |
| # flags: --strict-optional |
| from typing import Callable, Iterable, List, Optional, TypeVar |
| |
| class C: |
| x: str |
| |
| T = TypeVar('T') |
| def f(i: Iterable[T], c: Callable[[T], str]) -> Optional[T]: ... |
| |
| def g(l: List[C], x: str) -> Optional[C]: |
| return f(l, lambda c: reveal_type(c).x) # N: Revealed type is '__main__.C' |
| [builtins fixtures/list.pyi] |
| |
| [case testWideOuterContextEmpty] |
| from typing import List, TypeVar |
| |
| T = TypeVar('T', bound=int) |
| def f(x: List[T]) -> T: ... |
| |
| # mypy infers List[<nothing>] here, and <nothing> is a subtype of str |
| y: str = f([]) |
| [builtins fixtures/list.pyi] |
| |
| [case testWideOuterContextEmptyError] |
| from typing import List, TypeVar |
| |
| T = TypeVar('T', bound=int) |
| def f(x: List[T]) -> List[T]: ... |
| |
| # TODO: improve error message for such cases, see #3283 and #5706 |
| y: List[str] = f([]) \ |
| # E: Incompatible types in assignment (expression has type "List[<nothing>]", variable has type "List[str]") \ |
| # N: "List" is invariant -- see http://mypy.readthedocs.io/en/latest/common_issues.html#variance \ |
| # N: Consider using "Sequence" instead, which is covariant |
| [builtins fixtures/list.pyi] |
| |
| [case testWideOuterContextNoArgs] |
| # flags: --strict-optional |
| from typing import TypeVar, Optional |
| |
| T = TypeVar('T', bound=int) |
| def f(x: Optional[T] = None) -> T: ... |
| |
| y: str = f() |
| |
| [case testWideOuterContextNoArgsError] |
| # flags: --strict-optional |
| from typing import TypeVar, Optional, List |
| |
| T = TypeVar('T', bound=int) |
| def f(x: Optional[T] = None) -> List[T]: ... |
| |
| y: List[str] = f() \ |
| # E: Incompatible types in assignment (expression has type "List[<nothing>]", variable has type "List[str]") \ |
| # N: "List" is invariant -- see http://mypy.readthedocs.io/en/latest/common_issues.html#variance \ |
| # N: Consider using "Sequence" instead, which is covariant |
| [builtins fixtures/list.pyi] |
| |
| [case testUseCovariantGenericOuterContext] |
| from typing import TypeVar, Callable, Tuple |
| |
| T = TypeVar('T') |
| |
| def f(x: Callable[..., T]) -> T: |
| return x() |
| |
| x: Tuple[str, ...] = f(tuple) |
| [builtins fixtures/tuple.pyi] |
| [out] |
| |
| [case testUseCovariantGenericOuterContextUserDefined] |
| from typing import TypeVar, Callable, Generic |
| |
| T_co = TypeVar('T_co', covariant=True) |
| T = TypeVar('T') |
| |
| class G(Generic[T_co]): ... |
| |
| def f(x: Callable[..., T]) -> T: |
| return x() |
| |
| x: G[str] = f(G) |
| [out] |