← Back to index

generics_self_protocols.py

True Positive
False Positive
False Negative
Optional (detected)
Warning or Info
TP: 2
FP: 0
FN: 0
Optional: 0 / 0
1"""
2Tests for usage of the typing.Self type with protocols.
3"""
4
5# Specification: https://typing.readthedocs.io/en/latest/spec/generics.html#use-in-protocols
6
7from typing import Protocol, Self, assert_type
8
9
10class ShapeProtocol(Protocol):
11 def set_scale(self, scale: float) -> Self:
12 ...
15class ReturnSelf:
16 scale: float = 1.0
18 def set_scale(self, scale: float) -> Self:
19 self.scale = scale
20 return self
23class ReturnConcreteShape:
24 scale: float = 1.0
26 def set_scale(self, scale: float) -> "ReturnConcreteShape":
27 self.scale = scale
28 return self
31class BadReturnType:
32 scale: float = 1.0
34 def set_scale(self, scale: float) -> int:
35 self.scale = scale
36 return 42
39class ReturnDifferentClass:
40 scale: float = 1.0
42 def set_scale(self, scale: float) -> ReturnConcreteShape:
43 return ReturnConcreteShape()
46def accepts_shape(shape: ShapeProtocol) -> None:
47 y = shape.set_scale(0.5)
48 assert_type(y, ShapeProtocol)
51def main(
52 return_self_shape: ReturnSelf,
53 return_concrete_shape: ReturnConcreteShape,
54 bad_return_type: BadReturnType,
55 return_different_class: ReturnDifferentClass,
56) -> None:
57 accepts_shape(return_self_shape) # OK
58 accepts_shape(return_concrete_shape) # OK
60 # This should generate a type error.
61 accepts_shape(bad_return_type) # E
[invalid-argument-type] Argument to function `accepts_shape` is incorrect: Expected `ShapeProtocol`, found `BadReturnType`
63 # Not OK because it returns a non-subclass.
64 accepts_shape(return_different_class) # E
[invalid-argument-type] Argument to function `accepts_shape` is incorrect: Expected `ShapeProtocol`, found `ReturnDifferentClass`