blob: d1842a74d634aba68b43b5e1eb302b88b3b4005b [file] [log] [blame]
-- Simple generic types
-- --------------------
[case testGenericMethodReturnType]
from typing import TypeVar, Generic
T = TypeVar('T')
a: A[B]
b: B
c: C
if int():
c = a.f() # E: Incompatible types in assignment (expression has type "B", variable has type "C")
b = a.f()
class A(Generic[T]):
def f(self) -> T: pass
class B: pass
class C: pass
[builtins fixtures/tuple.pyi]
[case testGenericMethodArgument]
from typing import TypeVar, Generic
T = TypeVar('T')
class A(Generic[T]):
def f(self, a: T) -> None: pass
a: A[B]
b: B
c: C
a.f(c) # E: Argument 1 to "f" of "A" has incompatible type "C"; expected "B"
a.f(b)
class B: pass
class C: pass
[case testGenericMemberVariable]
from typing import TypeVar, Generic
T = TypeVar('T')
class A(Generic[T]):
def __init__(self, v: T) -> None:
self.v = v
a: A[B]
b: B
c: C
a.v = c # Fail
a.v = b
class B: pass
class C: pass
[builtins fixtures/tuple.pyi]
[out]
main:10: error: Incompatible types in assignment (expression has type "C", variable has type "B")
[case testGenericMemberVariable2]
from typing import TypeVar, Generic
T = TypeVar('T')
a: A[B]
b: B
c: C
a.v = c # Fail
a.v = b
class A(Generic[T]):
v: T
class B: pass
class C: pass
[builtins fixtures/tuple.pyi]
[out]
main:6: error: Incompatible types in assignment (expression has type "C", variable has type "B")
[case testSimpleGenericSubtyping]
from typing import TypeVar, Generic
T = TypeVar('T')
b: A[B]
bb: A[B]
c: A[C]
if int():
c = b # E: Incompatible types in assignment (expression has type "A[B]", variable has type "A[C]")
b = c # E: Incompatible types in assignment (expression has type "A[C]", variable has type "A[B]")
if int():
b = b
if int():
b = bb
class A(Generic[T]): pass
class B: pass
class C(B): pass
[builtins fixtures/tuple.pyi]
[case testGenericTypeCompatibilityWithAny]
from typing import Any, TypeVar, Generic
T = TypeVar('T')
b: A[B]
c: A[C]
d: A[Any]
b = d
c = d
d = b
d = c
class A(Generic[T]): pass
class B: pass
class C(B): pass
[builtins fixtures/tuple.pyi]
[out]
[case testTypeVariableAsTypeArgument]
from typing import TypeVar, Generic
T = TypeVar('T')
a: A[B]
b: A[B]
c: A[C]
a.v = c # E: Incompatible types in assignment (expression has type "A[C]", variable has type "A[B]")
if int():
c = a.v # E: Incompatible types in assignment (expression has type "A[B]", variable has type "A[C]")
a.v = b
if int():
b = a.v
class A(Generic[T]):
v = None # type: A[T]
class B: pass
class C: pass
[case testMultipleGenericTypeParametersWithMemberVars]
from typing import TypeVar, Generic
S = TypeVar('S')
T = TypeVar('T')
a: A[B, C]
s: B
t: C
if int():
t = a.s # E: Incompatible types in assignment (expression has type "B", variable has type "C")
s = a.t # E: Incompatible types in assignment (expression has type "C", variable has type "B")
if int():
s = a.s
t = a.t
class A(Generic[S, T]):
s: S
t: T
class B: pass
class C: pass
[case testMultipleGenericTypeParametersWithMethods]
from typing import TypeVar, Generic
S = TypeVar('S')
T = TypeVar('T')
a: A[B, C]
s: B
t: C
a.f(s, s) # Fail
a.f(t, t) # Fail
a.f(s, t)
class A(Generic[S, T]):
def f(self, s: S, t: T) -> None: pass
class B: pass
class C: pass
[out]
main:8: error: Argument 2 to "f" of "A" has incompatible type "B"; expected "C"
main:9: error: Argument 1 to "f" of "A" has incompatible type "C"; expected "B"
[case testMultipleGenericTypeParametersAndSubtyping]
from typing import TypeVar, Generic
S = TypeVar('S')
T = TypeVar('T')
bc: A[B, C]
bb: A[B, B]
cb: A[C, B]
if int():
bb = bc # E: Incompatible types in assignment (expression has type "A[B, C]", variable has type "A[B, B]")
if int():
bb = cb # E: Incompatible types in assignment (expression has type "A[C, B]", variable has type "A[B, B]")
bc = bb # E: Incompatible types in assignment (expression has type "A[B, B]", variable has type "A[B, C]")
if int():
bb = bb
bc = bc
class A(Generic[S, T]):
s: S
t: T
class B: pass
class C(B):pass
-- Simple generic type bodies
-- --------------------------
[case testGenericTypeBody1]
from typing import TypeVar, Generic
T = TypeVar('T')
class A(Generic[T]):
a: T
def f(self, b: T) -> T:
self.f(x) # Fail
d = self # type: A[B] # Fail
self.a = self.f(self.a)
return self.a
c = self # type: A[T]
x: B
class B: pass
[out]
main:7: error: Argument 1 to "f" of "A" has incompatible type "B"; expected "T"
main:8: error: Incompatible types in assignment (expression has type "A[T]", variable has type "A[B]")
[case testGenericTypeBodyWithMultipleVariables]
from typing import TypeVar, Generic
S = TypeVar('S')
T = TypeVar('T')
class A(Generic[S, T]):
def f(self) -> None:
s: S
t: T
if int():
s = t # E: Incompatible types in assignment (expression has type "T", variable has type "S")
t = s # E: Incompatible types in assignment (expression has type "S", variable has type "T")
a = self # type: A[S, B] # E: Incompatible types in assignment (expression has type "A[S, T]", variable has type "A[S, B]")
b = self # type: A[T, T] # E: Incompatible types in assignment (expression has type "A[S, T]", variable has type "A[T, T]")
c = self # type: A[S, T]
if int():
t = t
class B: pass
[out]
[case testCompatibilityOfNoneWithTypeVar]
# flags: --no-strict-optional
from typing import TypeVar, Generic
T = TypeVar('T')
class A(Generic[T]):
def f(self) -> None:
a = None # type: T
a = None
[out]
[case testCompatibilityOfTypeVarWithObject]
# flags: --no-strict-optional
from typing import TypeVar, Generic
T = TypeVar('T')
class A(Generic[T]):
def f(self) -> T:
a = object() # type: T # E: Incompatible types in assignment (expression has type "object", variable has type "T")
if int():
a = object() # E: Incompatible types in assignment (expression has type "object", variable has type "T")
b = self.f() # type: object
if int():
b = self.f()
return None
[out]
-- Operations with generic types
-- -----------------------------
[case testGenericOperations]
from typing import TypeVar, Generic
S = TypeVar('S')
T = TypeVar('T')
a: A[B, C]
b: B
c: C
if int():
b = a + b # E: Incompatible types in assignment (expression has type "C", variable has type "B")
c = a + c # E: Unsupported operand types for + ("A[B, C]" and "C")
if int():
c = a[c] # E: Incompatible types in assignment (expression has type "B", variable has type "C")
b = a[b] # E: Invalid index type "B" for "A[B, C]"; expected type "C"
if int():
c = a + b
b = a[c]
class A(Generic[S, T]):
def __add__(self, a: S) -> T: pass
def __getitem__(self, i: T) -> S: pass
class B: pass
class C: pass
[case testOperatorAssignmentWithIndexLvalue1]
from typing import TypeVar, Generic
T = TypeVar('T')
b: B
c: C
ac: A[C]
ac[b] += b # Fail
ac[c] += c # Fail
ac[b] += c
ac[b] = ac[b] + c
class A(Generic[T]):
def __getitem__(self, i: 'B') -> T: pass
def __setitem__(self, i: 'B', v: T) -> None: pass
class B: pass
class C:
def __add__(self, o: 'C') -> 'C': pass
[out]
main:7: error: Unsupported operand types for + ("C" and "B")
main:8: error: Invalid index type "C" for "A[C]"; expected type "B"
[case testOperatorAssignmentWithIndexLvalue2]
from typing import TypeVar, Generic
T = TypeVar('T')
b: B
c: C
ac: A[C]
ac[b] += c # Fail
ac[c] += c # Fail
ac[b] = ac[b] + c # Fail
class A(Generic[T]):
def __getitem__(self, i: 'B') -> T: pass
def __setitem__(self, i: 'C', v: T) -> None: pass
class B: pass
class C:
def __add__(self, o: 'C') -> 'C': pass
[out]
main:7: error: Invalid index type "B" for "A[C]"; expected type "C"
main:8: error: Invalid index type "C" for "A[C]"; expected type "B"
main:9: error: Invalid index type "B" for "A[C]"; expected type "C"
-- Nested generic types
-- --------------------
[case testNestedGenericTypes]
from typing import TypeVar, Generic
T = TypeVar('T')
aab: A[A[B]]
aac: A[A[C]]
ab: A[B]
ac: A[C]
if int():
ac = aab.x # E: Incompatible types in assignment (expression has type "A[B]", variable has type "A[C]")
ac.y = aab # E: Incompatible types in assignment (expression has type "A[A[B]]", variable has type "A[A[C]]")
if int():
ab = aab.x
ac = aac.x
ab.y = aab
ac.y = aac
class A(Generic[T]):
x: T
y: A[A[T]]
class B:
pass
class C:
pass
-- Generic functions
-- -----------------
[case testTypeCheckingGenericFunctionBody]
from typing import TypeVar, Generic
S = TypeVar('S')
T = TypeVar('T')
class A: pass
class p(Generic[T, S]):
def __init__(self, t: T, a: S) -> None: pass
def f(s: S, t: T) -> p[T, A]:
a = t # type: S # E: Incompatible types in assignment (expression has type "T", variable has type "S")
if int():
s = t # E: Incompatible types in assignment (expression has type "T", variable has type "S")
p_s_a: p[S, A]
if s:
return p_s_a # E: Incompatible return value type (got "p[S, A]", expected "p[T, A]")
b = t # type: T
c = s # type: S
p_t_a: p[T, A]
return p_t_a
[out]
[case testTypeCheckingGenericMethodBody]
from typing import TypeVar, Generic
T = TypeVar('T')
S = TypeVar('S')
class p(Generic[T, S]):
def __init__(self, t: T, a: S) -> None: pass
class A(Generic[T]):
def f(self, s: S, t: T) -> p[S, T]:
if int():
s = t # E: Incompatible types in assignment (expression has type "T", variable has type "S")
p_s_s: p[S, S]
if s:
return p_s_s # E: Incompatible return value type (got "p[S, S]", expected "p[S, T]")
p_t_t: p[T, T]
if t:
return p_t_t # E: Incompatible return value type (got "p[T, T]", expected "p[S, T]")
if 1:
t = t
s = s
p_s_t: p[S, T]
return p_s_t
[out]
[case testProhibitTypeApplicationToGenericFunctions]
from typing import TypeVar
T = TypeVar('T')
def f(x: T) -> T: pass
y = f[int] # E: Type application is only supported for generic classes
[out]
-- Generic types in expressions
-- ----------------------------
[case testTypeApplicationArgs]
from typing import TypeVar, Generic
T = TypeVar('T')
class Node(Generic[T]):
def __init__(self, x: T) -> None:
...
Node[int]() # E: Missing positional argument "x" in call to "Node"
Node[int](1, 1, 1) # E: Too many arguments for "Node"
[out]
[case testTypeApplicationTvars]
from typing import TypeVar, Generic
T = TypeVar('T')
S = TypeVar('S')
class A(Generic[T, S]): pass
A[int]() # E: Type application has too few types (2 expected)
A[int, str, int]() # E: Type application has too many types (2 expected)
[out]
[case testInvalidTypeApplicationType]
a: A
class A: pass
a[A]() # E: Value of type "A" is not indexable
A[A]() # E: The type "Type[A]" is not generic and not indexable
[out]
[case testTypeApplicationArgTypes]
from typing import TypeVar, Generic
T = TypeVar('T')
class Node(Generic[T]):
def __init__(self, x: T) -> None:
...
Node[int](1)
Node[int]('a') # E: Argument 1 to "Node" has incompatible type "str"; expected "int"
class Dummy(Generic[T]):
def meth(self, x: T) -> None:
...
def methout(self) -> T:
...
Dummy[int]().meth(1)
Dummy[int]().meth('a') # E: Argument 1 to "meth" of "Dummy" has incompatible type "str"; expected "int"
reveal_type(Dummy[int]()) # N: Revealed type is "__main__.Dummy[builtins.int]"
reveal_type(Dummy[int]().methout()) # N: Revealed type is "builtins.int"
[out]
[case testTypeApplicationArgTypesSubclasses]
from typing import TypeVar, Generic
T = TypeVar('T')
S = TypeVar('S')
class C(Generic[T, S]):
def __init__(self, x: T, y: S) -> None:
...
class D(C[int, T]): ...
D[str](1, 'a')
D[str](1, 1) # E: Argument 2 to "D" has incompatible type "int"; expected "str"
class E(D[str]): ...
E(1, 'a')
E(1, 1) # E: Argument 2 to "E" has incompatible type "int"; expected "str"
[out]
[case testTypeApplicationAlias]
from typing import TypeVar, Generic
T = TypeVar('T')
class Node(Generic[T]):
def __init__(self, x: T) -> None:
...
Alias = Node
Alias[int](1)
Alias[int]("a") # E: Argument 1 to "Node" has incompatible type "str"; expected "int"
[out]
[case testTypeApplicationCrash]
type[int] # this was crashing, see #2302 (comment) # E: The type "Type[type]" is not generic and not indexable
[out]
-- Generic type aliases
-- --------------------
[case testGenericTypeAliasesBasic]
from typing import TypeVar, Generic
T = TypeVar('T')
S = TypeVar('S')
class Node(Generic[T, S]):
def __init__(self, x: T, y: S) -> None:
...
IntNode = Node[int, S]
IntIntNode = Node[int, int]
SameNode = Node[T, T]
n = Node(1, 1) # type: IntIntNode
n1 = Node(1, 'a') # type: IntIntNode # E: Argument 2 to "Node" has incompatible type "str"; expected "int"
m = Node(1, 1) # type: IntNode
m1 = Node('x', 1) # type: IntNode # E: Argument 1 to "Node" has incompatible type "str"; expected "int"
m2 = Node(1, 1) # type: IntNode[str] # E: Argument 2 to "Node" has incompatible type "int"; expected "str"
s = Node(1, 1) # type: SameNode[int]
reveal_type(s) # N: Revealed type is "__main__.Node[builtins.int, builtins.int]"
s1 = Node(1, 'x') # type: SameNode[int] # E: Argument 2 to "Node" has incompatible type "str"; expected "int"
[out]
[case testGenericTypeAliasesBasic2]
from typing import TypeVar, Generic
T = TypeVar('T')
S = TypeVar('S')
class Node(Generic[T, S]):
def __init__(self, x: T, y: S) -> None:
...
IntNode = Node[int, S]
IntIntNode = Node[int, int]
SameNode = Node[T, T]
def output_bad() -> IntNode[str]:
return Node(1, 1) # Error - bad return type, see out
def input(x: IntNode[str]) -> None:
pass
input(Node(1, 's'))
input(Node(1, 1)) # E: Argument 2 to "Node" has incompatible type "int"; expected "str"
def output() -> IntNode[str]:
return Node(1, 'x')
reveal_type(output()) # N: Revealed type is "__main__.Node[builtins.int, builtins.str]"
def func(x: IntNode[T]) -> IntNode[T]:
return x
reveal_type(func) # N: Revealed type is "def [T] (x: __main__.Node[builtins.int, T`-1]) -> __main__.Node[builtins.int, T`-1]"
func(1) # E: Argument 1 to "func" has incompatible type "int"; expected "Node[int, <nothing>]"
func(Node('x', 1)) # E: Argument 1 to "Node" has incompatible type "str"; expected "int"
reveal_type(func(Node(1, 'x'))) # N: Revealed type is "__main__.Node[builtins.int, builtins.str]"
def func2(x: SameNode[T]) -> SameNode[T]:
return x
reveal_type(func2) # N: Revealed type is "def [T] (x: __main__.Node[T`-1, T`-1]) -> __main__.Node[T`-1, T`-1]"
func2(Node(1, 'x')) # E: Cannot infer type argument 1 of "func2"
y = func2(Node('x', 'x'))
reveal_type(y) # N: Revealed type is "__main__.Node[builtins.str, builtins.str]"
def wrap(x: T) -> IntNode[T]:
return Node(1, x)
z: str
reveal_type(wrap(z)) # N: Revealed type is "__main__.Node[builtins.int, builtins.str]"
[out]
main:13: error: Argument 2 to "Node" has incompatible type "int"; expected "str"
-- Error formatting is a bit different (and probably better) with new analyzer
[case testGenericTypeAliasesWrongAliases]
# flags: --show-column-numbers --no-strict-optional
from typing import TypeVar, Generic, List, Callable, Tuple, Union
T = TypeVar('T')
S = TypeVar('S')
class Node(Generic[T, S]):
def __init__(self, x: T, y: S) -> None:
...
A = Node[T] # Error
B = Node[T, T]
C = Node[T, T, T] # Error
D = Node[T, S]
E = Node[Node[T, T], List[T]]
F = Node[List[T, T], S] # Error
G = Callable[..., List[T, T]] # Error
H = Union[int, Tuple[T, Node[T]]] # Error
h: H # This was reported on previous line
h1: H[int, str] # Error
x = None # type: D[int, str]
reveal_type(x)
y = None # type: E[int]
reveal_type(y)
X = T # Error
[builtins fixtures/list.pyi]
[out]
main:9:5: error: "Node" expects 2 type arguments, but 1 given
main:11:5: error: "Node" expects 2 type arguments, but 3 given
main:15:10: error: "list" expects 1 type argument, but 2 given
main:16:19: error: "list" expects 1 type argument, but 2 given
main:17:25: error: "Node" expects 2 type arguments, but 1 given
main:19:5: error: Bad number of arguments for type alias, expected: 1, given: 2
main:22:13: note: Revealed type is "__main__.Node[builtins.int, builtins.str]"
main:24:13: note: Revealed type is "__main__.Node[__main__.Node[builtins.int, builtins.int], builtins.list[builtins.int]]"
main:26:5: error: Type variable "__main__.T" is invalid as target for type alias
[case testGenericTypeAliasesForAliases]
from typing import TypeVar, Generic, List, Union
T = TypeVar('T')
S = TypeVar('S')
class Node(Generic[T, S]):
def __init__(self, x: T, y: S) -> None:
pass
ListedNode = Node[List[T], List[S]]
Second = ListedNode[int, T]
Third = Union[int, Second[str]]
def f2(x: T) -> Second[T]:
return Node([1], [x])
reveal_type(f2('a')) # N: Revealed type is "__main__.Node[builtins.list[builtins.int], builtins.list[builtins.str]]"
def f3() -> Third:
return Node([1], ['x'])
reveal_type(f3()) # N: Revealed type is "Union[builtins.int, __main__.Node[builtins.list[builtins.int], builtins.list[builtins.str]]]"
[builtins fixtures/list.pyi]
[case testGenericTypeAliasesWithNestedArgs]
# flags: --pretty --show-error-codes
import other
a: other.Array[float]
reveal_type(a) # N: Revealed type is "other.array[Any, other.dtype[builtins.float]]"
[out]
main:3: error: Type argument "float" of "Array" must be a subtype of "generic" [type-var]
a: other.Array[float]
^
[file other.py]
from typing import Any, Generic, TypeVar
DT = TypeVar("DT", covariant=True, bound='dtype[Any]')
DTS = TypeVar("DTS", covariant=True, bound='generic')
S = TypeVar("S", bound=Any)
ST = TypeVar("ST", bound='generic', covariant=True)
class common: pass
class generic(common): pass
class dtype(Generic[DTS]): pass
class array(common, Generic[S, DT]): pass
Array = array[Any, dtype[ST]]
[case testGenericTypeAliasesAny]
from typing import TypeVar, Generic
T = TypeVar('T')
S = TypeVar('S')
class Node(Generic[T, S]):
def __init__(self, x: T, y: S) -> None:
self.x = x
self.y = y
IntNode = Node[int, S]
AnyNode = Node[S, T]
def output() -> IntNode[str]:
return Node(1, 'x')
x = output() # type: IntNode # This is OK (implicit Any)
y: IntNode
y.x = 1
y.x = 'x' # E: Incompatible types in assignment (expression has type "str", variable has type "int")
y.y = 1 # Both are OK (implicit Any)
y.y = 'x'
z = Node(1, 'x') # type: AnyNode
reveal_type(z) # N: Revealed type is "__main__.Node[Any, Any]"
[out]
[case testGenericTypeAliasesAcessingMethods]
from typing import TypeVar, Generic, List
T = TypeVar('T')
class Node(Generic[T]):
def __init__(self, x: T) -> None:
self.x = x
def meth(self) -> T:
return self.x
ListedNode = Node[List[T]]
l: ListedNode[int]
l.x.append(1)
l.meth().append(1)
reveal_type(l.meth()) # N: Revealed type is "builtins.list[builtins.int]"
l.meth().append('x') # E: Argument 1 to "append" of "list" has incompatible type "str"; expected "int"
ListedNode[str]([]).x = 1 # E: Incompatible types in assignment (expression has type "int", variable has type "List[str]")
[builtins fixtures/list.pyi]
[case testGenericTypeAliasesSubclassing]
from typing import TypeVar, Generic, Tuple, List
T = TypeVar('T')
class Node(Generic[T]):
def __init__(self, x: T) -> None:
...
TupledNode = Node[Tuple[T, T]]
class D(TupledNode[T]):
...
class L(List[TupledNode[T]]):
...
def f_bad(x: T) -> D[T]:
return D(1) # Error, see out
L[int]().append(Node((1, 1)))
L[int]().append(5) # E: Argument 1 to "append" of "list" has incompatible type "int"; expected "Node[Tuple[int, int]]"
x = D((1, 1)) # type: D[int]
y = D(5) # type: D[int] # E: Argument 1 to "D" has incompatible type "int"; expected "Tuple[int, int]"
def f(x: T) -> D[T]:
return D((x, x))
reveal_type(f('a')) # N: Revealed type is "__main__.D[builtins.str]"
[builtins fixtures/list.pyi]
[out]
main:15: error: Argument 1 to "D" has incompatible type "int"; expected "Tuple[T, T]"
[case testGenericTypeAliasesSubclassingBad]
from typing import TypeVar, Generic, Tuple, Union
T = TypeVar('T')
class Node(Generic[T]):
def __init__(self, x: T) -> None:
...
TupledNode = Node[Tuple[T, T]]
UNode = Union[int, Node[T]]
class C(TupledNode): ... # Same as TupledNode[Any]
class D(TupledNode[T]): ...
class E(Generic[T], UNode[T]): ... # E: Invalid base class "UNode"
reveal_type(D((1, 1))) # N: Revealed type is "__main__.D[builtins.int]"
[builtins fixtures/list.pyi]
[case testGenericTypeAliasesUnion]
from typing import TypeVar, Generic, Union, Any
T = TypeVar('T')
class Node(Generic[T]):
def __init__(self, x: T) -> None:
self.x = x
UNode = Union[int, Node[T]]
x = 1 # type: UNode[int]
x + 1 # E: Unsupported left operand type for + ("Node[int]") \
# N: Left operand is of type "Union[int, Node[int]]"
if not isinstance(x, Node):
x + 1
if not isinstance(x, int):
x.x = 1
x.x = 'a' # E: Incompatible types in assignment (expression has type "str", variable has type "int")
def f(x: T) -> UNode[T]:
if int():
return Node(x)
else:
return 1
reveal_type(f(1)) # N: Revealed type is "Union[builtins.int, __main__.Node[builtins.int]]"
TNode = Union[T, Node[int]]
s = 1 # type: TNode[str] # E: Incompatible types in assignment (expression has type "int", variable has type "Union[str, Node[int]]")
if not isinstance(s, str):
s.x = 1
z = None # type: TNode # Same as TNode[Any]
z.x
z.foo() # E: Item "Node[int]" of "Union[Any, Node[int]]" has no attribute "foo"
[builtins fixtures/isinstance.pyi]
[case testGenericTypeAliasesTuple]
from typing import TypeVar, Tuple
T = TypeVar('T')
SameTP = Tuple[T, T]
IntTP = Tuple[int, T]
def f1(x: T) -> SameTP[T]:
return x, x
a, b, c = f1(1) # E: Need more than 2 values to unpack (3 expected)
x, y = f1(1)
reveal_type(x) # N: Revealed type is "builtins.int"
def f2(x: IntTP[T]) -> IntTP[T]:
return x
f2((1, 2, 3)) # E: Argument 1 to "f2" has incompatible type "Tuple[int, int, int]"; expected "Tuple[int, <nothing>]"
reveal_type(f2((1, 'x'))) # N: Revealed type is "Tuple[builtins.int, builtins.str]"
[builtins fixtures/for.pyi]
[case testGenericTypeAliasesCallable]
from typing import TypeVar, Generic, Callable
T = TypeVar('T')
class Node(Generic[T]):
def __init__(self, x: T) -> None:
...
BadC = Callable[T] # E: Please use "Callable[[<parameters>], <return type>]" or "Callable"
C = Callable[..., T]
C2 = Callable[[T, T], Node[T]]
def make_cb(x: T) -> C[T]:
return lambda *args: x
reveal_type(make_cb(1)) # N: Revealed type is "def (*Any, **Any) -> builtins.int"
def use_cb(arg: T, cb: C2[T]) -> Node[T]:
return cb(arg, arg)
use_cb(1, 1) # E: Argument 2 to "use_cb" has incompatible type "int"; expected "Callable[[int, int], Node[int]]"
my_cb: C2[int]
use_cb('x', my_cb) # E: Argument 2 to "use_cb" has incompatible type "Callable[[int, int], Node[int]]"; expected "Callable[[str, str], Node[str]]"
reveal_type(use_cb(1, my_cb)) # N: Revealed type is "__main__.Node[builtins.int]"
[builtins fixtures/tuple.pyi]
[out]
[case testGenericTypeAliasesPEPBasedExample]
from typing import TypeVar, List, Tuple
T = TypeVar('T', int, bool)
Vec = List[Tuple[T, T]]
vec = [] # type: Vec[bool]
vec.append('x') # E: Argument 1 to "append" of "list" has incompatible type "str"; expected "Tuple[bool, bool]"
reveal_type(vec[0]) # N: Revealed type is "Tuple[builtins.bool, builtins.bool]"
def fun1(v: Vec[T]) -> T:
return v[0][0]
def fun2(v: Vec[T], scale: T) -> Vec[T]:
return v
reveal_type(fun1([(1, 1)])) # N: Revealed type is "builtins.int"
fun1(1) # E: Argument 1 to "fun1" has incompatible type "int"; expected "List[Tuple[bool, bool]]"
fun1([(1, 'x')]) # E: Cannot infer type argument 1 of "fun1"
reveal_type(fun2([(1, 1)], 1)) # N: Revealed type is "builtins.list[Tuple[builtins.int, builtins.int]]"
fun2([('x', 'x')], 'x') # E: Value of type variable "T" of "fun2" cannot be "str"
[builtins fixtures/list.pyi]
[case testGenericTypeAliasesImporting]
from typing import TypeVar
from a import Node, TupledNode
T = TypeVar('T')
n: TupledNode[int]
n.x = 1
n.y = (1, 1)
n.y = 'x' # E: Incompatible types in assignment (expression has type "str", variable has type "Tuple[int, int]")
def f(x: Node[T, T]) -> TupledNode[T]:
return Node(x.x, (x.x, x.x))
f(1) # E: Argument 1 to "f" has incompatible type "int"; expected "Node[<nothing>, <nothing>]"
f(Node(1, 'x')) # E: Cannot infer type argument 1 of "f"
reveal_type(Node('x', 'x')) # N: Revealed type is "a.Node[builtins.str, builtins.str]"
[file a.py]
from typing import TypeVar, Generic, Tuple
T = TypeVar('T')
S = TypeVar('S')
class Node(Generic[T, S]):
def __init__(self, x: T, y: S) -> None:
self.x = x
self.y = y
TupledNode = Node[T, Tuple[T, T]]
[builtins fixtures/list.pyi]
[case testGenericTypeAliasesImportingWithoutTypeVar]
from typing import Tuple
from lib import Transform
def int_tf(m: int) -> Transform[int, str]:
def transform(i: int, pos: int) -> Tuple[int, str]:
pass
return transform
var: Transform[int, str]
reveal_type(var) # N: Revealed type is "def (builtins.int, builtins.int) -> Tuple[builtins.int, builtins.str]"
[file lib.py]
from typing import Callable, TypeVar, Tuple
T = TypeVar('T')
R = TypeVar('R')
Transform = Callable[[T, int], Tuple[T, R]]
[builtins fixtures/tuple.pyi]
[out]
[case testGenericTypeAliasesImportingWithoutTypeVarError]
from a import Alias
x: Alias[int, str] # E: Bad number of arguments for type alias, expected: 1, given: 2
reveal_type(x) # N: Revealed type is "builtins.list[builtins.list[Any]]"
[file a.py]
from typing import TypeVar, List
T = TypeVar('T')
Alias = List[List[T]]
[builtins fixtures/list.pyi]
[out]
[case testGenericAliasWithTypeVarsFromDifferentModules]
from mod import Alias, TypeVar
S = TypeVar('S')
NewAlias = Alias[int, int, S, S]
class C: pass
x: NewAlias[str]
reveal_type(x) # N: Revealed type is "builtins.list[Tuple[builtins.int, builtins.int, builtins.str, builtins.str]]"
y: Alias[int, str, C, C]
reveal_type(y) # N: Revealed type is "builtins.list[Tuple[builtins.int, builtins.str, __main__.C, __main__.C]]"
[file mod.py]
from typing import TypeVar, List, Tuple
import a
import b
T = TypeVar('T')
Alias = List[Tuple[T, a.T, b.T, b.B.T]] # alias_tvars here will be ['T', 'a.T', 'b.T', 'b.B.T']
[file a.py]
from typing import TypeVar
T = TypeVar('T')
[file b.py]
from typing import TypeVar
T = TypeVar('T')
class B:
T = TypeVar('T')
[builtins fixtures/list.pyi]
[out]
[case testTypeAliasesResultingInPlainInstance]
from typing import Optional, Union
O = Optional[int]
U = Union[int]
x: O
y: U
reveal_type(x) # N: Revealed type is "Union[builtins.int, None]"
reveal_type(y) # N: Revealed type is "builtins.int"
U[int] # E: Type application targets a non-generic function or class
O[int] # E: Bad number of arguments for type alias, expected: 0, given: 1 # E: Type application is only supported for generic classes
[out]
[case testAliasesInClassBodyNormalVsSubscripted]
from typing import Union, Type, Iterable
class A: pass
class B(A): pass
class C:
a = A # This is a variable
b = Union[int, str] # This is an alias
c: Type[object] = Iterable[int] # This is however also a variable
if int():
a = B
if int():
b = int # E: Cannot assign multiple types to name "b" without an explicit "Type[...]" annotation
if int():
c = int
def f(self, x: a) -> None: pass # E: Variable "__main__.C.a" is not valid as a type \
# N: See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases
def g(self, x: b) -> None: pass
def h(self, x: c) -> None: pass # E: Variable "__main__.C.c" is not valid as a type \
# N: See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases
x: b
reveal_type(x) # N: Revealed type is "Union[builtins.int, builtins.str]"
[out]
[case testGenericTypeAliasesRuntimeExpressionsInstance]
from typing import TypeVar, Generic
T = TypeVar('T')
S = TypeVar('S')
class Node(Generic[T, S]):
def __init__(self, x: T, y: S) -> None:
...
IntNode = Node[int, T]
IntNode[int](1, 1)
IntNode[int](1, 'a') # E: Argument 2 to "Node" has incompatible type "str"; expected "int"
SameNode = Node[T, T]
ff = SameNode[T](1, 1) # E: Type variable "__main__.T" is unbound \
# N: (Hint: Use "Generic[T]" or "Protocol[T]" base class to bind "T" inside a class) \
# N: (Hint: Use "T" in function signature to bind "T" inside a function)
a = SameNode(1, 'x')
reveal_type(a) # N: Revealed type is "__main__.Node[Any, Any]"
b = SameNode[int](1, 1)
reveal_type(b) # N: Revealed type is "__main__.Node[builtins.int, builtins.int]"
SameNode[int](1, 'x') # E: Argument 2 to "Node" has incompatible type "str"; expected "int"
[out]
[case testGenericTypeAliasesRuntimeExpressionsOther]
from typing import TypeVar, Union, Tuple, Callable, Any
T = TypeVar('T')
CA = Callable[[T], int]
TA = Tuple[T, int]
UA = Union[T, int]
cs = CA + 1 # E: Unsupported left operand type for + ("<typing special form>")
reveal_type(cs) # N: Revealed type is "Any"
ts = TA() # E: "<typing special form>" not callable
reveal_type(ts) # N: Revealed type is "Any"
us = UA.x # E: "<typing special form>" has no attribute "x"
reveal_type(us) # N: Revealed type is "Any"
xx = CA[str] + 1 # E: Type application is only supported for generic classes
yy = TA[str]() # E: Type application is only supported for generic classes
zz = UA[str].x # E: Type application is only supported for generic classes
[builtins fixtures/tuple.pyi]
[typing fixtures/typing-medium.pyi]
[out]
[case testGenericTypeAliasesTypeVarBinding]
from typing import TypeVar, Generic, List
T = TypeVar('T')
S = TypeVar('S')
class A(Generic[T, S]):
def __init__(self, x: T, y: S) -> None: ...
class B(Generic[T, S]):
def __init__(self, x: List[T], y: List[S]) -> None: ...
SameA = A[T, T]
SameB = B[T, T]
class C(Generic[T]):
a = None # type: SameA[T]
b = SameB[T]([], [])
reveal_type(C[int]().a) # N: Revealed type is "__main__.A[builtins.int, builtins.int]"
reveal_type(C[str]().b) # N: Revealed type is "__main__.B[builtins.str, builtins.str]"
[builtins fixtures/list.pyi]
[case testGenericTypeAliasesTypeVarConstraints]
# flags: --show-column-numbers --no-strict-optional
from typing import TypeVar, Generic
T = TypeVar('T', int, list)
S = TypeVar('S', int, list)
class A(Generic[T, S]):
def __init__(self, x: T, y: S) -> None: ...
BadA = A[str, T] # One error here
SameA = A[T, T]
x = None # type: SameA[int]
y = None # type: SameA[str] # Another error here
[builtins fixtures/list.pyi]
[out]
main:9:8: error: Value of type variable "T" of "A" cannot be "str"
main:13:1: error: Value of type variable "T" of "SameA" cannot be "str"
[case testGenericTypeAliasesIgnoredPotentialAlias]
class A: ...
Bad = A[int] # type: ignore
reveal_type(Bad) # N: Revealed type is "Any"
[out]
[case testNoSubscriptionOfBuiltinAliases]
from typing import List, TypeVar
list[int]() # E: "list" is not subscriptable
ListAlias = List
def fun() -> ListAlias[int]:
pass
reveal_type(fun()) # N: Revealed type is "builtins.list[builtins.int]"
BuiltinAlias = list
BuiltinAlias[int]() # E: "list" is not subscriptable
#check that error is reported only once, and type is still stored
T = TypeVar('T')
BadGenList = list[T] # E: "list" is not subscriptable
reveal_type(BadGenList[int]()) # N: Revealed type is "builtins.list[builtins.int]"
reveal_type(BadGenList()) # N: Revealed type is "builtins.list[Any]"
[builtins fixtures/list.pyi]
[out]
[case testImportedTypeAliasInRuntimeContext]
from m import Alias
n = Alias[int]([1])
reveal_type(n) # N: Revealed type is "m.Node[builtins.list[builtins.int]]"
bad = Alias[str]([1]) # E: List item 0 has incompatible type "int"; expected "str"
n2 = Alias([1]) # Same as Node[List[Any]]
reveal_type(n2) # N: Revealed type is "m.Node[builtins.list[Any]]"
[file m.py]
from typing import TypeVar, Generic, List
T = TypeVar('T')
class Node(Generic[T]):
def __init__(self, x: T) -> None:
self.x = x
Alias = Node[List[T]]
[builtins fixtures/list.pyi]
[out]
-- Simplified declaration of generics
-- ----------------------------------
[case testSimplifiedGenericSimple]
from typing import TypeVar, Generic
T = TypeVar('T')
S = TypeVar('S')
class B(Generic[T]):
def b(self) -> T: ...
class C(Generic[T]):
def c(self) -> T: ...
class D(B[T], C[S]): ...
reveal_type(D[str, int]().b()) # N: Revealed type is "builtins.str"
reveal_type(D[str, int]().c()) # N: Revealed type is "builtins.int"
[builtins fixtures/list.pyi]
[out]
[case testSimplifiedGenericCallable]
from typing import TypeVar, Generic, Callable
T = TypeVar('T')
S = TypeVar('S')
class B(Generic[T]):
def b(self) -> T: ...
class D(B[Callable[[T], S]]): ...
reveal_type(D[str, int]().b()) # N: Revealed type is "def (builtins.str) -> builtins.int"
[builtins fixtures/list.pyi]
[out]
[case testSimplifiedGenericComplex]
from typing import TypeVar, Generic, Tuple
T = TypeVar('T')
S = TypeVar('S')
U = TypeVar('U')
class A(Generic[T, S]):
pass
class B(Generic[T, S]):
def m(self) -> Tuple[T, S]:
pass
class C(A[S, B[T, int]], B[U, A[int, T]]):
pass
c = C[object, int, str]()
reveal_type(c.m()) # N: Revealed type is "Tuple[builtins.str, __main__.A[builtins.int, builtins.int]]"
[builtins fixtures/tuple.pyi]
[out]
[case testSimplifiedGenericOrder]
from typing import TypeVar, Generic
T = TypeVar('T')
S = TypeVar('S')
class B(Generic[T]):
def b(self) -> T: ...
class C(Generic[T]):
def c(self) -> T: ...
class D(B[T], C[S], Generic[S, T]): ...
reveal_type(D[str, int]().b()) # N: Revealed type is "builtins.int"
reveal_type(D[str, int]().c()) # N: Revealed type is "builtins.str"
[builtins fixtures/list.pyi]
[out]
[case testSimplifiedGenericDuplicate]
from typing import TypeVar, Generic
T = TypeVar('T')
class A(Generic[T, T]): # E: Duplicate type variables in Generic[...] or Protocol[...]
pass
a = A[int]()
[builtins fixtures/list.pyi]
[out]
[case testSimplifiedGenericNotAll]
from typing import TypeVar, Generic
T = TypeVar('T')
S = TypeVar('S')
class A(Generic[T]):
pass
class B(Generic[T]):
pass
class C(A[T], B[S], Generic[T]): # E: If Generic[...] or Protocol[...] is present it should list all type variables
pass
c = C[int, str]()
[builtins fixtures/list.pyi]
[out]
[case testSimplifiedGenericInvalid]
from typing import TypeVar, Generic
T = TypeVar('T')
class A(Generic[T]):
pass
class B(A[S]): # E: Name "S" is not defined
pass
[builtins fixtures/list.pyi]
[out]
-- Multiple assignment with lists
-- ------------------------------
[case testMultipleAssignmentWithLists]
from typing import List
class A: pass
class B: pass
class B2(B): pass
a: A
b: B
b2: B2
list_a = [a]
list_b = [b]
list_b2 = [b2]
if int():
a, b = list_a # E: Incompatible types in assignment (expression has type "A", variable has type "B")
if int():
b, a = list_a # E: Incompatible types in assignment (expression has type "A", variable has type "B")
if int():
b2, b2 = list_b # E: Incompatible types in assignment (expression has type "B", variable has type "B2")
a, a = list_a
b, b2, b = list_b2
[builtins fixtures/for.pyi]
[case testMultipleAssignmentWithListsInInitialization]
from typing import List
class A: pass
list_object = [object()]
list_a = [A()]
a, b = list_object # type: (A, object) # E: Incompatible types in assignment (expression has type "object", variable has type "A")
c, d = list_object # type: (object, A) # E: Incompatible types in assignment (expression has type "object", variable has type "A")
e, f = list_a # type: (A, object)
[builtins fixtures/for.pyi]
[case testMultipleAssignmentWithListAndIndexing]
from typing import List
a: List[A]
b: List[int]
a[1], b[1] = a # E: Incompatible types in assignment (expression has type "A", target has type "int")
a[1], a[2] = a
class A: pass
[file builtins.py]
from typing import TypeVar, Generic, Iterable
T = TypeVar('T')
class object: pass
class list(Iterable[T]):
def __setitem__(self, x: int, v: T) -> None: pass
class int: pass
class type: pass
class tuple: pass
class function: pass
class str: pass
class dict: pass
[case testMultipleAssignmentWithIterable]
from typing import Iterable, TypeVar
a: int
b: str
T = TypeVar('T')
def f(x: T) -> Iterable[T]: pass
a, b = f(a) # E: Incompatible types in assignment (expression has type "int", variable has type "str")
b, b = f(a) # E: Incompatible types in assignment (expression has type "int", variable has type "str")
a, a = f(a)
b, b = f(b)
[builtins fixtures/for.pyi]
-- Error messages
-- --------------
[case testErrorWithLongGenericTypeName]
from typing import TypeVar, Generic
B = TypeVar('B')
C = TypeVar('C')
D = TypeVar('D')
E = TypeVar('E')
F = TypeVar('F')
G = TypeVar('G')
H = TypeVar('H')
I = TypeVar('I')
J = TypeVar('J')
K = TypeVar('K')
L = TypeVar('L')
M = TypeVar('M')
N = TypeVar('N')
O = TypeVar('O')
P = TypeVar('P')
Q = TypeVar('Q')
R = TypeVar('R')
S = TypeVar('S')
T = TypeVar('T')
U = TypeVar('U')
V = TypeVar('V')
W = TypeVar('W')
X = TypeVar('X')
Y = TypeVar('Y')
Z = TypeVar('Z')
class OO: pass
a: A[object, object, object, object, object, object, object, object, object, object, object, object, object, object, object, object, object, object, object, object, object, object, object, object, object]
def f(a: OO) -> None:
pass
f(a) # E: Argument 1 to "f" has incompatible type "A[object, object, object, object, object, object, object, object, object, object, object, object, object, object, object, object, object, object, object, object, object, object, object, object, object]"; expected "OO"
class A(Generic[B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z]): pass
[case testErrorWithShorterGenericTypeName]
from typing import TypeVar, Generic
S = TypeVar('S')
T = TypeVar('T')
a: A[object, B]
def f(a: 'B') -> None: pass
f(a) # E: Argument 1 to "f" has incompatible type "A[object, B]"; expected "B"
class A(Generic[S, T]): pass
class B: pass
[case testErrorWithShorterGenericTypeName2]
from typing import Callable, TypeVar, Generic
S = TypeVar('S')
T = TypeVar('T')
a: A[object, Callable[[], None]]
def f(a: 'B') -> None: pass
f(a) # E: Argument 1 to "f" has incompatible type "A[object, Callable[[], None]]"; expected "B"
class A(Generic[S, T]): pass
class B: pass
-- Overloads + generics
-- --------------------
[case testGenericArgumentInOverload]
from foo import *
[file foo.pyi]
from typing import overload, List
class A: pass
class B: pass
a: A
b: B
@overload
def f(a: List[A]) -> A: pass
@overload
def f(a: B) -> B: pass
b = f([a]) # E: Incompatible types in assignment (expression has type "A", variable has type "B")
a = f([b]) # E: List item 0 has incompatible type "B"; expected "A"
a = f(b) # E: Incompatible types in assignment (expression has type "B", variable has type "A")
a = f([a])
b = f(b)
[builtins fixtures/list.pyi]
[case testGenericFunctionAsOverloadItem]
from foo import *
[file foo.pyi]
from typing import overload, TypeVar, List
T = TypeVar('T')
class A: pass
class B: pass
@overload
def f(a: B) -> B: pass
@overload
def f(a: List[T]) -> T: pass
a: A
b: B
if int():
b = f([a]) # E: Incompatible types in assignment (expression has type "A", variable has type "B")
a = f([b]) # E: Incompatible types in assignment (expression has type "B", variable has type "A")
if int():
a = f(b) # E: Incompatible types in assignment (expression has type "B", variable has type "A")
if int():
a = f([a])
b = f([b])
if int():
b = f(b)
[builtins fixtures/list.pyi]
-- Type variable scoping
-- ---------------------
[case testLocalTypeVariable]
from typing import TypeVar
def f() -> None:
T = TypeVar('T')
def g(x: T) -> T: pass
a = g(1)
if int():
a = 1
a = '' # E: Incompatible types in assignment (expression has type "str", variable has type "int")
[out]
[case testClassLevelTypeVariable]
from typing import TypeVar
class A:
T = TypeVar('T')
def g(self, x: T) -> T: pass
a = A().g(1)
if int():
a = 1
if int():
a = '' # E: Incompatible types in assignment (expression has type "str", variable has type "int")
[case testGenericInnerClass]
from typing import TypeVar, Generic
T = TypeVar('T')
class A:
class B(Generic[T]):
def meth(self) -> T: ...
B[int]()
reveal_type(B[int]().meth) # N: Revealed type is "def () -> builtins.int"
A.B[int]()
reveal_type(A.B[int]().meth) # N: Revealed type is "def () -> builtins.int"
[case testGenericClassInnerFunctionTypeVariable]
from typing import TypeVar, Generic
T = TypeVar('T')
class A(Generic[T]):
def __init__(self, a: T) -> None:
self.a = a
def f(self, n: int) -> None:
def g(a: T):
self.a = a
g(self.a)
g(n) # E: Argument 1 to "g" has incompatible type "int"; expected "T"
-- This is non-trivial with new analyzer (and also in fine grained incremental):
-- We need to store whole tvar_scope, not only active class.
[case testFunctionInGenericInnerClassTypeVariable-skip]
from typing import TypeVar, Generic
T = TypeVar('T')
class Outer(Generic[T]):
class Inner:
x: T # E: Invalid type "__main__.T"
def f(self, x: T) -> T: ... # E: Type variable "T" is bound by an outer class
def g(self) -> None:
y: T # E: Invalid type "__main__.T"
[case testGenericClassInsideOtherGenericClass]
from typing import TypeVar, Generic
T = TypeVar("T")
K = TypeVar("K")
class C(Generic[T]):
def __init__(self, t: T) -> None: ...
class F(Generic[K]):
def __init__(self, k: K) -> None: ...
def foo(self) -> K: ...
reveal_type(C.F(17).foo()) # N: Revealed type is "builtins.int"
reveal_type(C("").F(17).foo()) # N: Revealed type is "builtins.int"
reveal_type(C.F) # N: Revealed type is "def [K] (k: K`1) -> __main__.C.F[K`1]"
reveal_type(C("").F) # N: Revealed type is "def [K] (k: K`6) -> __main__.C.F[K`6]"
-- Callable subtyping with generic functions
-- -----------------------------------------
[case testSubtypingWithGenericFunctions]
from typing import TypeVar
A = TypeVar('A')
B = TypeVar('B')
def f1(x: A) -> A: ...
def f2(x: A) -> B: ... # E: A function returning TypeVar should receive at least one argument containing the same TypeVar
def f3(x: B) -> B: ...
def f4(x: int) -> A: ... # E: A function returning TypeVar should receive at least one argument containing the same TypeVar
y1 = f1
if int():
y1 = f1
if int():
y1 = f2
if int():
y1 = f3
if int():
y1 = f4 # E: Incompatible types in assignment (expression has type "Callable[[int], A]", variable has type "Callable[[A], A]")
y2 = f2
if int():
y2 = f2
if int():
y2 = f1 # E: Incompatible types in assignment (expression has type "Callable[[A], A]", variable has type "Callable[[A], B]")
if int():
y2 = f3 # E: Incompatible types in assignment (expression has type "Callable[[B], B]", variable has type "Callable[[A], B]")
if int():
y2 = f4 # E: Incompatible types in assignment (expression has type "Callable[[int], A]", variable has type "Callable[[A], B]")
y3 = f3
if int():
y3 = f3
if int():
y3 = f1
if int():
y3 = f2
if int():
y3 = f4 # E: Incompatible types in assignment (expression has type "Callable[[int], A]", variable has type "Callable[[B], B]")
y4 = f4
if int():
y4 = f4
if int():
y4 = f1 # E: Incompatible types in assignment (expression has type "Callable[[A], A]", variable has type "Callable[[int], A]")
if int():
y4 = f2
if int():
y4 = f3 # E: Incompatible types in assignment (expression has type "Callable[[B], B]", variable has type "Callable[[int], A]")
[case testSubtypingWithGenericInnerFunctions]
from typing import TypeVar
A = TypeVar('A')
B = TypeVar('B')
T = TypeVar('T')
def outer(t: T) -> None:
def f1(x: A) -> A: ...
def f2(x: A) -> B: ... # E: A function returning TypeVar should receive at least one argument containing the same TypeVar
def f3(x: T) -> A: ... # E: A function returning TypeVar should receive at least one argument containing the same TypeVar
def f4(x: A) -> T: ...
def f5(x: T) -> T: ...
y1 = f1
if int():
y1 = f2
y1 = f3 # E: Incompatible types in assignment (expression has type "Callable[[T], A]", variable has type "Callable[[A], A]")
y1 = f4 # E: Incompatible types in assignment (expression has type "Callable[[A], T]", variable has type "Callable[[A], A]")
y1 = f5 # E: Incompatible types in assignment (expression has type "Callable[[T], T]", variable has type "Callable[[A], A]")
y2 = f2
if int():
y2 = f1 # E: Incompatible types in assignment (expression has type "Callable[[A], A]", variable has type "Callable[[A], B]")
y3 = f3
if int():
y3 = f1 # E: Incompatible types in assignment (expression has type "Callable[[A], A]", variable has type "Callable[[T], A]")
y3 = f2
y3 = f4 # E: Incompatible types in assignment (expression has type "Callable[[A], T]", variable has type "Callable[[T], A]")
y3 = f5 # E: Incompatible types in assignment (expression has type "Callable[[T], T]", variable has type "Callable[[T], A]")
y4 = f4
if int():
y4 = f1 # E: Incompatible types in assignment (expression has type "Callable[[A], A]", variable has type "Callable[[A], T]")
y4 = f2
y4 = f3 # E: Incompatible types in assignment (expression has type "Callable[[T], A]", variable has type "Callable[[A], T]")
y4 = f5 # E: Incompatible types in assignment (expression has type "Callable[[T], T]", variable has type "Callable[[A], T]")
y5 = f5
if int():
y5 = f1
y5 = f2
y5 = f3
y5 = f4
[out]
[case testSubtypingWithGenericFunctionUsingTypevarWithValues]
from typing import TypeVar, Callable
T = TypeVar('T', int, str)
def f(x: T) -> T: pass
def g1(f: Callable[[str], str]) -> None: pass
g1(f)
def g2(f: Callable[[int], int]) -> None: pass
g2(f)
def g3(f: Callable[[object], object]) -> None: pass
g3(f) # E: Argument 1 to "g3" has incompatible type "Callable[[T], T]"; \
expected "Callable[[object], object]"
[case testSubtypingWithGenericFunctionUsingTypevarWithValues2]
from typing import TypeVar, Callable
T = TypeVar('T', int, str)
def f(x: T) -> T: pass
g = f
g = f
--Operations on type variable types
-- ---------------------------------
[case testTypeVariableTypeEquality]
from typing import TypeVar
T = TypeVar('T')
def f(a: T, b: T) -> T:
a.__ne__(b)
if a == b:
return a
else:
return b
[builtins fixtures/ops.pyi]
[case testTypeVariableTypeIs]
from typing import TypeVar
T = TypeVar('T')
def f(a: T, b: T) -> T:
if a is b or a is 1:
return a
else:
return b
[builtins fixtures/ops.pyi]
[case testTypeVarLessThan]
from typing import TypeVar
T = TypeVar('T')
def f(a: T, b: T) -> T:
if a < b: # E: Unsupported left operand type for < ("T")
return a
else:
return b
[builtins fixtures/ops.pyi]
[case testTypeVarReversibleOperator]
from typing import TypeVar
class A:
def __mul__(cls, other: int) -> str: return ""
T = TypeVar("T", bound=A)
def f(x: T) -> str:
return reveal_type(x * 0) # N: Revealed type is "builtins.str"
[case testTypeVarReversibleOperatorTuple]
from typing import TypeVar, Tuple
class A(Tuple[int, int]):
def __mul__(cls, other: Tuple[int, int]) -> str: return "" # type: ignore # overriding default __mul__
T = TypeVar("T", bound=A)
def f(x: T) -> str:
return reveal_type(x * (1, 2) ) # N: Revealed type is "builtins.str"
[builtins fixtures/tuple.pyi]
-- Subtyping generic callables
-- ---------------------------
[case testSubtypingGenericTypeObject]
from typing import Callable, Generic, TypeVar
T = TypeVar('T')
class C(Generic[T]):
def __init__(self) -> None: pass
x = C # type: Callable[[], C[int]]
y = C # type: Callable[[], int] # E: Incompatible types in assignment (expression has type "Type[C[Any]]", variable has type "Callable[[], int]")
-- Special cases
-- -------------
[case testIdentityHigherOrderFunction]
from typing import Callable, TypeVar
A = TypeVar('A')
B = TypeVar('B')
def square(n: int) -> int:
return n
def id(f: Callable[[A], B]) -> Callable[[A], B]:
return f
g = id(square)
g(1)
g('x') # E: Argument 1 has incompatible type "str"; expected "int"
[case testIdentityHigherOrderFunction2]
from typing import Callable, TypeVar
A = TypeVar('A')
def voidify(n: int) -> None: pass
def identity(f: Callable[[A], None]) -> Callable[[A], None]:
return f
identity(voidify)(3)
[case testIdentityHigherOrderFunction3]
from typing import Callable, TypeVar
A = TypeVar('A')
B = TypeVar('B')
def fn(n: B) -> None: pass
def identity(f: A) -> A:
return f
identity(fn)
identity(fn)('x')
[case testTypeVariableUnionAndCallableInTypeInference]
from typing import Union, Callable, TypeVar
T = TypeVar('T')
def f(x: T, y: Union[T, Callable[[T], None]]) -> None: pass
f('', '')
[case testGenericFunctionsWithUnalignedIds]
from typing import TypeVar
A = TypeVar('A')
B = TypeVar('B')
def f1(x: int, y: A) -> A: ...
def f2(x: int, y: A) -> B: ... # E: A function returning TypeVar should receive at least one argument containing the same TypeVar
def f3(x: A, y: B) -> B: ...
g = f1
g = f2
g = f3
[case testTypeVariableWithContainerAndTuple]
from typing import TypeVar, Container
T = TypeVar('T')
def f(x: Container[T]) -> T: ...
reveal_type(f((1, 2))) # N: Revealed type is "builtins.int"
[typing fixtures/typing-full.pyi]
[builtins fixtures/tuple.pyi]
[case testClassMethodInGenericClassWithGenericConstructorArg]
from typing import TypeVar, Generic
T = TypeVar('T')
class A(Generic[T]):
def __init__(self, a: T) -> None: pass
@classmethod
def f(cls) -> None: pass
[builtins fixtures/classmethod.pyi]
[case testClassMethodInClassWithGenericConstructor]
from typing import TypeVar, Generic
T = TypeVar('T')
class A:
def __init__(self, a: T) -> None: pass
@classmethod
def f(cls) -> None: pass
[builtins fixtures/classmethod.pyi]
[case testGenericOperatorMethodOverlapping]
from typing import TypeVar, Generic, Tuple
T = TypeVar('T')
T2 = TypeVar('T2')
S = TypeVar('S', bound=str)
S2 = TypeVar('S2', bound=str)
class G(Generic[T]):
pass
class A:
def __or__(self, x: G[T]) -> G[T]: pass
def __ior__(self, x: G[T2]) -> G[T2]: pass
class B:
def __or__(self, x: G[T]) -> G[T]: pass
def __ior__(self, x: G[S]) -> G[S]: pass \
# E: Signatures of "__ior__" and "__or__" are incompatible
class C:
def __or__(self, x: G[S]) -> G[S]: pass
def __ior__(self, x: G[S2]) -> G[S2]: pass
[case testGenericOperatorMethodOverlapping2]
from typing import TypeVar, Generic, Tuple
X = TypeVar('X')
T = TypeVar('T', int, str)
T2 = TypeVar('T2', int, str)
S = TypeVar('S', float, str)
S2 = TypeVar('S2', float, str)
class G(Generic[X]):
pass
class A:
def __or__(self, x: G[T]) -> G[T]: pass
def __ior__(self, x: G[T2]) -> G[T2]: pass
class B:
def __or__(self, x: G[T]) -> G[T]: pass
def __ior__(self, x: G[S]) -> G[S]: pass \
# E: Signatures of "__ior__" and "__or__" are incompatible
class C:
def __or__(self, x: G[S]) -> G[S]: pass
def __ior__(self, x: G[S2]) -> G[S2]: pass
class D:
def __or__(self, x: G[X]) -> G[X]: pass
def __ior__(self, x: G[S2]) -> G[S2]: pass \
# E: Signatures of "__ior__" and "__or__" are incompatible
[case testConstraintInferenceForAnyAgainstTypeT]
from typing import Type, Any, TypeVar
T = TypeVar('T')
def f(c: Type[T]) -> T: ...
x: Any
reveal_type(f(x)) # N: Revealed type is "Any"
[case testCallTypeTWithGenericBound]
from typing import Generic, TypeVar, Type
T = TypeVar('T')
S = TypeVar('S', bound='A')
class A(Generic[T]): pass
def f(cls: Type[S]) -> None:
cls()
[case testQualifiedTypeVariableName]
import b
def f(x: b.T) -> b.T: return x
reveal_type(f)
reveal_type(b.g)
[file b.py]
from typing import TypeVar
T = TypeVar('T')
def g(x: T) -> T: return x
[out]
main:3: note: Revealed type is "def [b.T] (x: b.T`-1) -> b.T`-1"
main:4: note: Revealed type is "def [T] (x: T`-1) -> T`-1"
[case testPartiallyQualifiedTypeVariableName]
from p import b
def f(x: b.T) -> b.T: return x
reveal_type(f)
reveal_type(b.g)
[file p/__init__.py]
[file p/b.py]
from typing import TypeVar
T = TypeVar('T')
def g(x: T) -> T: return x
[out]
main:3: note: Revealed type is "def [b.T] (x: b.T`-1) -> b.T`-1"
main:4: note: Revealed type is "def [T] (x: T`-1) -> T`-1"
[case testGenericClassMethodSimple]
from typing import Generic, TypeVar
T = TypeVar('T')
class C(Generic[T]):
@classmethod
def get(cls) -> T: ...
class D(C[str]): ...
reveal_type(D.get()) # N: Revealed type is "builtins.str"
reveal_type(D().get()) # N: Revealed type is "builtins.str"
[builtins fixtures/classmethod.pyi]
[case testGenericClassMethodExpansion]
from typing import Generic, TypeVar, Tuple
T = TypeVar('T')
class C(Generic[T]):
@classmethod
def get(cls) -> T: ...
class D(C[Tuple[T, T]]): ...
class E(D[str]): ...
reveal_type(E.get()) # N: Revealed type is "Tuple[builtins.str, builtins.str]"
reveal_type(E().get()) # N: Revealed type is "Tuple[builtins.str, builtins.str]"
[builtins fixtures/classmethod.pyi]
[case testGenericClassMethodExpansionReplacingTypeVar]
from typing import Generic, TypeVar
T = TypeVar('T')
S = TypeVar('S')
class C(Generic[T]):
@classmethod
def get(cls) -> T: ...
class D(C[S]): ...
class E(D[int]): ...
reveal_type(E.get()) # N: Revealed type is "builtins.int"
reveal_type(E().get()) # N: Revealed type is "builtins.int"
[builtins fixtures/classmethod.pyi]
[case testGenericClassMethodUnboundOnClass]
from typing import Generic, TypeVar
T = TypeVar('T')
class C(Generic[T]):
@classmethod
def get(cls) -> T: ...
@classmethod
def make_one(cls, x: T) -> C[T]: ...
reveal_type(C.get) # N: Revealed type is "def [T] () -> T`1"
reveal_type(C[int].get) # N: Revealed type is "def () -> builtins.int"
reveal_type(C.make_one) # N: Revealed type is "def [T] (x: T`1) -> __main__.C[T`1]"
reveal_type(C[int].make_one) # N: Revealed type is "def (x: builtins.int) -> __main__.C[builtins.int]"
[builtins fixtures/classmethod.pyi]
[case testGenericClassMethodUnboundOnSubClass]
from typing import Generic, TypeVar, Tuple
T = TypeVar('T')
S = TypeVar('S')
class C(Generic[T]):
@classmethod
def get(cls) -> T: ...
@classmethod
def make_one(cls, x: T) -> C[T]: ...
class D(C[Tuple[T, S]]): ...
class E(D[S, str]): ...
reveal_type(D.make_one) # N: Revealed type is "def [T, S] (x: Tuple[T`1, S`2]) -> __main__.C[Tuple[T`1, S`2]]"
reveal_type(D[int, str].make_one) # N: Revealed type is "def (x: Tuple[builtins.int, builtins.str]) -> __main__.C[Tuple[builtins.int, builtins.str]]"
reveal_type(E.make_one) # N: Revealed type is "def [S] (x: Tuple[S`1, builtins.str]) -> __main__.C[Tuple[S`1, builtins.str]]"
reveal_type(E[int].make_one) # N: Revealed type is "def (x: Tuple[builtins.int, builtins.str]) -> __main__.C[Tuple[builtins.int, builtins.str]]"
[builtins fixtures/classmethod.pyi]
[case testGenericClassClsNonGeneric]
from typing import TypeVar, Generic
T = TypeVar('T')
class C(Generic[T]):
@classmethod
def f(cls, x: T) -> T:
return x
@classmethod
def other(cls) -> None:
reveal_type(C) # N: Revealed type is "def [T] () -> __main__.C[T`1]"
reveal_type(C[T]) # N: Revealed type is "def () -> __main__.C[T`1]"
reveal_type(C.f) # N: Revealed type is "def [T] (x: T`1) -> T`1"
reveal_type(C[T].f) # N: Revealed type is "def (x: T`1) -> T`1"
reveal_type(cls.f) # N: Revealed type is "def (x: T`1) -> T`1"
[builtins fixtures/classmethod.pyi]
[case testGenericClassUnrelatedVars]
from typing import TypeVar, Generic
T = TypeVar('T')
T2 = TypeVar('T2')
class C(Generic[T]):
@classmethod
def f(cls, x: T) -> T:
return x
@classmethod
def g(cls, x: T2) -> T2:
cls.f(x) # E: Argument 1 to "f" of "C" has incompatible type "T2"; expected "T"
return x
[builtins fixtures/classmethod.pyi]
[case testGenericClassInGenericFunction]
from typing import TypeVar, Generic
T = TypeVar('T')
class C(Generic[T]):
def __init__(self, item: T) -> None: ...
@classmethod
def f(cls, x: T) -> T:
return x
def foo(x: T, y: int) -> T:
C(y) # OK
C[T](y) # E: Argument 1 to "C" has incompatible type "int"; expected "T"
C[T].f(y) # E: Argument 1 to "f" of "C" has incompatible type "int"; expected "T"
C[T].f(x) # OK
return x
[builtins fixtures/classmethod.pyi]
# TODO: enable this when #7935 is fixed.
[case testGenericClassInGenericFunctionOverloadedConstructor-skip]
from typing import TypeVar, Generic, overload
T = TypeVar('T')
class C(Generic[T]):
@overload
def __new__(cls) -> C[None]: ...
@overload
def __new__(cls, item: T) -> C[T]: ...
def __new__(cls, item=None):
...
@classmethod
def f(cls, x: T) -> T:
return x
def foo(x: T, y: int) -> T:
C.f(y)
C(y) # OK
C[T](y) # E: Argument 1 to "C" has incompatible type "int"; expected "T"
C[T].f(y) # E: Argument 1 to "f" of "C" has incompatible type "int"; expected "T"
C[T].f(x) # OK
return x
[builtins fixtures/classmethod.pyi]
[case testGenericClassDirectCall]
from typing import TypeVar, Generic
T = TypeVar('T')
class C(Generic[T]):
def __init__(self, item: T) -> None: ...
@classmethod
def f(cls) -> None:
cls(1) # E: Argument 1 to "C" has incompatible type "int"; expected "T"
[builtins fixtures/classmethod.pyi]
[case testGenericClassAlternativeConstructorPrecise]
from typing import Generic, TypeVar, Type, Tuple
T = TypeVar('T')
class Base(Generic[T]):
Q = TypeVar('Q', bound=Base[T])
def __init__(self, item: T) -> None: ...
@classmethod
def make_pair(cls: Type[Q], item: T) -> Tuple[Q, Q]:
if bool():
return cls(0), cls(0) # E: Argument 1 to "Base" has incompatible type "int"; expected "T"
return cls(item), cls(item)
[builtins fixtures/classmethod.pyi]
[case testGenericClassAlternativeConstructorPreciseOverloaded]
from typing import Generic, TypeVar, Type, Tuple, overload, Union
T = TypeVar('T')
class Base(Generic[T]):
Q = TypeVar('Q', bound=Base[T])
def __init__(self, item: T) -> None: ...
@overload
@classmethod
def make_some(cls: Type[Q], item: T) -> Q: ...
@overload
@classmethod
def make_some(cls: Type[Q], item: T, n: int) -> Tuple[Q, ...]: ...
@classmethod
def make_some(cls: Type[Q], item: T, n: int = 0) -> Union[Q, Tuple[Q, ...]]:
if n:
return (cls(item),)
return cls(item)
reveal_type(Base.make_some) # N: Revealed type is "Overload(def [T] (item: T`1) -> __main__.Base[T`1], def [T] (item: T`1, n: builtins.int) -> builtins.tuple[__main__.Base[T`1], ...])"
reveal_type(Base.make_some(1)) # N: Revealed type is "__main__.Base[builtins.int]"
reveal_type(Base.make_some(1, 1)) # N: Revealed type is "builtins.tuple[__main__.Base[builtins.int], ...]"
class Sub(Base[str]): ...
Sub.make_some(1) # E: No overload variant of "make_some" of "Base" matches argument type "int" \
# N: Possible overload variants: \
# N: def make_some(cls, item: str) -> Sub \
# N: def make_some(cls, item: str, n: int) -> Tuple[Sub, ...]
[builtins fixtures/classmethod.pyi]
[case testNoGenericAccessOnImplicitAttributes]
from typing import TypeVar, Generic
T = TypeVar('T')
class C(Generic[T]):
def __init__(self, x: T) -> None:
self.x = x
@classmethod
def meth(cls) -> None:
cls.x # E: Access to generic instance variables via class is ambiguous
[builtins fixtures/classmethod.pyi]
[case testGenericClassMethodUnboundOnClassNonMatchingIdNonGeneric]
from typing import Generic, TypeVar, Any, Tuple, Type
T = TypeVar('T')
S = TypeVar('S')
Q = TypeVar('Q', bound='A[Any]')
class A(Generic[T]):
@classmethod
def foo(cls: Type[Q]) -> Tuple[T, Q]: ...
class B(A[T], Generic[T, S]):
def meth(self) -> None:
reveal_type(A[T].foo) # N: Revealed type is "def () -> Tuple[T`1, __main__.A[T`1]]"
@classmethod
def other(cls) -> None:
reveal_type(cls.foo) # N: Revealed type is "def () -> Tuple[T`1, __main__.B[T`1, S`2]]"
reveal_type(B.foo) # N: Revealed type is "def [T, S] () -> Tuple[T`1, __main__.B[T`1, S`2]]"
[builtins fixtures/classmethod.pyi]
[case testGenericClassAlternativeConstructorPrecise2]
from typing import Generic, TypeVar, Type, Tuple, Any
T = TypeVar('T')
Q = TypeVar('Q')
class Base(Generic[T]):
def __init__(self, item: T) -> None: ...
@classmethod
def make_pair(cls: Type[Q], item: T) -> Tuple[Q, Q]: ...
class Sub(Base[T]):
...
reveal_type(Sub.make_pair('yes')) # N: Revealed type is "Tuple[__main__.Sub[builtins.str], __main__.Sub[builtins.str]]"
Sub[int].make_pair('no') # E: Argument 1 to "make_pair" of "Base" has incompatible type "str"; expected "int"
[builtins fixtures/classmethod.pyi]
[case testGenericClassAttrUnboundOnClass]
from typing import Generic, TypeVar
T = TypeVar('T')
class C(Generic[T]):
x: T
@classmethod
def get(cls) -> T:
return cls.x # OK
x = C.x # E: Access to generic instance variables via class is ambiguous
reveal_type(x) # N: Revealed type is "Any"
xi = C[int].x # E: Access to generic instance variables via class is ambiguous
reveal_type(xi) # N: Revealed type is "builtins.int"
[builtins fixtures/classmethod.pyi]
[case testGenericClassAttrUnboundOnSubClass]
from typing import Generic, TypeVar, Tuple
T = TypeVar('T')
class C(Generic[T]):
x: T
class D(C[int]): ...
class E(C[int]):
x = 42
x = D.x # E: Access to generic instance variables via class is ambiguous
reveal_type(x) # N: Revealed type is "builtins.int"
E.x # OK
[case testGenericClassMethodOverloaded]
from typing import Generic, TypeVar, overload, Tuple
T = TypeVar('T')
class C(Generic[T]):
@overload
@classmethod
def get(cls) -> T: ...
@overload
@classmethod
def get(cls, n: int) -> Tuple[T, ...]: ...
@classmethod
def get(cls, n: int = 0):
pass
class D(C[str]): ...
reveal_type(D.get()) # N: Revealed type is "builtins.str"
reveal_type(D.get(42)) # N: Revealed type is "builtins.tuple[builtins.str, ...]"
[builtins fixtures/classmethod.pyi]
[case testGenericClassMethodAnnotation]
from typing import Generic, TypeVar, Type
T = TypeVar('T')
class Maker(Generic[T]):
x: T
@classmethod
def get(cls) -> T: ...
class B(Maker[B]): ...
def f(o: Maker[T]) -> T:
if bool():
return o.x
return o.get()
b = f(B())
reveal_type(b) # N: Revealed type is "__main__.B"
def g(t: Type[Maker[T]]) -> T:
if bool():
return t.x
return t.get()
bb = g(B)
reveal_type(bb) # N: Revealed type is "__main__.B"
[builtins fixtures/classmethod.pyi]
[case testGenericClassMethodAnnotationDecorator]
from typing import Generic, Callable, TypeVar, Iterator
T = TypeVar('T')
class Box(Generic[T]):
@classmethod
def wrap(cls, generator: Callable[[], T]) -> Box[T]: ...
class IteratorBox(Box[Iterator[T]]): ...
@IteratorBox.wrap # E: Argument 1 to "wrap" of "Box" has incompatible type "Callable[[], int]"; expected "Callable[[], Iterator[<nothing>]]"
def g() -> int:
...
[builtins fixtures/classmethod.pyi]
[case testGenericClassMethodInGenericFunction]
from typing import Generic, TypeVar
T = TypeVar('T')
S = TypeVar('S')
class C(Generic[T]):
@classmethod
def get(cls) -> T: ...
def func(x: S) -> S:
return C[S].get()
[builtins fixtures/classmethod.pyi]
[case testMultipleAssignmentFromAnyIterable]
from typing import Any
class A:
def __iter__(self) -> Any: ...
x, y = A()
reveal_type(x) # N: Revealed type is "Any"
reveal_type(y) # N: Revealed type is "Any"
[case testSubclassingGenericSelfClassMethod]
from typing import TypeVar, Type
AT = TypeVar('AT', bound='A')
class A:
@classmethod
def from_config(cls: Type[AT]) -> AT:
...
class B(A):
@classmethod
def from_config(cls: Type[B]) -> B:
return B()
[builtins fixtures/classmethod.pyi]
[case testSubclassingGenericSelfClassMethodOptional]
from typing import TypeVar, Type, Optional
AT = TypeVar('AT', bound='A')
class A:
@classmethod
def from_config(cls: Type[AT]) -> Optional[AT]:
return None
class B(A):
@classmethod
def from_config(cls: Type[B]) -> Optional[B]:
return B()
[builtins fixtures/classmethod.pyi]
[case testSubclassingGenericSelfClassMethodNonAnnotated]
from typing import TypeVar, Type
AT = TypeVar('AT', bound='A')
class A:
@classmethod
def from_config(cls: Type[AT]) -> AT:
...
class B(A):
@classmethod
def from_config(cls) -> B:
return B()
[builtins fixtures/classmethod.pyi]
[case testAbstractGenericMethodInference]
from abc import ABC, abstractmethod
from typing import Callable, Generic, TypeVar
A = TypeVar('A')
B = TypeVar('B')
C = TypeVar('C')
class TwoTypes(Generic[A, B]):
def __call__(self) -> B: pass
class MakeTwoAbstract(ABC, Generic[A]):
def __init__(self) -> None: pass
@abstractmethod
def __call__(self, b: B) -> TwoTypes[A, B]: pass
class MakeTwoConcrete(Generic[A]):
def __call__(self, b: B) -> TwoTypes[A, B]: pass
class MakeTwoGenericSubAbstract(Generic[C], MakeTwoAbstract[C]):
def __call__(self, b: B) -> TwoTypes[C, B]: pass
class MakeTwoAppliedSubAbstract(MakeTwoAbstract[str]):
def __call__(self, b: B) -> TwoTypes[str, B]: pass
class Test():
def make_two(self,
mts: MakeTwoAbstract[A],
mte: MakeTwoConcrete[A],
mtgsa: MakeTwoGenericSubAbstract[A],
mtasa: MakeTwoAppliedSubAbstract) -> None:
reveal_type(mts(2)) # N: Revealed type is "__main__.TwoTypes[A`-1, builtins.int]"
reveal_type(mte(2)) # N: Revealed type is "__main__.TwoTypes[A`-1, builtins.int]"
reveal_type(mtgsa(2)) # N: Revealed type is "__main__.TwoTypes[A`-1, builtins.int]"
reveal_type(mtasa(2)) # N: Revealed type is "__main__.TwoTypes[builtins.str, builtins.int]"
reveal_type(MakeTwoConcrete[int]()('foo')) # N: Revealed type is "__main__.TwoTypes[builtins.int, builtins.str]"
reveal_type(MakeTwoConcrete[str]()(2)) # N: Revealed type is "__main__.TwoTypes[builtins.str, builtins.int]"
reveal_type(MakeTwoAppliedSubAbstract()('foo')) # N: Revealed type is "__main__.TwoTypes[builtins.str, builtins.str]"
reveal_type(MakeTwoAppliedSubAbstract()(2)) # N: Revealed type is "__main__.TwoTypes[builtins.str, builtins.int]"
reveal_type(MakeTwoGenericSubAbstract[str]()('foo')) # N: Revealed type is "__main__.TwoTypes[builtins.str, builtins.str]"
reveal_type(MakeTwoGenericSubAbstract[str]()(2)) # N: Revealed type is "__main__.TwoTypes[builtins.str, builtins.int]"
[case testGenericClassPropertyBound]
from typing import Generic, TypeVar, Callable, Type, List, Dict
T = TypeVar('T')
U = TypeVar('U')
def classproperty(f: Callable[..., U]) -> U: ...
class C(Generic[T]):
@classproperty
def test(self) -> T: ...
class D(C[str]): ...
class E1(C[T], Generic[T, U]): ...
class E2(C[U], Generic[T, U]): ...
class G(C[List[T]]): ...
x: C[int]
y: Type[C[int]]
reveal_type(x.test) # N: Revealed type is "builtins.int"
reveal_type(y.test) # N: Revealed type is "builtins.int"
xd: D
yd: Type[D]
reveal_type(xd.test) # N: Revealed type is "builtins.str"
reveal_type(yd.test) # N: Revealed type is "builtins.str"
ye1: Type[E1[int, str]]
ye2: Type[E2[int, str]]
reveal_type(ye1.test) # N: Revealed type is "builtins.int"
reveal_type(ye2.test) # N: Revealed type is "builtins.str"
xg: G[int]
yg: Type[G[int]]
reveal_type(xg.test) # N: Revealed type is "builtins.list[builtins.int]"
reveal_type(yg.test) # N: Revealed type is "builtins.list[builtins.int]"
class Sup:
attr: int
S = TypeVar('S', bound=Sup)
def func(tp: Type[C[S]]) -> S:
reveal_type(tp.test.attr) # N: Revealed type is "builtins.int"
reg: Dict[S, G[S]]
reveal_type(reg[tp.test]) # N: Revealed type is "__main__.G[S`-1]"
reveal_type(reg[tp.test].test) # N: Revealed type is "builtins.list[S`-1]"
if bool():
return tp.test
else:
return reg[tp.test].test[0]
[builtins fixtures/dict.pyi]
[case testGenericFunctionAliasExpand]
from typing import Optional, TypeVar
T = TypeVar("T")
def gen(x: T) -> T: ...
gen_a = gen
S = TypeVar("S", int, str)
class C: ...
def test() -> Optional[S]:
reveal_type(gen_a(C())) # N: Revealed type is "__main__.C"
return None
[case testGenericFunctionMemberExpand]
from typing import Optional, TypeVar, Callable
T = TypeVar("T")
class A:
def __init__(self) -> None:
self.gen: Callable[[T], T]
S = TypeVar("S", int, str)
class C: ...
def test() -> Optional[S]:
reveal_type(A().gen(C())) # N: Revealed type is "__main__.C"
return None
[case testGenericJoinCovariant]
from typing import Generic, TypeVar, List
T = TypeVar("T", covariant=True)
class Container(Generic[T]): ...
class Base: ...
class A(Base): ...
class B(Base): ...
a: A
b: B
a_c: Container[A]
b_c: Container[B]
reveal_type([a, b]) # N: Revealed type is "builtins.list[__main__.Base]"
reveal_type([a_c, b_c]) # N: Revealed type is "builtins.list[__main__.Container[__main__.Base]]"
[builtins fixtures/list.pyi]
[case testGenericJoinContravariant]
from typing import Generic, TypeVar, List
T = TypeVar("T", contravariant=True)
class Container(Generic[T]): ...
class A: ...
class B(A): ...
a_c: Container[A]
b_c: Container[B]
# TODO: this can be more precise than "object", see a comment in mypy/join.py
reveal_type([a_c, b_c]) # N: Revealed type is "builtins.list[builtins.object]"
[builtins fixtures/list.pyi]
[case testGenericJoinRecursiveTypes]
from typing import Sequence, TypeVar
class A(Sequence[A]): ...
class B(Sequence[B]): ...
a: A
b: B
reveal_type([a, b]) # N: Revealed type is "builtins.list[typing.Sequence[builtins.object]]"
[builtins fixtures/list.pyi]
[case testGenericJoinRecursiveInvariant]
from typing import Generic, TypeVar
T = TypeVar("T")
class I(Generic[T]): ...
class A(I[A]): ...
class B(I[B]): ...
a: A
b: B
reveal_type([a, b]) # N: Revealed type is "builtins.list[builtins.object]"
[builtins fixtures/list.pyi]
[case testGenericJoinNestedInvariantAny]
from typing import Any, Generic, TypeVar
T = TypeVar("T")
class I(Generic[T]): ...
a: I[I[int]]
b: I[I[Any]]
reveal_type([a, b]) # N: Revealed type is "builtins.list[__main__.I[__main__.I[Any]]]"
reveal_type([b, a]) # N: Revealed type is "builtins.list[__main__.I[__main__.I[Any]]]"
[builtins fixtures/list.pyi]
[case testOverlappingTypeVarIds]
from typing import TypeVar, Generic
class A: ...
class B: ...
T = TypeVar("T", bound=A)
V = TypeVar("V", bound=B)
S = TypeVar("S")
class Whatever(Generic[T]):
def something(self: S) -> S:
return self
# the "V" here had the same id as "T" and so mypy used to think it could expand one into another.
# this test is here to make sure that doesn't happen!
class WhateverPartTwo(Whatever[A], Generic[V]):
def something(self: S) -> S:
return self
[case testConstrainedGenericSuper]
from typing import Generic, TypeVar
AnyStr = TypeVar("AnyStr", str, bytes)
class Foo(Generic[AnyStr]):
def method1(self, s: AnyStr, t: AnyStr) -> None: ...
class Bar(Foo[AnyStr]):
def method1(self, s: AnyStr, t: AnyStr) -> None:
super().method1('x', b'y') # Should be an error
[out]
main:10: error: Argument 1 to "method1" of "Foo" has incompatible type "str"; expected "AnyStr"
main:10: error: Argument 2 to "method1" of "Foo" has incompatible type "bytes"; expected "AnyStr"
[case testTypeVariableClashVar]
from typing import Generic, TypeVar, Callable
T = TypeVar("T")
R = TypeVar("R")
class C(Generic[R]):
x: Callable[[T], R]
def func(x: C[R]) -> R:
return x.x(42) # OK
[case testTypeVariableClashVarTuple]
from typing import Generic, TypeVar, Callable, Tuple
T = TypeVar("T")
R = TypeVar("R")
class C(Generic[R]):
x: Callable[[T], Tuple[R, T]]
def func(x: C[R]) -> R:
if bool():
return x.x(42)[0] # OK
else:
return x.x(42)[1] # E: Incompatible return value type (got "int", expected "R")
[builtins fixtures/tuple.pyi]
[case testTypeVariableClashMethod]
from typing import Generic, TypeVar, Callable
T = TypeVar("T")
R = TypeVar("R")
class C(Generic[R]):
def x(self) -> Callable[[T], R]: ...
def func(x: C[R]) -> R:
return x.x()(42) # OK
[case testTypeVariableClashMethodTuple]
from typing import Generic, TypeVar, Callable, Tuple
T = TypeVar("T")
R = TypeVar("R")
class C(Generic[R]):
def x(self) -> Callable[[T], Tuple[R, T]]: ...
def func(x: C[R]) -> R:
if bool():
return x.x()(42)[0] # OK
else:
return x.x()(42)[1] # E: Incompatible return value type (got "int", expected "R")
[builtins fixtures/tuple.pyi]
[case testTypeVariableClashVarSelf]
from typing import Self, TypeVar, Generic, Callable
T = TypeVar("T")
S = TypeVar("S")
class C(Generic[T]):
x: Callable[[S], Self]
y: T
def foo(x: C[T]) -> T:
return x.x(42).y # OK
[case testNestedGenericFunctionTypeApplication]
from typing import TypeVar, Generic, List
A = TypeVar("A")
B = TypeVar("B")
class C(Generic[A]):
x: A
def foo(x: A) -> A:
def bar() -> List[A]:
y = C[List[A]]()
z = C[List[B]]() # E: Type variable "__main__.B" is unbound \
# N: (Hint: Use "Generic[B]" or "Protocol[B]" base class to bind "B" inside a class) \
# N: (Hint: Use "B" in function signature to bind "B" inside a function)
return y.x
return bar()[0]
-- TypeVar imported from typing_extensions
-- ---------------------------------------
[case testTypeVarTypingExtensionsSimpleGeneric]
from typing import Generic
from typing_extensions import TypeVar
T = TypeVar("T")
class A(Generic[T]):
def __init__(self, value: T) -> None:
self.value = value
a: A = A(8)
b: A[str] = A("")
reveal_type(A(1.23)) # N: Revealed type is "__main__.A[builtins.float]"
[builtins fixtures/tuple.pyi]
[case testTypeVarTypingExtensionsSimpleBound]
from typing_extensions import TypeVar
T= TypeVar("T")
def func(var: T) -> T:
return var
reveal_type(func(1)) # N: Revealed type is "builtins.int"
[builtins fixtures/tuple.pyi]
[case testGenericLambdaGenericMethodNoCrash]
from typing import TypeVar, Union, Callable, Generic
S = TypeVar("S")
T = TypeVar("T")
def f(x: Callable[[G[T]], int]) -> T: ...
class G(Generic[T]):
def g(self, x: S) -> Union[S, T]: ...
f(lambda x: x.g(0)) # E: Cannot infer type argument 1 of "f"
[case testDictStarInference]
class B: ...
class C1(B): ...
class C2(B): ...
dict1 = {"a": C1()}
dict2 = {"a": C2(), **dict1}
reveal_type(dict2) # N: Revealed type is "builtins.dict[builtins.str, __main__.B]"
[builtins fixtures/dict.pyi]
[case testDictStarAnyKeyJoinValue]
from typing import Any
class B: ...
class C1(B): ...
class C2(B): ...
dict1: Any
dict2 = {"a": C1(), **{x: C2() for x in dict1}}
reveal_type(dict2) # N: Revealed type is "builtins.dict[Any, __main__.B]"
[builtins fixtures/dict.pyi]
-- Type inference for generic decorators applied to generic callables
-- ------------------------------------------------------------------
[case testInferenceAgainstGenericCallable]
# flags: --new-type-inference
from typing import TypeVar, Callable, List
X = TypeVar('X')
T = TypeVar('T')
def foo(x: Callable[[int], X]) -> List[X]:
...
def bar(x: Callable[[X], int]) -> List[X]:
...
def id(x: T) -> T:
...
reveal_type(foo(id)) # N: Revealed type is "builtins.list[builtins.int]"
reveal_type(bar(id)) # N: Revealed type is "builtins.list[builtins.int]"
[builtins fixtures/list.pyi]
[case testInferenceAgainstGenericCallableNoLeak]
# flags: --new-type-inference
from typing import TypeVar, Callable
T = TypeVar('T')
def f(x: Callable[..., T]) -> T:
return x()
def tpl(x: T) -> T:
return x
# This is valid because of "..."
reveal_type(f(tpl)) # N: Revealed type is "Any"
[out]
[case testInferenceAgainstGenericCallableChain]
# flags: --new-type-inference
from typing import TypeVar, Callable, List
X = TypeVar('X')
T = TypeVar('T')
def chain(f: Callable[[X], T], g: Callable[[T], int]) -> Callable[[X], int]: ...
def id(x: T) -> T:
...
reveal_type(chain(id, id)) # N: Revealed type is "def (builtins.int) -> builtins.int"
[builtins fixtures/list.pyi]
[case testInferenceAgainstGenericCallableGeneric]
# flags: --new-type-inference
from typing import TypeVar, Callable, List
S = TypeVar('S')
T = TypeVar('T')
U = TypeVar('U')
def dec(f: Callable[[S], T]) -> Callable[[S], List[T]]:
...
def id(x: U) -> U:
...
reveal_type(dec(id)) # N: Revealed type is "def [S] (S`1) -> builtins.list[S`1]"
@dec
def same(x: U) -> U:
...
reveal_type(same) # N: Revealed type is "def [S] (S`3) -> builtins.list[S`3]"
reveal_type(same(42)) # N: Revealed type is "builtins.list[builtins.int]"
[builtins fixtures/list.pyi]
[case testInferenceAgainstGenericCallableGenericReverse]
# flags: --new-type-inference
from typing import TypeVar, Callable, List
S = TypeVar('S')
T = TypeVar('T')
U = TypeVar('U')
def dec(f: Callable[[S], List[T]]) -> Callable[[S], T]:
...
def id(x: U) -> U:
...
reveal_type(dec(id)) # N: Revealed type is "def [T] (builtins.list[T`2]) -> T`2"
@dec
def same(x: U) -> U:
...
reveal_type(same) # N: Revealed type is "def [T] (builtins.list[T`4]) -> T`4"
reveal_type(same([42])) # N: Revealed type is "builtins.int"
[builtins fixtures/list.pyi]
[case testInferenceAgainstGenericCallableGenericArg]
# flags: --new-type-inference
from typing import TypeVar, Callable, List
S = TypeVar('S')
T = TypeVar('T')
U = TypeVar('U')
def dec(f: Callable[[S], T]) -> Callable[[S], T]:
...
def test(x: U) -> List[U]:
...
reveal_type(dec(test)) # N: Revealed type is "def [S] (S`1) -> builtins.list[S`1]"
@dec
def single(x: U) -> List[U]:
...
reveal_type(single) # N: Revealed type is "def [S] (S`3) -> builtins.list[S`3]"
reveal_type(single(42)) # N: Revealed type is "builtins.list[builtins.int]"
[builtins fixtures/list.pyi]
[case testInferenceAgainstGenericCallableGenericChain]
# flags: --new-type-inference
from typing import TypeVar, Callable, List
S = TypeVar('S')
T = TypeVar('T')
U = TypeVar('U')
def comb(f: Callable[[T], S], g: Callable[[S], U]) -> Callable[[T], U]: ...
def id(x: U) -> U:
...
reveal_type(comb(id, id)) # N: Revealed type is "def [T] (T`1) -> T`1"
[builtins fixtures/list.pyi]
[case testInferenceAgainstGenericCallableGenericNonLinear]
# flags: --new-type-inference
from typing import TypeVar, Callable, List
S = TypeVar('S')
T = TypeVar('T')
U = TypeVar('U')
def mix(fs: List[Callable[[S], T]]) -> Callable[[S], List[T]]:
def inner(x: S) -> List[T]:
return [f(x) for f in fs]
return inner
# Errors caused by arg *name* mismatch are truly cryptic, but this is a known issue :/
def id(__x: U) -> U:
...
fs = [id, id, id]
reveal_type(mix(fs)) # N: Revealed type is "def [S] (S`3) -> builtins.list[S`3]"
reveal_type(mix([id, id, id])) # N: Revealed type is "def [S] (S`5) -> builtins.list[S`5]"
[builtins fixtures/list.pyi]
[case testInferenceAgainstGenericCurry]
# flags: --new-type-inference
from typing import Callable, List, TypeVar
S = TypeVar("S")
T = TypeVar("T")
U = TypeVar("U")
V = TypeVar("V")
def dec1(f: Callable[[T], S]) -> Callable[[], Callable[[T], S]]: ...
def dec2(f: Callable[[T, U], S]) -> Callable[[U], Callable[[T], S]]: ...
def test1(x: V) -> V: ...
def test2(x: V, y: V) -> V: ...
reveal_type(dec1(test1)) # N: Revealed type is "def () -> def [T] (T`1) -> T`1"
reveal_type(dec2(test2)) # N: Revealed type is "def [T] (T`3) -> def (T`3) -> T`3"
[builtins fixtures/list.pyi]
[case testInferenceAgainstGenericCallableNewVariable]
# flags: --new-type-inference
from typing import TypeVar, Callable, List
S = TypeVar('S')
T = TypeVar('T')
U = TypeVar('U')
def dec(f: Callable[[S], T]) -> Callable[[S], T]:
...
def test(x: List[U]) -> List[U]:
...
reveal_type(dec(test)) # N: Revealed type is "def [U] (builtins.list[U`-1]) -> builtins.list[U`-1]"
[builtins fixtures/list.pyi]
[case testInferenceAgainstGenericCallableGenericAlias]
# flags: --new-type-inference
from typing import TypeVar, Callable, List
S = TypeVar('S')
T = TypeVar('T')
U = TypeVar('U')
A = Callable[[S], T]
B = Callable[[S], List[T]]
def dec(f: A[S, T]) -> B[S, T]:
...
def id(x: U) -> U:
...
reveal_type(dec(id)) # N: Revealed type is "def [S] (S`1) -> builtins.list[S`1]"
[builtins fixtures/list.pyi]
[case testInferenceAgainstGenericCallableGenericProtocol]
# flags: --new-type-inference
from typing import TypeVar, Protocol, Generic, Optional
T = TypeVar('T')
class F(Protocol[T]):
def __call__(self, __x: T) -> T: ...
def lift(f: F[T]) -> F[Optional[T]]: ...
def g(x: T) -> T:
return x
reveal_type(lift(g)) # N: Revealed type is "def [T] (Union[T`1, None]) -> Union[T`1, None]"
[builtins fixtures/list.pyi]
[case testInferenceAgainstGenericSplitOrder]
# flags: --new-type-inference
from typing import TypeVar, Callable, List
S = TypeVar('S')
T = TypeVar('T')
U = TypeVar('U')
def dec(f: Callable[[T], S], g: Callable[[T], int]) -> Callable[[T], List[S]]: ...
def id(x: U) -> U:
...
reveal_type(dec(id, id)) # N: Revealed type is "def (builtins.int) -> builtins.list[builtins.int]"
[builtins fixtures/list.pyi]
[case testInferenceAgainstGenericSplitOrderGeneric]
# flags: --new-type-inference
from typing import TypeVar, Callable, Tuple
S = TypeVar('S')
T = TypeVar('T')
U = TypeVar('U')
V = TypeVar('V')
def dec(f: Callable[[T], S], g: Callable[[T], U]) -> Callable[[T], Tuple[S, U]]: ...
def id(x: V) -> V:
...
reveal_type(dec(id, id)) # N: Revealed type is "def [T] (T`1) -> Tuple[T`1, T`1]"
[builtins fixtures/tuple.pyi]
[case testInferenceAgainstGenericEllipsisSelfSpecialCase]
# flags: --new-type-inference
from typing import Self, Callable, TypeVar
T = TypeVar("T")
def dec(f: Callable[..., T]) -> Callable[..., T]: ...
class C:
@dec
def test(self) -> Self: ...
c: C
reveal_type(c.test()) # N: Revealed type is "__main__.C"
[case testInferenceAgainstGenericBoundsAndValues]
# flags: --new-type-inference
from typing import TypeVar, Callable, List
class B: ...
class C(B): ...
S = TypeVar('S')
T = TypeVar('T')
UB = TypeVar('UB', bound=B)
UC = TypeVar('UC', bound=C)
V = TypeVar('V', int, str)
def dec1(f: Callable[[S], T]) -> Callable[[S], List[T]]:
...
def dec2(f: Callable[[UC], T]) -> Callable[[UC], List[T]]:
...
def id1(x: UB) -> UB:
...
def id2(x: V) -> V:
...
reveal_type(dec1(id1)) # N: Revealed type is "def [S <: __main__.B] (S`1) -> builtins.list[S`1]"
reveal_type(dec1(id2)) # N: Revealed type is "def [S in (builtins.int, builtins.str)] (S`3) -> builtins.list[S`3]"
reveal_type(dec2(id1)) # N: Revealed type is "def [UC <: __main__.C] (UC`5) -> builtins.list[UC`5]"
reveal_type(dec2(id2)) # N: Revealed type is "def (<nothing>) -> builtins.list[<nothing>]" \
# E: Argument 1 to "dec2" has incompatible type "Callable[[V], V]"; expected "Callable[[<nothing>], <nothing>]"