Skip to main content

Include/abstract.h

Source:

cpython 3.14 @ ab2d84fe1023/Include/abstract.h

Include/abstract.h is the public stable ABI for the abstract object protocol. It declares the functions that operate on any Python object through its type's slot functions: attribute access, calling, number/sequence/mapping operations, and iteration. Extension modules and embedding code use these functions to avoid depending on concrete type internals.

Map

LinesSymbolRole
1-60PyObject_Call, PyObject_CallNoArgsCall protocol; with/without args
61-140PyObject_GetAttr, PyObject_SetAttr, PyObject_HasAttrAttribute access
141-230PyNumber_*Arithmetic, bitwise, coercion, PyNumber_Index
231-330PySequence_*Length, getitem, setitem, contains, concat
331-420PyMapping_*Keys, values, items, GetItem, SetItem, HasKey
421-500PyIter_Next, PyIter_Send, PyObject_GetIterIterator protocol

Reading

Call protocol

PyObject_Call(callable, args, kwargs) is the lowest-level public call that accepts a pre-built args tuple and optional kwargs dict. PyObject_CallNoArgs and PyObject_CallOneArg are optimized variants. All of these route through the type's tp_call slot or the vectorcall protocol.

// Include/abstract.h:1 PyObject_Call
PyAPI_FUNC(PyObject *) PyObject_Call(
PyObject *callable, PyObject *args, PyObject *kwargs);

PyAPI_FUNC(PyObject *) PyObject_CallNoArgs(PyObject *callable);

PyAPI_FUNC(PyObject *) PyObject_CallOneArg(
PyObject *callable, PyObject *arg);

Attribute access

PyObject_GetAttr(o, name) calls o->ob_type->tp_getattro(o, name). For most objects this routes to PyObject_GenericGetAttr which searches the MRO for data descriptors, the instance dict, and non-data descriptors in that order.

// Include/abstract.h:61 PyObject_GetAttr
PyAPI_FUNC(PyObject *) PyObject_GetAttr(PyObject *o, PyObject *attr_name);
PyAPI_FUNC(int) PyObject_SetAttr(PyObject *o, PyObject *attr_name, PyObject *v);
PyAPI_FUNC(int) PyObject_HasAttr(PyObject *o, PyObject *attr_name);

Number and sequence protocols

PyNumber_Add(o1, o2) calls o1->ob_type->tp_as_number->nb_add. If the slot returns NotImplemented, the reflected operation o2->tp_as_number->nb_radd is tried. This implements Python's operator dispatch including __add__ and __radd__.

// Include/abstract.h:141 PyNumber_Add
PyAPI_FUNC(PyObject *) PyNumber_Add(PyObject *o1, PyObject *o2);
PyAPI_FUNC(PyObject *) PyNumber_Index(PyObject *o); /* __index__ protocol */
PyAPI_FUNC(PyObject *) PySequence_GetItem(PyObject *o, Py_ssize_t i);
PyAPI_FUNC(int) PySequence_Contains(PyObject *seq, PyObject *ob);

gopy notes

The gopy equivalent is objects/protocol.go, which implements GetAttr, SetAttr, Call, and arithmetic operations on the Object interface. The number/sequence/mapping dispatch follows the same slot-lookup logic as CPython, dispatching through the type's method table.