-- Test cases for type variables with values restriction. [case testCallGenericFunctionWithTypeVarValueRestriction] from typing import TypeVar T = TypeVar('T', int, str) def f(x: T) -> None: pass f(1) f('x') f(object()) # E: Value of type variable "T" of "f" cannot be "object" [case testCallGenericFunctionWithTypeVarValueRestrictionUsingContext] from typing import TypeVar, List T = TypeVar('T', int, str) def f(x: T) -> List[T]: pass i = [1] s = ['x'] o = [object()] if int(): i = f(1) s = f('') o = f(1) \ # E: Incompatible types in assignment (expression has type "list[int]", variable has type "list[object]") \ # 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] [case testCallGenericFunctionWithTypeVarValueRestrictionAndAnyArgs] from typing import TypeVar, Any, cast T = TypeVar('T', int, str) def f(x: T) -> None: pass f(cast(Any, object())) [out] [case testCallGenericFunctionWithTypeVarValueRestrictionInDynamicFunc] from typing import TypeVar, Any T = TypeVar('T', int, str) def f(x: T) -> None: pass def g(): f(object()) [out] [case testCallGenericFunctionWithTypeVarValueRestrictionUsingSubtype] from typing import TypeVar T = TypeVar('T', int, str) def f(x: T) -> None: pass class S(str): pass f(S()) [out] [case testCheckGenericFunctionBodyWithTypeVarValues] from typing import TypeVar class A: def f(self, x: int) -> A: return self class B: def f(self, x: int) -> B: return self AB = TypeVar('AB', A, B) def f(x: AB) -> AB: x = x.f(1) return x.f(1) [case testCheckGenericFunctionBodyWithTypeVarValues2] from typing import TypeVar class A: def f(self) -> A: return A() def g(self) -> B: return B() class B: def f(self) -> A: return A() def g(self) -> B: return B() AB = TypeVar('AB', A, B) def f(x: AB) -> AB: return x.f() # Error def g(x: AB) -> AB: return x.g() # Error [out] main:10: error: Incompatible return value type (got "A", expected "B") main:12: error: Incompatible return value type (got "B", expected "A") [case testTypeInferenceAndTypeVarValues] from typing import TypeVar class A: def f(self) -> A: return self def g(self) -> B: return B() class B: def f(self) -> B: return self def g(self) -> B: return B() AB = TypeVar('AB', A, B) def f(x: AB) -> AB: y = x if y: return y.f() else: return y.g() # E: Incompatible return value type (got "B", expected "A") [out] [case testTypeDeclaredBasedOnTypeVarWithValues] from typing import TypeVar T = TypeVar('T', int, str) def f(x: T) -> T: a: T b: T if 1: a = x b = x a = '' # E: Incompatible types in assignment (expression has type "str", variable has type "int") b = 1 # E: Incompatible types in assignment (expression has type "int", variable has type "str") return x [out] [case testIsinstanceAndTypeVarValues] from typing import TypeVar T = TypeVar('T', int, str) def f(x: T) -> T: if isinstance(x, int): return 2 return x def g(x: T) -> T: if isinstance(x, str): return '' return x def h(x: T) -> T: if isinstance(x, int): return '' # E: Incompatible return value type (got "str", expected "int") return x [builtins fixtures/isinstance.pyi] [out] [case testIsinstanceAndTypeVarValues2] from typing import TypeVar T = TypeVar('T', int, str) def f(x: T) -> T: if isinstance(x, int): return 2 else: return '' def g(x: T) -> T: if isinstance(x, int): return '' # E: Incompatible return value type (got "str", expected "int") else: return 2 # E: Incompatible return value type (got "int", expected "str") return x [builtins fixtures/isinstance.pyi] [out] [case testIsinstanceAndTypeVarValues3] from typing import TypeVar T = TypeVar('T', int, str) def f(x: T) -> T: if isinstance(x, int): y = 1 else: y = '' return y [builtins fixtures/isinstance.pyi] [case testIsinstanceAndTypeVarValues4] from typing import TypeVar T = TypeVar('T', int, str) def f(x: T) -> T: if isinstance(x, int): y = 1 else: y = object() return y # E: Incompatible return value type (got "object", expected "str") [builtins fixtures/isinstance.pyi] [out] [case testIsinstanceAndTypeVarValues5] from typing import TypeVar T = TypeVar('T', int, str) def f(x: T) -> T: if isinstance(x, int): y = object() else: y = '' return y # E: Incompatible return value type (got "object", expected "int") [builtins fixtures/isinstance.pyi] [out] [case testIsinstanceWithUserDefinedTypeAndTypeVarValues] # flags: --warn-unreachable from typing import TypeVar class A: pass class B: pass T1 = TypeVar('T1', A, B) def f1(x: T1) -> None: y = x if isinstance(x, A): x = y x = A() # E: Incompatible types in assignment (expression has type "A", variable has type "B") else: x = B() x = y x.foo() # E: "B" has no attribute "foo" class C: field: int class D: field: str T2 = TypeVar('T2', C, D) def f2(x: T2) -> None: y = x if isinstance(x, C): # C and D are non-overlapping, so this branch is never checked x = y x = C() else: x = D() x = y x.foo() # E: "D" has no attribute "foo" S = TypeVar('S', int, str) def g(x: S) -> None: y = x if isinstance(x, int): x = y [builtins fixtures/isinstance.pyi] [out] [case testIsinstanceWithUserDefinedTypeAndTypeVarValues2] from typing import TypeVar class S(str): pass T = TypeVar('T', S, int) def f(x: T) -> None: y = x if isinstance(x, S): # This is checked only when type of x is str. x = y x = S() x = 1 # E: Incompatible types in assignment (expression has type "int", variable has type "S") else: x = y x = 1 x = S() # E: Incompatible types in assignment (expression has type "S", variable has type "int") [builtins fixtures/isinstance.pyi] [out] [case testTypeVarValuesAndNestedCalls] from typing import TypeVar T = TypeVar('T', int, str) def f(m: T) -> int: pass def h(x: int) -> int: pass def g(a: T) -> None: h(f(a)) [out] [case testGenericTypeWithTypevarValues] from typing import TypeVar, Generic, Any X = TypeVar('X', int, str) class A(Generic[X]): pass a: A[int] b: A[str] d: A[object] # E: Value of type variable "X" of "A" cannot be "object" c: A[Any] [case testConstructGenericTypeWithTypevarValuesAndTypeInference] from typing import TypeVar, Generic, Any, cast X = TypeVar('X', int, str) class A(Generic[X]): def __init__(self, x: X) -> None: pass A(1) A('x') A(cast(Any, object())) A(object()) # E: Value of type variable "X" of "A" cannot be "object" [case testGenericTypeWithTypevarValuesAndTypevarArgument] from typing import TypeVar, Generic class C: pass X = TypeVar('X', int, str) Y = TypeVar('Y', int, C) Z = TypeVar('Z') class D(Generic[X]): def __init__(self, x: X) -> None: pass def f(x: X) -> None: a: D[X] def g(x: Y) -> None: a: D[Y] def h(x: Z) -> None: a: D[Z] [out] main:11: error: Invalid type argument value for "D" main:13: error: Type variable "Z" not valid as type argument value for "D" [case testGenericTypeWithTypevarValuesAndSubtypePromotion] from typing import TypeVar, Generic X = TypeVar('X', int, str) class S(str): pass class C(Generic[X]): def __init__(self, x: X) -> None: pass x: C[str] y = C(S()) if int(): x = y y = x c_int = C(1) # type: C[int] if int(): y = c_int # E: Incompatible types in assignment (expression has type "C[int]", variable has type "C[str]") [case testGenericTypeBodyWithTypevarValues] from typing import TypeVar, Generic class A: def f(self, x: int) -> None: pass def g(self, x: int) -> None: pass def h(self, x: str) -> None: pass class B: def f(self, x: int) -> None: pass def g(self, x: str) -> None: pass def h(self, x: int) -> None: pass X = TypeVar('X', A, B) class C(Generic[X]): def f(self, x: X) -> None: x.f(1) x.g(1) # E: Argument 1 to "g" of "B" has incompatible type "int"; expected "str" x.h(1) # E: Argument 1 to "h" of "A" has incompatible type "int"; expected "str" [out] [case testAttributeInGenericTypeWithTypevarValues1] from typing import TypeVar, Generic X = TypeVar('X', int, str) class C(Generic[X]): x: X def f(self, x: X) -> None: self.x = x self.x = 1 # E: Incompatible types in assignment (expression has type "int", variable has type "str") [out] [case testAttributeInGenericTypeWithTypevarValues2] from typing import TypeVar, Generic X = TypeVar('X', int, str) class C(Generic[X]): x: X cn = C() # type: C[int] cn.x = 1 cn.x = '' # E: Incompatible types in assignment (expression has type "str", variable has type "int") cs = C() # type: C[str] cs.x = '' cs.x = 1 # E: Incompatible types in assignment (expression has type "int", variable has type "str") [case testAttributeInGenericTypeWithTypevarValues3] from typing import TypeVar, Generic X = TypeVar('X', int, str) class C(Generic[X]): def f(self, x: X) -> None: self.x = x # type: X ci: C[int] cs: C[str] reveal_type(ci.x) # N: Revealed type is "builtins.int" reveal_type(cs.x) # N: Revealed type is "builtins.str" [case testAttributeInGenericTypeWithTypevarValuesUsingInference1] from typing import TypeVar, Generic X = TypeVar('X', int, str) class C(Generic[X]): def f(self, x: X) -> None: self.x = x # E: Need type annotation for "x" ci: C[int] cs: C[str] reveal_type(ci.x) # N: Revealed type is "Any" reveal_type(cs.x) # N: Revealed type is "Any" [case testAttributeInGenericTypeWithTypevarValuesUsingInference2] from typing import TypeVar, Generic X = TypeVar('X', int, str) class C(Generic[X]): def f(self, x: X) -> None: self.x = 1 reveal_type(self.x) # N: Revealed type is "builtins.int" ci: C[int] cs: C[str] reveal_type(ci.x) # N: Revealed type is "builtins.int" reveal_type(cs.x) # N: Revealed type is "builtins.int" [case testAttributeInGenericTypeWithTypevarValuesUsingInference3] from typing import TypeVar, Generic X = TypeVar('X', int, str) class C(Generic[X]): x: X def f(self) -> None: self.y = self.x # E: Need type annotation for "y" ci: C[int] cs: C[str] reveal_type(ci.y) # N: Revealed type is "Any" reveal_type(cs.y) # N: Revealed type is "Any" [case testInferredAttributeInGenericClassBodyWithTypevarValues] from typing import TypeVar, Generic X = TypeVar('X', int, str) class C(Generic[X]): x = 1 C.x = 1 C.x = '' # E: Incompatible types in assignment (expression has type "str", variable has type "int") [case testMultipleClassTypevarsWithValues1] from typing import TypeVar, Generic class A: def f(self, x: int) -> None: pass class B: def f(self, x: str) -> None: pass X = TypeVar('X', A, B) Y = TypeVar('Y', int, str) class C(Generic[X, Y]): def f(self, x: X, y: Y) -> None: x.f(y) [out] main:10: error: Argument 1 to "f" of "A" has incompatible type "str"; expected "int" main:10: error: Argument 1 to "f" of "B" has incompatible type "int"; expected "str" [case testMultipleClassTypevarsWithValues2] from typing import TypeVar, Generic class A: pass class B: pass X = TypeVar('X', A, B) Y = TypeVar('Y', int, str) class C(Generic[X, Y]): pass a: C[A, int] b: C[B, str] c: C[int, int] # E: Value of type variable "X" of "C" cannot be "int" d: C[A, A] # E: Value of type variable "Y" of "C" cannot be "A" [case testCallGenericFunctionUsingMultipleTypevarsWithValues] from typing import TypeVar class A: pass class B: pass X = TypeVar('X', A, B) Y = TypeVar('Y', int, str) def f(x: X, y: Y) -> None: pass f(A(), '') f(B(), 1) f(A(), A()) # E: Value of type variable "Y" of "f" cannot be "A" f(1, 1) # E: Value of type variable "X" of "f" cannot be "int" [case testGenericFunctionWithNormalAndRestrictedTypevar] from typing import TypeVar, Generic X = TypeVar('X') Y = TypeVar('Y', int, str) class C(Generic[Y]): def __init__(self, y: Y) -> None: pass def f(x: X, y: Y, z: int) -> None: C(y) C(x) # Error if int(): z = x # Error z = y # Error y.foo # Error [out] main:8: error: Value of type variable "Y" of "C" cannot be "X" main:10: error: Incompatible types in assignment (expression has type "X", variable has type "int") main:11: error: Incompatible types in assignment (expression has type "str", variable has type "int") main:12: error: "int" has no attribute "foo" main:12: error: "str" has no attribute "foo" [case testTypeVarWithValueInferredFromObjectReturnTypeContext] from typing import TypeVar T = TypeVar('T', int, str) def c1(x: object) -> None: pass def c2(x: int) -> None: pass def c3(x: str) -> None: pass def g(x: T) -> T: pass c1(g('')) c2(g(1)) c3(g('')) c2(g('')) # E: Argument 1 to "c2" has incompatible type "str"; expected "int" c3(g(1)) # E: Argument 1 to "c3" has incompatible type "int"; expected "str" [case testTypeVarWithValueInferredFromObjectReturnTypeContext2] from typing import TypeVar T = TypeVar('T', int, str) class ss(str): pass def c(x: ss) -> None: pass def g(x: T) -> T: pass c(g('')) c(g(1)) [out] main:6: error: Argument 1 to "c" has incompatible type "str"; expected "ss" main:7: error: Argument 1 to "c" has incompatible type "int"; expected "ss" [case testDefineAttributeInGenericMethodUsingTypeVarWithValues] from typing import TypeVar T = TypeVar('T', int, str) class A: def f(self, x: T) -> None: self.x = x # E: Need type annotation for "x" self.y = [x] # E: Need type annotation for "y" self.z = 1 reveal_type(A().x) # N: Revealed type is "Any" reveal_type(A().y) # N: Revealed type is "Any" reveal_type(A().z) # N: Revealed type is "builtins.int" [builtins fixtures/list.pyi] -- Special cases -- ------------- [case testTypevarValuesSpecialCase1] from typing import TypeVar, Generic from abc import abstractmethod T = TypeVar('T', int, str) class A(Generic[T]): @abstractmethod def f(self) -> 'A[T]': pass class B(A[str]): @abstractmethod def f(self) -> 'B': pass class C(A[str]): @abstractmethod def f(self) -> int: # E: Return type "int" of "f" incompatible with return type "A[str]" in supertype "A" pass [out] [case testDefaultArgumentValueInGenericClassWithTypevarValues] from typing import TypeVar, Generic T = TypeVar('T', int, str) class C(Generic[T]): def f(self, x: int = 2) -> None: pass [case testTypevarValuesWithOverloadedFunctionSpecialCase] from foo import * [file foo.pyi] from typing import TypeVar, overload, Callable T = TypeVar('T', int, str) def f(x: T) -> None: y = m(g, x) if int(): x = y y = object() # Error A = TypeVar('A') R = TypeVar('R') def m(f: Callable[[A], R], it: A) -> A: pass @overload def g(x: int) -> int: return x @overload def g(x: str) -> str: return x [out] tmp/foo.pyi:8: error: Incompatible types in assignment (expression has type "object", variable has type "int") tmp/foo.pyi:8: error: Incompatible types in assignment (expression has type "object", variable has type "str") [case testGenericFunctionSubtypingWithTypevarValues] from typing import TypeVar class A: pass T = TypeVar('T', int, str) U = TypeVar('U', str, A, int) def f(x: T) -> T: pass def g(x: U) -> U: pass a = f if int(): a = f if int(): a = g b = g if int(): b = g if int(): b = f # E: Incompatible types in assignment (expression has type "Callable[[T], T]", variable has type "Callable[[U], U]") [case testInnerFunctionWithTypevarValues] from typing import TypeVar T = TypeVar('T', int, str) U = TypeVar('U', int, str) def outer(x: T) -> T: def inner(y: T) -> T: return x def inner2(y: U) -> U: return y inner(x) inner(3) # E: Argument 1 to "inner" has incompatible type "int"; expected "str" inner2(x) inner2(3) outer(3) return x [out] [case testInnerFunctionMutualRecursionWithTypevarValues] from typing import TypeVar T = TypeVar('T', int, str) def outer(x: T) -> T: def inner1(y: T) -> T: return inner2(y) def inner2(y: T) -> T: return inner1('a') # E: Argument 1 to "inner1" has incompatible type "str"; expected "int" return inner1(x) [out] [case testClassMemberTypeVarInFunctionBody] from typing import TypeVar, List S = TypeVar('S') class C: T = TypeVar('T', bound=int) def f(self, x: T) -> T: L = List[S] y: L[C.T] = [x] reveal_type(C.T) # N: Revealed type is "typing.TypeVar" return y[0] [builtins fixtures/list.pyi] [typing fixtures/typing-full.pyi] [case testTypeVarWithAnyTypeBound] # flags: --follow-imports=skip from typing import Type, TypeVar from a import A T = TypeVar('T', bound=A) def method(t: Type[T]) -> None: t.a [file a.py] class A: a: int = 7 [out] [case testParameterLessGenericAsRestriction] from typing import Sequence, Iterable, TypeVar S = TypeVar('S', Sequence, Iterable) def my_len(s: S) -> None: pass def crash() -> None: my_len((0,)) [builtins fixtures/tuple.pyi] [case testReferenceToDecoratedFunctionAndTypeVarValues] from typing import TypeVar, Callable T = TypeVar('T') S = TypeVar('S', int, str) def dec(f: Callable[..., T]) -> Callable[..., T]: ... @dec def g(s: S) -> Callable[[S], None]: ... def f(x: S) -> None: h = g(x) h(x) [case testTypeVarWithTypedDictBoundInIndexExpression] from typing import TypedDict, TypeVar class Data(TypedDict): x: int T = TypeVar("T", bound=Data) def f(data: T) -> None: reveal_type(data["x"]) # N: Revealed type is "builtins.int" [builtins fixtures/dict.pyi] [typing fixtures/typing-typeddict.pyi] [case testTypeVarWithUnionTypedDictBoundInIndexExpression] from typing import TypedDict, TypeVar, Union, Dict class Data(TypedDict): x: int T = TypeVar("T", bound=Union[Data, Dict[str, str]]) def f(data: T) -> None: reveal_type(data["x"]) # N: Revealed type is "builtins.int | builtins.str" [builtins fixtures/dict.pyi] [typing fixtures/typing-typeddict.pyi] [case testTypeVarWithTypedDictValueInIndexExpression] from typing import TypedDict, TypeVar, Union, Dict class Data(TypedDict): x: int T = TypeVar("T", Data, Dict[str, str]) def f(data: T) -> None: _: Union[str, int] = data["x"] [builtins fixtures/dict.pyi] [typing fixtures/typing-typeddict.pyi] [case testSelfTypeVarIndexExpr] from typing import TypedDict, TypeVar, Union, Type T = TypeVar("T", bound="Indexable") class Indexable: def __init__(self, index: str) -> None: self.index = index def __getitem__(self: T, index: str) -> T: return self._new_instance(index) @classmethod def _new_instance(cls: Type[T], index: str) -> T: return cls("foo") def m(self: T) -> T: return self["foo"] [builtins fixtures/classmethod.pyi] [typing fixtures/typing-full.pyi] [case testTypeVarWithValueDeferral] from typing import TypeVar, Callable T = TypeVar("T", "A", "B") Func = Callable[[], T] class A: ... class B: ... [case testTypeCommentInGenericTypeWithConstrainedTypeVar] from typing import Generic, TypeVar NT = TypeVar("NT", int, float) class Foo1(Generic[NT]): p = 1 # type: int class Foo2(Generic[NT]): p, q = 1, 2.0 # type: (int, float) class Foo3(Generic[NT]): def bar(self) -> None: p = 1 # type: int class Foo4(Generic[NT]): def bar(self) -> None: p, q = 1, 2.0 # type: (int, float) def foo3(x: NT) -> None: p = 1 # type: int def foo4(x: NT) -> None: p, q = 1, 2.0 # type: (int, float) [builtins fixtures/tuple.pyi] [case testTypeVarValuesNarrowing] from typing import TypeVar W = TypeVar("W", int, str) def fn(w: W) -> W: if type(w) is str: reveal_type(w) # N: Revealed type is "builtins.str" elif type(w) is int: reveal_type(w) # N: Revealed type is "builtins.int" return w [builtins fixtures/isinstance.pyi]