← Back to index

generics_syntax_scoping.py

True Positive
False Positive
False Negative
Optional (detected)
Warning or Info
TP: 4
FP: 3
FN: 3
Optional: 0 / 0
1"""
2Tests the scoping rules for type parameter syntax introduced in PEP 695.
3"""
4
5# Specification: https://peps.python.org/pep-0695/#type-parameter-scopes
6
7from typing import Callable, Mapping, Sequence, TypeVar, assert_type
8
9# > A compiler error or runtime exception is generated if the definition
10# > of an earlier type parameter references a later type parameter even
11# > if the name is defined in an outer scope.
14class ClassA[S, T: Sequence[S]]: # E
[invalid-type-variable-bound] TypeVar upper bound cannot be generic
15 ...
18class ClassB[S: Sequence[T], T]: # E
[invalid-type-variable-bound] TypeVar upper bound cannot be generic
19 ...
22class Foo[T]:
23 ...
26class BaseClassC[T]:
27 def __init_subclass__(cls, param: type[Foo[T]]) -> None:
28 ...
31class ClassC[T](BaseClassC[T], param=Foo[T]): # OK
32 ...
35print(T) # E: Runtime error: 'T' is not defined
[unresolved-reference] Name `T` used when not defined
38def decorator1[
39 T, **P, R
40](x: type[Foo[T]]) -> Callable[[Callable[P, R]], Callable[P, R]]:
41 raise NotImplementedError
44@decorator1(Foo[T]) # E: Runtime error: 'T' is not defined
[unresolved-reference] Name `T` used when not defined
45class ClassD[T]:
46 ...
49type Alias1[K, V] = Mapping[K, V] | Sequence[K]
52S: int = int(0)
55def outer1[S](x: str):
56 S: str = x
57 T: int = 1
59 def outer2[T]():
60 def inner1():
61 nonlocal S # OK
62 assert_type(S, str)
63 # nonlocal T # Syntax error
65 def inner2():
66 global S # OK
67 assert_type(S, int)
70class Outer1:
71 class Private:
72 pass
74 class Inner[T](Private, Sequence[T]): # OK
75 pass
77 def method1[T](self, a: Inner[T]) -> Inner[T]: # OK
78 return a
81def decorator2[**P, R](x: int) -> Callable[[Callable[P, R]], Callable[P, R]]:
82 raise NotImplementedError
85T = int(0)
88@decorator2(T) # OK
89class ClassE[T](Sequence[T]):
90 T = int(1)
92 def method1[T](self): # E
Expected a ty diagnostic for this line
93 ...
95 def method2[T](self, x=T): # E
Expected a ty diagnostic for this line
96 ...
98 def method3[T](self, x: T): # E
Expected a ty diagnostic for this line
99 ...
102T = int(0)
105class Outer2[T]:
106 T = int(1)
108 assert_type(T, int)
110 class Inner1:
111 T = str("")
113 assert_type(T, str)
Unexpected error [type-assertion-failure] Type `str` does not match asserted type `Literal[""]`
115 def inner_method(self):
116 assert_type(T, TypeVar)
118 def outer_method(self):
119 T = 3j
121 assert_type(T, complex)
Unexpected error [type-assertion-failure] Type `int | float | complex` does not match asserted type `complex`
123 def inner_func():
124 assert_type(T, complex)
Unexpected error [type-assertion-failure] Type `int | float | complex` does not match asserted type `complex`