Skip to main content

Include/object.h (part 2)

Source:

cpython 3.14 @ ab2d84fe1023/Include/object.h

This annotation supplements include_object_h_detail with coverage of the slot-name macros, type flags, and the type-checking accessor macros. These are the building blocks every C extension author uses.

Map

LinesSymbolRole
1-100Py_TYPE, Py_REFCNT, Py_SET_TYPEObject field accessors
101-300PyObject_TypeCheck, PyType_Check, PyList_Check, etc.Type-check macros
301-500Py_TPFLAGS_*Type flags bitfield
501-700PyTypeObject slot namestp_name, tp_new, tp_init, tp_call, tp_repr, etc.
701-900PyNumberMethods, PySequenceMethods, PyMappingMethods, PyBufferProcsSub-struct slot tables

Reading

Py_TYPE and Py_REFCNT

// CPython: Include/object.h:176 Py_TYPE
static inline PyTypeObject *
Py_TYPE(PyObject *ob) {
return ob->ob_type;
}

static inline Py_ssize_t
Py_REFCNT(PyObject *ob) {
return ob->ob_refcnt;
}

In Python 3.10+ these became inline functions rather than macros for better type safety and debugger support.

Py_TPFLAGS_*

Type flags are bit positions in PyTypeObject.tp_flags. Key flags:

FlagMeaning
Py_TPFLAGS_HEAPTYPEAllocated on heap (Python-defined class) vs static
Py_TPFLAGS_BASETYPECan be subclassed
Py_TPFLAGS_HAVE_GCParticipates in GC cycle detection
Py_TPFLAGS_IMMUTABLETYPEType cannot be modified after creation (3.10+)
Py_TPFLAGS_MANAGED_DICTUses the new managed dict protocol (3.12+)
Py_TPFLAGS_MANAGED_WEAKREFSupports weak references (3.12+)
Py_TPFLAGS_SEQUENCEImplements the sequence protocol
Py_TPFLAGS_MAPPINGImplements the mapping protocol

PyNumberMethods

The sub-struct for numeric protocol slots:

// CPython: Include/object.h:225 PyNumberMethods
typedef struct {
binaryfunc nb_add;
binaryfunc nb_subtract;
binaryfunc nb_multiply;
binaryfunc nb_remainder;
binaryfunc nb_divmod;
ternaryfunc nb_power;
unaryfunc nb_negative;
unaryfunc nb_positive;
unaryfunc nb_absolute;
inquiry nb_bool;
...
binaryfunc nb_floor_divide;
binaryfunc nb_true_divide;
binaryfunc nb_inplace_floor_divide;
binaryfunc nb_inplace_true_divide;
unaryfunc nb_index;
binaryfunc nb_matrix_multiply;
binaryfunc nb_inplace_matrix_multiply;
} PyNumberMethods;

All slots are optional (can be NULL). The abstract object protocol checks for NULL before calling.

PyObject_TypeCheck

// CPython: Include/object.h:315 PyObject_TypeCheck
static inline int
PyObject_TypeCheck(PyObject *ob, PyTypeObject *type) {
return Py_IS_TYPE(ob, type) || PyType_IsSubtype(Py_TYPE(ob), type);
}

The common pattern for C extension type checking.

gopy notes

Py_TPFLAGS_* maps to boolean fields in gopy's Type struct. PyNumberMethods maps to Go function fields in the Type struct (e.g., Add func(*Object, *Object) (*Object, error)). PyObject_TypeCheck maps to Go's type assertion _, ok := obj.(*SomeType); ok || obj.Type().IsSubtype(targetType).