Skip to main content

Data model

Every Python value is an object. Every object has identity, type, and value. Identity is the address-like handle that id() returns; type is a type instance that determines what operations the object supports; value may or may not be mutable.

Source-of-record: Objects/object.c, Objects/typeobject.c, the CPython data model chapter.

Object identity, type, and value

PropertyMutabilityAccessorNotes
IdentityFixed for lifeid(x)Two objects with the same lifetime can share an id.
TypeFixed for lifetype(x)Exception: __class__ reassignment for HEAPTYPEs of the same layout.
ValuePer typex itselfImmutable for int, float, complex, bool, str, bytes, tuple, frozenset, range, slice, function, class.

Object lifecycle

  1. Allocation. tp_alloc returns memory of tp_basicsize plus tp_itemsize * nitems.
  2. Initialisation. tp_new populates the object; tp_init optionally runs after.
  3. Reference counting. Every reference increments ob_refcnt; every drop decrements. When the count hits zero, tp_dealloc runs.
  4. Cyclic collection. Objects whose type sets Py_TPFLAGS_HAVE_GC participate in cycle collection (see Memory model).
  5. Deallocation. tp_dealloc frees member references and then the object itself via tp_free.

The standard type hierarchy

None

A single immutable singleton. Type is <class 'NoneType'>. Truth value is false.

NotImplemented

Singleton returned by binary methods to indicate "ask the other operand". Truth value: deprecated since 3.9; raises if you try.

Ellipsis

Singleton .... Used in slicing and stub definitions.

numbers.Number

int

Arbitrary precision integers. Internally a sign-magnitude representation as an array of digits.

FieldSource
StorageInclude/cpython/longintrepr.h
OperationsObjects/longobject.c
Small ints[-5, 256] are cached singletons.

bool

Subclass of int. Singletons True == 1 and False == 0.

float

IEEE 754 double precision. NaN comparisons follow IEEE rules (NaN != NaN).

complex

Pair of double for real and imaginary parts.

Sequences

Immutable sequences

TypeElement typeNotes
strcode pointsPEP 393 kind storage (1/2/4 bytes).
tupleanyFixed length.
bytesunsigned bytesImmutable.
rangeintegersLazy.

Mutable sequences

TypeElement typeNotes
listanyResizable array of references.
bytearrayunsigned bytesMutable bytes.
memoryviewvariesView over a buffer-supporting object.
array.arraynumericStdlib array module.

Set types

TypeMutabilityElement constraint
setmutableHashable.
frozensetimmutableHashable. Hashable itself.

Mappings

TypeMutabilityNotes
dictmutableInsertion-ordered. Combined or split layout.
mappingproxyread-onlyView over a dict.
types.MappingProxyTyperead-onlyPublic alias of the above.

Callable types

FormExamples
User-defined functiondef f(...)
User-defined coroutineasync def f(...)
Generator functiondef f(...): yield ...
Async generator functionasync def f(...): yield ...
Built-in functionlen, print. C-implemented.
Built-in method[].append. Bound built-in.
Methodobj.method. Bound user method.
Classtype(...). Calling constructs an instance.
Class instance with __call__Anything implementing call.
functools.partialPartial application.

Modules

module objects carry an __name__, __dict__ (their namespace), __doc__, __file__, __loader__, __spec__, and __package__. Setting an attribute on a module assigns into its __dict__.

Custom classes

Class objects carry:

AttributeMeaning
__name__Short name.
__qualname__Qualified name path.
__module__Defining module.
__doc__Docstring.
__bases__Direct bases.
__mro__Method resolution order.
__dict__Class namespace.
__class__Metaclass (default type).
__subclasses__()Direct subclasses.
__type_params__PEP 695 type parameters.
__annotations__Annotation dict (lazy in 3.14).

Class instances

AttributeMeaning
__class__The class (reassignable for same-layout types).
__dict__Instance attribute dict (absent for __slots__).
__weakref__Optional weakref support.

Code objects

Compiled bytecode plus all the metadata the VM needs to run it. See Bytecode -> Opcodes and the Code struct in compile/code.go.

FieldMeaning
co_codeBytecode bytes.
co_constsTuple of literal constants.
co_namesGlobal names referenced.
co_varnamesLocal variable names.
co_freevarsFree variable names (closure inputs).
co_cellvarsCell variable names (created for nested).
co_argcountNumber of positional args.
co_posonlyargcountNumber of positional-only args.
co_kwonlyargcountNumber of keyword-only args.
co_stacksizeMaximum stack depth.
co_flagsBitfield: generator, coroutine, varargs, etc.
co_firstlinenoSource line of def.
co_linetablePEP 657 location table.
co_exceptiontableException handler ranges.
co_qualnameQualified name.

