from typing import TypeVar
T = TypeVar("T", bound="ShapeOld")
# *** before: ***
# a method returning "myself" was typed with a TypeVar bound to the class,
# declared apart and repeated in every such signature
class ShapeOld:
def __init__(self, width: int = 1) -> None:
self.width = width
def wider(self: T, add: int) -> T:
self.width += add
return self
class BoxOld(ShapeOld):
def label(self) -> str:
return "box " + str(self.width)
print(BoxOld().wider(2).label())
# *** in version 3.11: ***
from typing import Self
class Shape:
def __init__(self, width: int = 1) -> None:
self.width = width
def wider(self, add: int) -> Self: # "the type of this very object"
self.width += add
return self
@classmethod
def unit(cls) -> Self: # works for a constructor too
return cls()
class Box(Shape):
def label(self) -> str:
return "box " + str(self.width)
# the checker knows that Box.wider gives back a Box, so .label is allowed
print(Box.unit().wider(2).label())
# the hint is written ONCE in the base class and holds for every heir