← Back to index

generics_self_basic.py

True Positive
False Positive
False Negative
Optional (detected)
Warning or Info
TP: 3
FP: 0
FN: 0
Optional: 0 / 0
1"""
2Tests for basic usage of the typing.Self type.
3"""
4
5# Specification: https://typing.readthedocs.io/en/latest/spec/generics.html#self.
6
7from typing import Callable, Generic, Self, TypeVar, assert_type
8
9T = TypeVar("T")
12class Shape:
13 def set_scale(self, scale: float) -> Self:
14 assert_type(self, Self)
15 self.scale = scale
16 return self
18 def method2(self) -> Self:
19 # This should result in a type error.
20 return Shape() # E
[invalid-return-type] Return type does not match returned value: expected `Self@method2`, found `Shape`
22 def method3(self) -> "Shape":
23 return self
25 @classmethod
26 def from_config(cls, config: dict[str, float]) -> Self:
27 assert_type(cls, type[Self])
28 return cls()
30 @classmethod
31 def cls_method2(cls) -> Self:
32 # This should result in a type error.
33 return Shape() # E
[invalid-return-type] Return type does not match returned value: expected `Self@cls_method2`, found `Shape`
35 @classmethod
36 def cls_method3(cls) -> "Shape":
37 return cls()
39 def difference(self, other: Self) -> float:
40 assert_type(other, Self)
41 return 0.0
43 def apply(self, f: Callable[[Self], None]) -> None:
44 return f(self)
47class Circle(Shape):
48 pass
51assert_type(Shape().set_scale(1.0), Shape)
52assert_type(Circle().set_scale(1.0), Circle)
54assert_type(Shape.from_config({}), Shape)
55assert_type(Circle.from_config({}), Circle)
58class Container(Generic[T]):
59 value: T
61 def __init__(self, value: T) -> None:
62 self.value = value
64 def set_value(self, value: T) -> Self:
65 raise NotImplementedError
67 # This should generate an error because Self isn't subscriptable.
68 def foo(self, other: Self[int]) -> None: # E
[invalid-type-form] Special form `typing.Self` expected no type parameter
69 pass
72def object_with_concrete_type(
73 int_container: Container[int], str_container: Container[str]
74) -> None:
75 assert_type(int_container.set_value(42), Container[int])
76 assert_type(str_container.set_value("hello"), Container[str])
79def object_with_generic_type(
80 container: Container[T],
81 value: T,
82) -> Container[T]:
83 val = container.set_value(value)
84 assert_type(val, Container[T])
85 return val