Frame objects

FieldMeaning
f_backPrevious frame in the stack.
f_codeCode object being executed.
f_localsLocal namespace (lazy).
f_globalsModule globals.
f_builtinsBuiltins namespace.
f_lastiIndex of the last completed instruction.
f_linenoCurrent line.
f_tracePer-frame trace function.

Traceback objects

A linked list of frame snapshots. tb_next chains toward the innermost frame; tb_frame, tb_lineno, tb_lasti describe the record.

Generator, coroutine, async generator

State machine objects produced by calling a generator function, coroutine function, or async generator function. Backed by a suspended frame. See Compound statements -> def.

Internal types

TypePurpose
cellClosure cell holding a free variable.
slot wrapperSlot exposed as a method (object.__str__).
method-wrapperBound slot.
wrapper_descriptorUnbound slot.
member_descriptorC-level tp_members entry.
getset_descriptorC-level tp_getset entry.
functionUser function.
methodBound user method.
builtin_function_or_methodC-level callable.
staticmethod / classmethodDescriptor wrappers.

Attribute lookup

x.name goes through type(x).__getattribute__(x, 'name'). The default implementation does:

  1. Locate name in type(x).__mro__. If found and the descriptor is a data descriptor (has __set__ or __delete__), invoke __get__ and return.
  2. Otherwise look in x.__dict__. If present, return.
  3. Otherwise return the non-data descriptor or class attribute found in step 1.
  4. If still nothing, call type(x).__getattr__(x, 'name') if defined.
  5. Otherwise raise AttributeError.

__setattr__ and __delattr__ go through analogous slot machinery.

Descriptor protocol

A descriptor is any object whose type defines at least one of:

SlotMethodRole
tp_descr_get__get__Read access.
tp_descr_set__set__Assignment.
tp_descr_set__delete__Deletion (shares the slot).

Adding __set__ or __delete__ makes the descriptor a data descriptor, which has priority over instance dict (see attribute lookup above).

The canonical examples are property, staticmethod, classmethod, and member_descriptor.

Method resolution order

The MRO is computed by the C3 linearisation algorithm.

C.__mro__ == c3(C, [c.__mro__ for c in C.__bases__], C.__bases__)

Where c3 is defined as merging head-of-list candidates while preserving the relative order in every input. A linearisation is rejected (raising TypeError) if no consistent order exists.

Metaclasses

A metaclass is the class of a class. type(C) returns its metaclass. The metaclass controls class creation:

  1. The class statement collects the class body in a namespace.
  2. The metaclass is determined: explicit metaclass= argument, or the most-derived metaclass of any base, or type.
  3. metaclass.__prepare__(name, bases, **kwds) (if defined) returns the namespace mapping.
  4. The class body executes in that namespace.
  5. metaclass(name, bases, namespace, **kwds) constructs the class.

__slots__

A class with __slots__ does not get an instance __dict__. Each slot becomes a member descriptor.

PropertyRule
Instances do not have __dict__.Unless __dict__ is in slots.
Instances do not support weak refs.Unless __weakref__ is in slots.
Slots inherit, but only one base may have non-empty __slots__.
Slots cannot be redefined in a subclass.

Reference equality and hashing

OperationDefault
x == yid(x) == id(y) for object; types override.
hash(x)Hash that respects equality. Mutable containers raise.
x is yIdentity, not method-overridable.

If __eq__ is overridden and __hash__ is not, the type's __hash__ is set to None, making instances unhashable.

Subclassing built-in types

Allowed in general. Restrictions:

TypeRestriction
boolCannot be subclassed.
NoneType / NotImplementedType / EllipsisTypeCannot be subclassed.
slice (3.12+)Subclassable.
rangeCannot be subclassed.

When subclassing immutable built-in types, override __new__, not __init__; the slots that produce the object are part of construction.

Memory model

Propertygopy
Refcountingobjects.Object carries a count; cooperatively maintained by interface methods.
Cycle collectionGenerational, triggered by allocation thresholds; mirrors CPython's three-generation collector.
Object identityStable for the object's lifetime.
Finalisation__del__ runs once when refcount reaches zero, or as part of GC if it is part of an unreachable cycle.

Gopy status

AreaState
Standard type hierarchyComplete.
MRO (C3)Complete.
Descriptor protocolComplete.
__slots__Complete.
MetaclassesComplete including __prepare__.
Weak referencesComplete.
Lazy __annotations__ (PEP 649)Complete.

Reference