| -- Simple generic types |
| -- -------------------- |
| |
| |
| [case testGenericMethodReturnType] |
| from typing import TypeVar, Generic |
| T = TypeVar('T') |
| a, b, c = None, None, None # type: (A[B], B, C) |
| c = a.f() # Fail |
| b = a.f() |
| |
| class A(Generic[T]): |
| def f(self) -> T: pass |
| |
| class B: pass |
| class C: pass |
| [out] |
| main:4: error: Incompatible types in assignment (expression has type "B", variable has type "C") |
| |
| [case testGenericMethodArgument] |
| from typing import TypeVar, Generic |
| T = TypeVar('T') |
| a.f(c) # Fail |
| a.f(b) |
| |
| a = None # type: A[B] |
| b = None # type: B |
| c = None # type: C |
| |
| class A(Generic[T]): |
| def f(self, a: T) -> None: pass |
| |
| class B: pass |
| class C: pass |
| [out] |
| main:3: error: Argument 1 to "f" of "A" has incompatible type "C"; expected "B" |
| |
| [case testGenericMemberVariable] |
| from typing import TypeVar, Generic |
| T = TypeVar('T') |
| class A(Generic[T]): |
| def __init__(self, v: T) -> None: |
| self.v = v |
| |
| a, b, c = None, None, None # type: (A[B], B, C) |
| a.v = c # Fail |
| a.v = b |
| |
| class B: pass |
| class C: pass |
| [out] |
| main:8: error: Incompatible types in assignment (expression has type "C", variable has type "B") |
| |
| [case testGenericMemberVariable] |
| from typing import TypeVar, Generic |
| T = TypeVar('T') |
| a, b, c = None, None, None # type: (A[B], B, C) |
| a.v = c # Fail |
| a.v = b |
| |
| class A(Generic[T]): |
| v = None # type: T |
| class B: pass |
| class C: pass |
| [out] |
| main:4: error: Incompatible types in assignment (expression has type "C", variable has type "B") |
| |
| [case testSimpleGenericSubtyping] |
| from typing import TypeVar, Generic |
| T = TypeVar('T') |
| b, bb, c = None, None, None # type: (A[B], A[B], A[C]) |
| c = b # Fail |
| b = c # Fail |
| |
| b = b |
| b = bb |
| |
| class A(Generic[T]): pass |
| class B: pass |
| class C(B): pass |
| [out] |
| main:4: error: Incompatible types in assignment (expression has type A[B], variable has type A[C]) |
| main:5: error: Incompatible types in assignment (expression has type A[C], variable has type A[B]) |
| |
| [case testGenericTypeCompatibilityWithAny] |
| from typing import Any, TypeVar, Generic |
| T = TypeVar('T') |
| b, c, d = None, None, None # type: (A[B], A[C], A[Any]) |
| |
| b = d |
| c = d |
| d = b |
| d = c |
| |
| class A(Generic[T]): pass |
| class B: pass |
| class C(B): pass |
| [out] |
| |
| [case testTypeVariableAsTypeArgument] |
| from typing import TypeVar, Generic |
| T = TypeVar('T') |
| a = None # type: A[B] |
| b = None # type: A[B] |
| c = None # type: A[C] |
| |
| a.v = c # Fail |
| c = a.v # Fail |
| a.v = b |
| b = a.v |
| |
| class A(Generic[T]): |
| v = None # type: A[T] |
| |
| class B: pass |
| class C: pass |
| [out] |
| main:7: error: Incompatible types in assignment (expression has type A[C], variable has type A[B]) |
| main:8: error: Incompatible types in assignment (expression has type A[B], variable has type A[C]) |
| |
| [case testMultipleGenericTypeParametersWithMemberVars] |
| from typing import TypeVar, Generic |
| S = TypeVar('S') |
| T = TypeVar('T') |
| a = None # type: A[B, C] |
| s = None # type: B |
| t = None # type: C |
| |
| t = a.s # Fail |
| s = a.t # Fail |
| |
| s = a.s |
| t = a.t |
| |
| class A(Generic[S, T]): |
| s = None # type: S |
| t = None # type: T |
| class B: pass |
| class C: pass |
| [out] |
| main:8: error: Incompatible types in assignment (expression has type "B", variable has type "C") |
| main:9: error: Incompatible types in assignment (expression has type "C", variable has type "B") |
| |
| [case testMultipleGenericTypeParametersWithMethods] |
| from typing import TypeVar, Generic |
| S = TypeVar('S') |
| T = TypeVar('T') |
| a = None # type: A[B, C] |
| s = None # type: B |
| t = None # type: 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 = None # type: A[B, C] |
| bb = None # type: A[B, B] |
| cb = None # type: A[C, B] |
| |
| bb = bc # Fail |
| bb = cb # Fail |
| bc = bb # Fail |
| |
| bb = bb |
| bc = bc |
| |
| class A(Generic[S, T]): |
| s = None # type: S |
| t = None # type: T |
| |
| class B: pass |
| class C(B):pass |
| [out] |
| main:8: error: Incompatible types in assignment (expression has type A[B, C], variable has type A[B, B]) |
| main:9: error: Incompatible types in assignment (expression has type A[C, B], variable has type A[B, B]) |
| main:10: error: Incompatible types in assignment (expression has type A[B, B], variable has type A[B, C]) |
| |
| |
| -- Simple generic type bodies |
| -- -------------------------- |
| |
| |
| [case testGenericTypeBody1] |
| from typing import TypeVar, Generic |
| T = TypeVar('T') |
| class A(Generic[T]): |
| a = None # type: 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 = None # type: 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 = None # type: S |
| t = None # type: T |
| s = t # Fail |
| t = s # Fail |
| a = self # type: A[S, B] # Fail |
| b = self # type: A[T, T] # Fail |
| c = self # type: A[S, T] |
| t = t |
| |
| class B: pass |
| [out] |
| main:8: error: Incompatible types in assignment (expression has type "T", variable has type "S") |
| main:9: error: Incompatible types in assignment (expression has type "S", variable has type "T") |
| main:10: error: Incompatible types in assignment (expression has type A[S, T], variable has type A[S, B]) |
| main:11: error: Incompatible types in assignment (expression has type A[S, T], variable has type A[T, T]) |
| |
| [case testCompatibilityOfNoneWithTypeVar] |
| 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] |
| from typing import TypeVar, Generic |
| T = TypeVar('T') |
| class A(Generic[T]): |
| def f(self) -> T: |
| a = object() # type: T # Fail |
| a = object() # Fail |
| b = self.f() # type: object |
| b = self.f() |
| [out] |
| main:5: error: Incompatible types in assignment (expression has type "object", variable has type "T") |
| main:6: error: Incompatible types in assignment (expression has type "object", variable has type "T") |
| |
| |
| -- Operations with generic types |
| -- ----------------------------- |
| |
| |
| [case testGenericOperations] |
| from typing import TypeVar, Generic |
| S = TypeVar('S') |
| T = TypeVar('T') |
| a = None # type: A[B, C] |
| b = None # type: B |
| c = None # type: C |
| |
| b = a + b # Fail |
| c = a + c # Fail |
| c = a[c] # Fail |
| b = a[b] # Fail |
| |
| 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 |
| [out] |
| main:8: error: Incompatible types in assignment (expression has type "C", variable has type "B") |
| main:9: error: Unsupported operand types for + ("A" and "C") |
| main:10: error: Incompatible types in assignment (expression has type "B", variable has type "C") |
| main:11: error: Invalid index type "B" for "A"; expected type "C" |
| |
| [case testOperatorAssignmentWithIndexLvalue1] |
| from typing import TypeVar, Generic |
| T = TypeVar('T') |
| b = None # type: B |
| c = None # type: C |
| ac = None # type: 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:7: error: Incompatible types in assignment (expression has type "B", target has type "C") |
| main:8: error: Invalid index type "C" for "A"; expected type "B" |
| |
| [case testOperatorAssignmentWithIndexLvalue2] |
| from typing import TypeVar, Generic |
| T = TypeVar('T') |
| b = None # type: B |
| c = None # type: C |
| ac = None # type: 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"; expected type "C" |
| main:8: error: Invalid index type "C" for "A"; expected type "B" |
| main:9: error: Invalid index type "B" for "A"; expected type "C" |
| |
| |
| -- Nested generic types |
| -- -------------------- |
| |
| |
| [case testNestedGenericTypes] |
| from typing import TypeVar, Generic |
| T = TypeVar('T') |
| aab = None # type: A[A[B]] |
| aac = None # type: A[A[C]] |
| ab = None # type: A[B] |
| ac = None # type: A[C] |
| |
| ac = aab.x # Fail |
| ac.y = aab # Fail |
| |
| ab = aab.x |
| ac = aac.x |
| ab.y = aab |
| ac.y = aac |
| |
| class A(Generic[T]): |
| x = None # type: T |
| y = None # type: A[A[T]] |
| |
| class B: |
| pass |
| class C: |
| pass |
| [out] |
| main:8: error: Incompatible types in assignment (expression has type A[B], variable has type A[C]) |
| main:9: error: Incompatible types in assignment (expression has type A[A[B]], variable has type A[A[C]]) |
| |
| |
| -- 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") |
| s = t # E: Incompatible types in assignment (expression has type "T", variable has type "S") |
| p_s_a = None # type: 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 = None # type: 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]: |
| s = t # E: Incompatible types in assignment (expression has type "T", variable has type "S") |
| p_s_s = None # type: 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 = None # type: p[T, T] |
| if t: |
| return p_t_t # E: Incompatible return value type (got p[T, T], expected p[S, T]) |
| t = t |
| s = s |
| p_s_t = None # type: 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: Too few arguments for "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 = None # type: A |
| class A: pass |
| a[A]() # E: Value of type "A" is not indexable |
| A[A]() # E: Type application targets a non-generic function or class |
| [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]()) # E: Revealed type is '__main__.Dummy[builtins.int*]' |
| reveal_type(Dummy[int]().methout()) # E: 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], Generic[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: Type application targets a non-generic function or class |
| [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) # E: 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) # Eroor - 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()) # E: Revealed type is '__main__.Node[builtins.int, builtins.str]' |
| |
| def func(x: IntNode[T]) -> IntNode[T]: |
| return x |
| reveal_type(func) # E: 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, None] |
| func(Node('x', 1)) # E: Argument 1 to "Node" has incompatible type "str"; expected "int" |
| reveal_type(func(Node(1, 'x'))) # E: Revealed type is '__main__.Node[builtins.int, builtins.str*]' |
| |
| def func2(x: SameNode[T]) -> SameNode[T]: |
| return x |
| reveal_type(func2) # E: 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) # E: Revealed type is '__main__.Node[builtins.str*, builtins.str*]' |
| |
| def wrap(x: T) -> IntNode[T]: |
| return Node(1, x) |
| |
| z = None # type: str |
| reveal_type(wrap(z)) # E: Revealed type is '__main__.Node[builtins.int, builtins.str*]' |
| |
| [out] |
| main:13: error: Argument 2 to "Node" has incompatible type "int"; expected "str" |
| |
| [case testGenericTypeAliasesWrongAliases] |
| # flags: --show-column-numbers --fast-parser --python-version 3.6 |
| 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 # Error |
| 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:4: error: "Node" expects 2 type arguments, but 1 given |
| main:11:4: error: "Node" expects 2 type arguments, but 3 given |
| main:15:9: error: "list" expects 1 type argument, but 2 given |
| main:16:18: error: "list" expects 1 type argument, but 2 given |
| main:17:24: error: "Node" expects 2 type arguments, but 1 given |
| main:18:3: error: "Node" expects 2 type arguments, but 1 given |
| main:19:4: error: Bad number of arguments for type alias, expected: 1, given: 2 |
| main:22:0: error: Revealed type is '__main__.Node[builtins.int, builtins.str]' |
| main:24:0: error: Revealed type is '__main__.Node[__main__.Node[builtins.int, builtins.int], builtins.list[builtins.int]]' |
| main:26:4: 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')) # E: Revealed type is '__main__.Node[builtins.list[builtins.int], builtins.list[builtins.str*]]' |
| |
| def f3() -> Third: |
| return Node([1], ['x']) |
| reveal_type(f3()) # E: Revealed type is 'Union[builtins.int, __main__.Node[builtins.list[builtins.int], builtins.list[builtins.str]]]' |
| |
| [builtins fixtures/list.pyi] |
| |
| [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 = None # type: 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) # E: 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 = None # type: ListedNode[int] |
| l.x.append(1) |
| l.meth().append(1) |
| reveal_type(l.meth()) # E: 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(Generic[T], TupledNode[T]): |
| ... |
| class L(Generic[T], 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')) # E: 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]): ... # E: Invalid type "__main__.T" |
| class E(Generic[T], UNode[T]): ... # E: Invalid base class |
| |
| [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 + (some union) |
| 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 1: |
| return Node(x) |
| else: |
| return 1 |
| |
| reveal_type(f(1)) # E: 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() # Any simplifies Union to Any now. This test should be updated after #2197 |
| |
| [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) # E: 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, None]" |
| reveal_type(f2((1, 'x'))) # E: 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: Invalid function type |
| |
| 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)) # E: 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 = None # type: 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)) # E: Revealed type is '__main__.Node[builtins.int]' |
| |
| [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]) # E: 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)])) # E: Revealed type is 'builtins.int*' |
| fun1(1) # E: Argument 1 to "fun1" has incompatible type "int"; expected List[Tuple[int, int]] |
| fun1([(1, 'x')]) # E: Cannot infer type argument 1 of "fun1" |
| |
| reveal_type(fun2([(1, 1)], 1)) # E: Revealed type is 'builtins.list[Tuple[builtins.int*, builtins.int*]]' |
| fun2([('x', 'x')], 'x') # E: Type argument 1 of "fun2" has incompatible value "str" |
| |
| [builtins fixtures/list.pyi] |
| |
| [case testGenericTypeAliasesImporting] |
| from typing import TypeVar |
| from a import Node, TupledNode |
| T = TypeVar('T') |
| |
| n = None # type: 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[None, None] |
| f(Node(1, 'x')) # E: Cannot infer type argument 1 of "f" |
| reveal_type(Node('x', 'x')) # E: 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 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: Need type annotation for variable |
| a = SameNode(1, 'x') |
| reveal_type(a) # E: Revealed type is '__main__.Node[Any, Any]' |
| b = SameNode[int](1, 1) |
| reveal_type(b) # E: 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[str] + 1 # E: Unsupported left operand type for + ("Type alias to Callable") |
| reveal_type(cs) # E: Revealed type is 'Any' |
| |
| ts = TA[str]() # E: "Type alias to Tuple" not callable |
| reveal_type(ts) # E: Revealed type is 'Any' |
| |
| us = UA[str].x # E: "Type alias to Union" has no attribute "x" |
| reveal_type(us) # E: Revealed type is 'Any' |
| |
| [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) # E: Revealed type is '__main__.A[builtins.int*, builtins.int*]' |
| reveal_type(C[str]().b) # E: Revealed type is '__main__.B[builtins.str*, builtins.str*]' |
| |
| [builtins fixtures/list.pyi] |
| |
| [case testGenericTypeAliasesTypeVarConstraints] |
| # flags: --show-column-numbers |
| 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] # Two errors here, for both args of A |
| |
| [builtins fixtures/list.pyi] |
| [out] |
| main:9:7: error: Type argument 1 of "A" has incompatible value "str" |
| main:13: error: Type argument 1 of "A" has incompatible value "str" |
| main:13: error: Type argument 2 of "A" has incompatible value "str" |
| |
| [case testGenericTypeAliasesIgnoredPotentialAlias] |
| class A: ... |
| Bad = A[int] # type: ignore |
| |
| reveal_type(Bad) # E: Revealed type is 'Any' |
| [out] |
| |
| |
| -- Multiple assignment with lists |
| -- ------------------------------ |
| |
| |
| [case testMultipleAssignmentWithLists] |
| from typing import List |
| class A: pass |
| class B: pass |
| class B2(B): pass |
| a = None # type: A |
| b = None # type: B |
| b2 = None # type: B2 |
| |
| list_a = [a] |
| list_b = [b] |
| list_b2 = [b2] |
| |
| a, b = list_a # E: Incompatible types in assignment (expression has type "A", variable has type "B") |
| b, a = list_a # E: Incompatible types in assignment (expression has type "A", variable has type "B") |
| 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 = None # type: List[A] |
| b = None # type: 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], Generic[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 |
| |
| [case testMultipleAssignmentWithIterable] |
| from typing import Iterable, TypeVar |
| a = None # type: int |
| b = None # type: 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 = None # 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] |
| |
| f(a) # E: Argument 1 to "f" has incompatible type A[...]; expected "OO" |
| |
| def f(a: OO) -> None: |
| pass |
| 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 = None # type: A[object, B] |
| f(a) # E: Argument 1 to "f" has incompatible type A[object, B]; expected "B" |
| |
| def f(a: 'B') -> None: pass |
| class A(Generic[S, T]): pass |
| class B: pass |
| |
| [case testErrorWithShorterGenericTypeName2] |
| from typing import Callable, TypeVar, Generic |
| S = TypeVar('S') |
| T = TypeVar('T') |
| a = None # type: A[object, Callable[[], None]] |
| f(a) # E: Argument 1 to "f" has incompatible type A[object, Callable[[], None]]; expected "B" |
| |
| def f(a: 'B') -> None: pass |
| class A(Generic[S, T]): pass |
| class B: pass |
| |
| |
| -- Overloads + generics |
| -- -------------------- |
| |
| |
| [case testGenericArgumentInOverload] |
| from typing import overload, List |
| class A: pass |
| class B: pass |
| a, b = None, None # type: (A, 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" |
| 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 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, b = None, None # type: (A, B) |
| |
| 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") |
| a = f(b) # E: Incompatible types in assignment (expression has type "B", variable has type "A") |
| |
| a = f([a]) |
| b = f([b]) |
| 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) |
| 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) |
| a = 1 |
| a = '' # E: Incompatible types in assignment (expression has type "str", variable has type "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" |
| [out] |
| |
| |
| -- 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: ... |
| def f3(x: B) -> B: ... |
| def f4(x: int) -> A: ... |
| |
| y1 = f1 |
| y1 = f1 |
| y1 = f2 |
| y1 = f3 |
| y1 = f4 # E: Incompatible types in assignment (expression has type Callable[[int], A], variable has type Callable[[A], A]) |
| |
| y2 = f2 |
| y2 = f2 |
| y2 = f1 # E: Incompatible types in assignment (expression has type Callable[[A], A], variable has type Callable[[A], B]) |
| y2 = f3 # E: Incompatible types in assignment (expression has type Callable[[B], B], variable has type Callable[[A], B]) |
| y2 = f4 # E: Incompatible types in assignment (expression has type Callable[[int], A], variable has type Callable[[A], B]) |
| |
| y3 = f3 |
| y3 = f3 |
| y3 = f1 |
| y3 = f2 |
| y3 = f4 # E: Incompatible types in assignment (expression has type Callable[[int], A], variable has type Callable[[B], B]) |
| |
| y4 = f4 |
| y4 = f4 |
| y4 = f1 # E: Incompatible types in assignment (expression has type Callable[[A], A], variable has type Callable[[int], A]) |
| y4 = f2 |
| 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: ... |
| def f3(x: T) -> A: ... |
| def f4(x: A) -> T: ... |
| def f5(x: T) -> T: ... |
| |
| y1 = f1 |
| 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 |
| y2 = f1 # E: Incompatible types in assignment (expression has type Callable[[A], A], variable has type Callable[[A], B]) |
| |
| y3 = f3 |
| 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 |
| 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 |
| 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-skip] |
| 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 testTypeVariableTypeLessThan] |
| from typing import TypeVar |
| T = TypeVar('T') |
| def f(a: T, b: T) -> T: |
| if a < b: |
| return a |
| else: |
| return b |
| [builtins fixtures/ops.pyi] |
| [out] |
| main:4: error: Unsupported left operand type for < ("T") |
| |
| |
| -- 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 C[T], 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: ... |
| 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))) # E: Revealed type is 'builtins.int*' |
| |
| [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] |