Skip to main content

Lib/typing.py (part 6)

Source:

cpython 3.14 @ ab2d84fe1023/Lib/typing.py

This annotation covers runtime type introspection. See lib_typing5_detail for TypeVar, Generic, Protocol, Annotated, and get_args.

Map

LinesSymbolRole
1-80get_type_hintsResolve string annotations to actual types
81-160@overloadRegister multiple signatures; last non-overload wins
161-240@runtime_checkableEnable isinstance for Protocol subclasses
241-340ParamSpecCapture callable parameter specifications
341-500TypeVarTupleVariadic generics (PEP 646)

Reading

get_type_hints

# CPython: Lib/typing.py:2340 get_type_hints
def get_type_hints(obj, globalns=None, localns=None, include_extras=False):
hints = {}
if isinstance(obj, type):
for base in reversed(obj.__mro__):
if getattr(base, '__no_type_check__', None):
continue
base_globals = getattr(sys.modules.get(base.__module__, None),
'__dict__', {})
ann = base.__dict__.get('__annotations__', {})
for name, value in ann.items():
if value is None:
value = type(None)
if isinstance(value, str):
value = ForwardRef(value)
hints[name] = _eval_type(value, base_globals, localns)
...
return hints

get_type_hints resolves string annotations (PEP 563 from __future__ import annotations) by evaluating them in the module's global namespace. The MRO walk means inherited annotations are included. include_extras=True preserves Annotated[...] metadata.

@overload

# CPython: Lib/typing.py:2540 overload
def overload(func):
return _overload_dummy

def _overload_dummy(*args, **kwds):
raise NotImplementedError(
"You should not call an overloaded function. "
"A non-overloaded implementation should be provided.")

@overload replaces the function with _overload_dummy. The final non-@overload definition is the actual implementation. At runtime, the overloads are documentation only; @overload has no dispatch effect. Type checkers use the overloads to determine the return type.

@runtime_checkable

# CPython: Lib/typing.py:1780 runtime_checkable
def runtime_checkable(cls):
if not (isinstance(cls, _ProtocolMeta) and cls._is_protocol):
raise TypeError('@runtime_checkable can be only applied to protocol classes')
cls._is_runtime_protocol = True
return cls

Marking a Protocol as @runtime_checkable enables isinstance(obj, MyProtocol). This checks only the presence of the protocol's methods (not their signatures). Without @runtime_checkable, isinstance raises TypeError.

ParamSpec

# CPython: Lib/typing.py:1020 ParamSpec
class ParamSpec(_SpecialForm):
def __init__(self, name, *, bound=None, covariant=False, contravariant=False):
super().__init__(name)
# P.args and P.kwargs are special forms for annotating *args/**kwargs
self.__args = ParamSpecArgs(self)
self.__kwargs = ParamSpecKwargs(self)

ParamSpec captures the full parameter spec of a callable. Callable[P, R] means "takes whatever P takes, returns R". P.args annotates *args and P.kwargs annotates **kwargs in the implementing function. Used for decorators that preserve callable signatures.

gopy notes

get_type_hints is module/typing.GetTypeHints in module/typing/module.go. String annotations are evaluated via objects.Eval in the module globals. @overload registers in a global map keyed by qualified name. ParamSpec is objects.ParamSpec with .args and .kwargs attributes.