Skip to main content

Lib/types.py

Source:

cpython 3.14 @ ab2d84fe1023/Lib/types.py

Map

LinesSymbolPurpose
1–30module headerImports; retrieves built-in types by introspecting known objects
31–60generator / coroutine / async-generator type aliasesGeneratorType, CoroutineType, AsyncGeneratorType
61–80FunctionType, LambdaType, CodeType, MappingProxyTypeRe-exports from C layer or from _collections_abc
81–120ModuleType with __spec__Thin wrapper that sets __spec__ on newly constructed modules
121–160SimpleNamespacePure-Python class for __dict__-backed attribute storage
161–200DynamicClassAttributeDescriptor routing attribute access to __getattr__ on the type
201–240GenericAlias re-exportImported from builtins as types.GenericAlias
241–270UnionType re-exportImported from _types C extension as types.UnionType
271–320NoneType, NotImplementedType, EllipsisType, CapsuleTypeSingleton type objects via type(None) etc.

Reading

SimpleNamespace and MappingProxyType

SimpleNamespace is defined in pure Python in this file. Its __init__ accepts only keyword arguments and stores them directly into self.__dict__. __repr__ renders the dict contents in sorted key order for stable output. __eq__ compares __dict__ pairs directly.

# CPython: Lib/types.py:182 SimpleNamespace.__init__
class SimpleNamespace:
def __init__(self, /, **kwargs):
self.__dict__.update(kwargs)

def __repr__(self):
items = (f'{k}={v!r}' for k, v in sorted(self.__dict__.items()))
return f'{type(self).__name__}({", ".join(items)})'

def __eq__(self, other):
if isinstance(self, SimpleNamespace) and isinstance(other, SimpleNamespace):
return self.__dict__ == other.__dict__
return NotImplemented

MappingProxyType is not implemented here. The file simply re-exports the C-level mappingproxy type from _collections_abc (or directly from builtins depending on the build). The re-export gives it a stable public name in types.

Generator, coroutine, and async-generator type objects

CPython obtains these type objects by constructing minimal objects and calling type() on them, rather than referencing any C symbol directly. The pattern is the same for all three.

# CPython: Lib/types.py:36 generator/coroutine type discovery
def _f(): yield
GeneratorType = type(_f())

async def _c(): pass
CoroutineType = type(_c())
_c().close() # suppress "coroutine was never awaited" warning

async def _ag(): yield
AsyncGeneratorType = type(_ag())

This approach means the file has no dependency on any private C API symbol: the correct type object is always retrieved from the interpreter that is actually running the code. The _c().close() call is necessary to silence the runtime warning that fires when a coroutine object is garbage-collected without being awaited.

ModuleType is also obtained from the C layer. The file extends it only to ensure that __spec__ is set to None when a module is constructed without a loader spec, matching the contract described in importlib.

DynamicClassAttribute descriptor

DynamicClassAttribute is used internally by enum.Enum to allow an attribute to behave differently when accessed on the class versus on an instance. On an instance it calls the getter as a normal property. On the class it raises AttributeError, which triggers the metaclass __getattr__ instead.

# CPython: Lib/types.py:232 DynamicClassAttribute.__get__
class DynamicClassAttribute:
def __get__(self, instance, ownerclass=None):
if instance is None:
if self.__doc__:
# called on the class, let __getattr__ handle it
raise AttributeError()
return self
if self.fget is None:
raise AttributeError()
return self.fget(instance)

The practical effect is that MyEnum.some_attribute can return an enum-level value (via the metaclass) while MyEnum.member.some_attribute returns the instance-level value via the getter. GenericAlias and UnionType are straightforward re-exports from lower-level modules and carry no Python-level logic in this file.

gopy notes

Status: partially ported.

Planned package path: module/types/.

SimpleNamespace maps directly to a gopy object with a Dict-backed attribute store; the implementation lives in objects/namespace.go. MappingProxyType has a stub in objects/mapping_proxy.go (untracked file visible in the current working tree). GeneratorType, CoroutineType, and AsyncGeneratorType are already present as gopy type objects and need only to be wired into the module/types/ export table. DynamicClassAttribute requires the descriptor protocol (implemented in objects/descr.go) and can be ported once that stabilises. GenericAlias and UnionType stubs exist in objects/generic_alias.go and objects/union_type.go respectively, also currently untracked.