← Back to index

generics_type_erasure.py

True Positive
False Positive
False Negative
Optional (detected)
Warning or Info
TP: 2
FP: 0
FN: 5
Optional: 0 / 0
1# Specification: https://typing.readthedocs.io/en/latest/spec/generics.html#instantiating-generic-classes-and-type-erasure
2
3from typing import Any, TypeVar, Generic, assert_type
4
5T = TypeVar("T")
6
7# > If the constructor (__init__ or __new__) uses T in its signature, and a
8# > corresponding argument value is passed, the type of the corresponding
9# > argument(s) is substituted. Otherwise, Any is assumed.
11class Node(Generic[T]):
12 label: T
13 def __init__(self, label: T | None = None) -> None:
14 if label is not None:
15 self.label = label
17assert_type(Node(''), Node[str])
18assert_type(Node(0), Node[int])
19assert_type(Node(), Node[Any])
21assert_type(Node(0).label, int)
22assert_type(Node().label, Any)
24# > In case the inferred type uses [Any] but the intended type is more specific,
25# > you can use an annotation to force the type of the variable, e.g.:
27n1: Node[int] = Node()
28assert_type(n1, Node[int])
29n2: Node[str] = Node()
30assert_type(n2, Node[str])
32n3 = Node[int]()
33assert_type(n3, Node[int])
34n4 = Node[str]()
35assert_type(n4, Node[str])
37n5 = Node[int](0) # OK
38n6 = Node[int]("") # E
[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `int | None`, found `Literal[""]`
39n7 = Node[str]("") # OK
40n8 = Node[str](0) # E
[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `str | None`, found `Literal[0]`
42Node[int].label = 1 # E
Expected a ty diagnostic for this line
43Node[int].label # E
Expected a ty diagnostic for this line
44Node.label = 1 # E
Expected a ty diagnostic for this line
45Node.label # E
Expected a ty diagnostic for this line
46type(n1).label # E
Expected a ty diagnostic for this line
47assert_type(n1.label, int)
48assert_type(Node[int]().label, int)
49n1.label = 1 # OK
51# > [...] generic versions of concrete collections can be instantiated:
53from typing import DefaultDict
55data = DefaultDict[int, bytes]()
56assert_type(data[0], bytes)