Skip to main content

Lib/typing.py

cpython 3.14 @ ab2d84fe1023/Lib/typing.py

Lib/typing.py is the pure-Python portion of the typing module. It defines the metaclasses and descriptor machinery for Generic, Protocol, and their subscript forms. Many core types (TypeVar, ParamSpec, TypeVarTuple, Union) are backed by C implementations in Objects/typevarobject.c and Objects/unionobject.c; typing.py re-exports those and adds the pure-Python generics machinery on top.

Map

LinesSymbolRole
1-120imports, __all__C-backed type imports, public names
121-400_SpecialForm, _LiteralSpecialFormDescriptor for Any, Union, Optional, ClassVar, Final
401-700TypeVar, ParamSpec, TypeVarTupleRe-exported C types with Python-level helpers
701-1100_GenericAlias, _SpecialGenericAliasSubscriptable alias types returned by Generic[T]
1101-1600GenericBase class for generic types with __class_getitem__ and __init_subclass__
1601-2100ProtocolStructural subtyping base with _is_protocol, _check_methods
2101-2600get_type_hints, get_origin, get_argsIntrospection helpers
2601-3800remaining special formsAnnotated, TypeGuard, Never, Self, Unpack, TypedDict, NamedTuple

Reading

_SpecialForm: descriptor for special syntax

Any, Union, Optional, and similar keywords that look like types but have no runtime type object are implemented as instances of _SpecialForm. The descriptor protocol's __getitem__ allows Optional[int] to work.

# CPython: Lib/typing.py:140 _SpecialForm.__getitem__
class _SpecialForm(_Final, _root=True):
def __getitem__(self, parameters):
if not isinstance(parameters, tuple):
parameters = (parameters,)
return self._getitem(self, parameters)

Each _SpecialForm instance carries a _getitem callable set at construction that implements the specific semantics (e.g., Union._getitem flattens nested unions).

_GenericAlias: subscripted generics

When Generic[T] is subscripted with List[int], the result is a _GenericAlias holding the origin type and the argument tuple. _GenericAlias supports __origin__, __args__, and equality comparison so that List[int] == List[int] works correctly.

# CPython: Lib/typing.py:760 _GenericAlias.__init__
class _GenericAlias(_BaseGenericAlias, _root=True):
def __init__(self, origin, args, *, name=None, inst=True):
super().__init__(origin, args, name=name, inst=inst)
if not isinstance(args, tuple):
args = (args,)
self.__args__ = tuple(... if a is _TypingEllipsis else
() if a is _TypingEmpty else
a for a in args)

Protocol and structural subtyping

Protocol implements structural subtyping by recording annotated members in __protocol_attrs__ at class creation time. isinstance checks delegate to _check_methods, which verifies that all protocol members exist on the tested object.

# CPython: Lib/typing.py:1720 _is_callable_members_only
def _check_methods(C, *mro):
mro = set(mro)
for B in C.__mro__:
if B in mro:
continue
for method in B.__dict__:
if method in mro:
mro.discard(method)
return not mro

gopy notes

Not yet ported. The typing module is needed for gopy's type annotation support, but most of its runtime behaviour is introspection-only. The C-backed types (TypeVar, ParamSpec, GenericAlias) are partially implemented in objects/. The pure-Python Protocol machinery and get_type_hints require full __annotations__ support.

CPython 3.14 changes

3.14 added typing.ReadOnly, typing.TypeIs, and typing.NoDefault. TypeVar gained __default__ (PEP 696). Annotated subscript now supports TypeVar in the annotation metadata position. get_type_hints gained a format parameter supporting the new annotationlib evaluation modes.