1# Specification: https://typing.readthedocs.io/en/latest/spec/generics.html#scoping-rules-for-type-variables
3from typing import TypeVar, Generic, Iterable, TypeAlias, assert_type
5# > A type variable used in a generic function could be inferred to represent
6# > different types in the same code block.
9def fun_1(x: T) -> T: # T here
11def fun_2(x: T) -> T: # and here could be different
14assert_type(fun_1(1), int)
Unexpected error
[type-assertion-failure] Type `int` does not match asserted type `Literal[1]`
15assert_type(fun_2('a'), str)
Unexpected error
[type-assertion-failure] Type `str` does not match asserted type `Literal["a"]`
17# > A type variable used in a method of a generic class that coincides
18# > with one of the variables that parameterize this class is always bound
21class MyClass(Generic[T]):
22 def meth_1(self, x: T) -> T: # T here
24 def meth_2(self, x: T) -> T: # and here are always the same
27a: MyClass[int] = MyClass()
[invalid-argument-type] Argument to bound method `meth_2` is incorrect: Expected `int`, found `Literal["a"]`
31# > A type variable used in a method that does not match any of the variables
32# > that parameterize the class makes this method a generic function in that
38 def method(self, x: T, y: S) -> S:
42assert_type(x.method(0, "abc"), str)
Unexpected error
[type-assertion-failure] Type `str` does not match asserted type `Literal["abc"]`
43assert_type(x.method(0, b"abc"), bytes)
Unexpected error
[type-assertion-failure] Type `bytes` does not match asserted type `Literal[b"abc"]`
45# > Unbound type variables should not appear in the bodies of generic functions,
46# > or in the class bodies apart from method definitions.
48def fun_3(x: T) -> list[T]:
Expected a ty diagnostic for this line
54 an_attr: list[S] = [] # E
Expected a ty diagnostic for this line
56 def do_something(self, x: S) -> S: # OK
59# A generic class definition that appears inside a generic function
60# should not use type variables that parameterize the generic function.
62def fun_4(x: T) -> list[T]:
63 a_list: list[T] = [] # OK
65 class MyGeneric(Generic[T]): # E
[invalid-generic-class] Generic class `MyGeneric` must not reference type variables bound in an enclosing scope: `T` referenced in class definition here
[invalid-generic-class] Generic class `MyGeneric` must not reference type variables bound in an enclosing scope: `T` referenced in class definition here
70# > A generic class nested in another generic class cannot use the same type
71# > variables. The scope of the type variables of the outer class
72# > doesn't cover the inner one
74class Outer(Generic[T]):
75 class Bad(Iterable[T]): # E
[invalid-generic-class] Generic class `Bad` must not reference type variables bound in an enclosing scope: `T` referenced in class definition here
Expected a ty diagnostic for this line
80 def __init__(self, x: list[T]) -> None: # E?
83 class Inner(Iterable[S]): # OK
87 alias: TypeAlias = list[T] # E
Expected a ty diagnostic for this line
89 def __init__(self, attr: Inner[T]) -> None:
93# Test unbound type variables at global scope
Expected a ty diagnostic for this line
95global_var2: list[T] = [] # E
Expected a ty diagnostic for this line
Expected a ty diagnostic for this line