| -- 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>]" |