Изменения в новых версиях / Python 3.11

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