Skip to main content

Objects/object.c

Source:

cpython 3.14 @ ab2d84fe1023/Objects/object.c

Objects/object.c implements the baseline object behavior that all Python types inherit: repr, str, hash, rich comparison, identity, truthiness, printing, and reference counting. It also defines the type display machinery and the special sentinel values Py_None, Py_NotImplemented, and Py_Ellipsis.

Map

LinesSymbolRole
1-100_Py_NoneStruct, _Py_NotImplementedStruct, _Py_EllipsisObjectSingleton objects
101-300PyObject_Repr, PyObject_ASCII, PyObject_StrString representation
301-500PyObject_Hash, _Py_HashBytes, _Py_HashDoubleHashing
501-700PyObject_RichCompare, PyObject_RichCompareBoolComparison dispatch
701-900PyObject_IsTrue, PyObject_NotTruthiness
901-1100Py_INCREF, Py_DECREF, _Py_DeallocReference counting
1101-1400PyObject_Dir, _PyObject_GetAttrWithoutErrorDirectory and attribute helpers
1401-1800object_richcompare, object_hash, object_repr, object_strDefault object implementations
1801-2100type_repr, PyType_Name, _PyType_IsSubtypeType helpers

Reading

PyObject_Repr

// CPython: Objects/object.c:511 PyObject_Repr
PyObject *
PyObject_Repr(PyObject *v)
{
PyObject *res;
if (PyErr_CheckSignals()) return NULL;
...
if (Py_TYPE(v)->tp_repr == NULL)
return PyUnicode_FromFormat("<%s object at %p>",
Py_TYPE(v)->tp_name, v);
res = (*Py_TYPE(v)->tp_repr)(v);
if (!PyUnicode_Check(res)) {
PyErr_Format(PyExc_TypeError,
"__repr__ returned non-string (type %.200s)",
Py_TYPE(res)->tp_name);
Py_DECREF(res);
return NULL;
}
return res;
}

Calls tp_repr; falls back to the <type at address> format if tp_repr is NULL; validates that the result is a str.

PyObject_RichCompare

// CPython: Objects/object.c:812 PyObject_RichCompare
PyObject *
PyObject_RichCompare(PyObject *v, PyObject *w, int op)
{
PyObject *res;
assert(Py_LT <= op && op <= Py_GE);
if (!Py_IS_TYPE(v, Py_TYPE(w)) &&
PyType_IsSubtype(Py_TYPE(w), Py_TYPE(v)) &&
(Py_TYPE(w)->tp_richcompare != NULL)) {
res = (*Py_TYPE(w)->tp_richcompare)(w, v, _Py_SwappedOp[op]);
if (res != Py_NotImplemented) return res;
Py_DECREF(res);
}
if (Py_TYPE(v)->tp_richcompare != NULL) {
res = (*Py_TYPE(v)->tp_richcompare)(v, w, op);
if (res != Py_NotImplemented) return res;
Py_DECREF(res);
}
...
}

Tries the subtype's reflected comparison first (if applicable), then the left operand's, then falls back to identity comparison for ==/!=.

PyObject_Hash

Default hash is the object's memory address (id(obj) // 16). Types can override via tp_hash. The hash is cached in ob_shash for strings and frozen sets to avoid recomputation.

_Py_Dealloc

// CPython: Objects/object.c:2432 _Py_Dealloc
void
_Py_Dealloc(PyObject *op)
{
destructor dealloc = Py_TYPE(op)->tp_dealloc;
...
(*dealloc)(op);
}

Called by Py_DECREF when the refcount reaches zero. Dispatches to the type's tp_dealloc.

gopy notes

The gopy equivalent is objects/object.go. PyObject_Repr maps to objects.Repr; PyObject_RichCompare maps to objects.RichCompare; reference counting is replaced by Go's garbage collector. Py_None, Py_NotImplemented, and Py_Ellipsis are singleton objects.NoneType, objects.NotImplementedType, and objects.EllipsisType instances.