typing.Self represents the concrete class type on which a method is called. In fluent APIs it preserves a subclass after returning self, without a manually bound TypeVar.
from typing import Self
class Consulta:
def __init__(self) -> None:
self.filtros: list[str] = []
def filtrar(self, expressao: str) -> Self:
self.filtros.append(expressao)
return self
class ConsultaAuditada(Consulta):
pass
consulta = ConsultaAuditada().filtrar("ativo = true")
Here, a type checker understands that calling filter on AuditedQuery still produces AuditedQuery. The same pattern applies to classmethods constructing cls and to __enter__() when a context manager returns its own instance.
Practical guidance
Do not annotate with Self when a method explicitly creates the base class, because a subclass call will not return the promised subtype. For Python versions before 3.11, consider the typing_extensions backport according to the project's compatibility policy.
Connect this concept to the type hints guide and classmethod and staticmethod.
The official typing.Self documentation, accessed July 22, 2026, documents the API and its constraints.