blob: 76730931c8e92c71b345165c00f6216bbcd99f2b [file]
-- 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
ao = f()
ab = f()
b = f() # E: Incompatible types in assignment (expression has type A[None], 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
ao = A()
ab = A()
b = A() # E: Incompatible types in assignment (expression has type A[None], 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]
ac = f(b) # E: Argument 1 to "f" has incompatible type "B"; expected "C"
ab = f(c) # E: Argument 1 to "f" has incompatible type "C"; expected "B"
ao = f(b)
ab = f(b)
ao = f(c)
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)
ab = x # E: Incompatible types in assignment (expression has type A[object], variable has type A[B])
ao = x
y = f(b)
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 variable
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)
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))
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]
ab, ao = f(b) # Fail
ao, ab = f(b) # Fail
ao, ao = f(b)
ab, ab = f(b)
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]
[out]
main:8: error: Incompatible types in assignment (expression has type A[B], variable has type A[object])
main:9: error: Incompatible types in assignment (expression has type A[B], variable has type A[object])
[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]
ao, ao, ab = f(b, b) # Fail
ao, ab, ao = g(b, b) # Fail
ao, ab, ab, ab = h(b, b) # Fail
ab, ab, ao, ab = h(b, b) # Fail
ao, ab, ab = f(b, b)
ab, ab, ao = g(b, b)
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]
[out]
main:9: error: Incompatible types in assignment (expression has type A[B], variable has type A[object])
main:10: error: Incompatible types in assignment (expression has type A[B], variable has type A[object])
main:11: error: Incompatible types in assignment (expression has type A[B], variable has type A[object])
main:12: error: Incompatible types in assignment (expression has type A[B], variable has type A[object])
-- 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
ab = f(b, o) # E: Argument 2 to "f" has incompatible type "object"; expected "B"
ab = f(o, b) # E: Argument 1 to "f" has incompatible type "object"; expected "B"
ac = f(b, c) # E: Argument 1 to "f" has incompatible type "B"; expected "C"
ac = f(c, b) # E: Argument 2 to "f" has incompatible type "B"; expected "C"
ao = f(b, c)
ao = f(c, b)
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
aab = f(f(o)) # E: Argument 1 to "f" has incompatible type "object"; expected "B"
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
ab = f(g(o)) # E: Argument 1 to "g" has incompatible type "object"; expected "B"
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
ab = f(g(o), g(b)) # E: Argument 1 to "g" has incompatible type "object"; expected "B"
ab = f(g(b), g(o)) # E: Argument 1 to "g" has incompatible type "object"; expected "B"
ab = f(g(b), g(b))
ao = f(g(b), g(o))
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"
ac = f(b).g(f(c)) # E: Incompatible types in assignment (expression has type A[B], variable has type A[C])
ac = f(c).g(f(b)) # E: Argument 1 to "f" has incompatible type "B"; expected "C"
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
a = [] # E: Incompatible types in assignment (expression has type List[None], 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
aa = [b] # E: List item 0 has incompatible type "B"
ab = [a] # E: List item 0 has incompatible type "A"
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
ab = [b, a] # E: List item 1 has incompatible type "A"
ab = [a, b] # E: List item 0 has incompatible type "A"
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 variable
b = [None] # E: Need type annotation for variable
c = [B()]
c = [object()] # E: List item 0 has incompatible type "object"
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
aao = [[o], ab] # E: List item 1 has incompatible type List[B]
aab = [[], [o]] # E: List item 0 has incompatible type "object"
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 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])
l = set([object()]) # E: List item 0 has incompatible type "object"
[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]
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]]
f = lambda: []
f = lambda: [B()] # E: List item 0 has incompatible type "B"
class A: pass
class B: pass
[builtins fixtures/list.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) # E: Revealed type is 'def (x: Any) -> Any'
reveal_type(lambda x: 1) # E: Revealed type is 'def (x: Any) -> builtins.int'
[case testLambdaContextVararg]
from typing import Callable
def f(t: Callable[[str], str]) -> str: ''
f(lambda *_: '')
[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: Incompatible types in assignment (expression has type Callable[[Any], A], variable has type Callable[[], A])
main:2: error: Cannot infer type of lambda
main:3: error: Incompatible types in assignment (expression has type Callable[[], A], variable has type Callable[[A], A])
main:3: error: Cannot infer type of lambda
[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( # E: Argument 1 to "f" has incompatible type Callable[[A], A]; expected Callable[[A], B]
lambda x: 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 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])
a = a or []
a = [] or a
b = b or [C()]
a = a or b # E: Incompatible types in assignment (expression has type "Union[List[A], List[B]]", variable has type List[A])
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]
a = f(A(), B())
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]
a = f(A(), B())
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]
i = i = []
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"
[builtins fixtures/list.pyi]
[case testListMultiplyInContext]
from typing import List
a = None # type: List[int]
a = [None] * 3
a = [''] * 3 # E: List item 0 has incompatible type "str"
[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[None], 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")