When a user-defined type is called to create a new object, type_call
is called. Its first parameter is PyObject *type
. Then, type->tp_new
is called to create the object.
I'm reading Eli Bendersky's article (And following along CPyton's source code) where it is explained that in such case, calling tp_new
invokes object_new
. Here's how it works (Joe
is a user-defined type; Italic is added):
Since the type parameter passed to
type_call
in our case isJoe
, andJoe
does not define a custom__new__
method, thentype->tp_new
defers to thetp_new
slot of the base type.The base type of
Joe
[...] isobject
. Theobject.tp_new
slot is implemented in CPython by theobject_new
function inObjects/typeobject.c
.
So, if I understand this correctly, it follows that if type->tp_new
references object_new
, then the runtime type of type
must be PyBaseObject_Type*
(Because only PyBaseObject_Type.tp_new
references object_new
).
My question: What are the steps - preceding the invocation of type_call
- that makes type
point to a PyBaseObject_Type
variable?
You've misunderstood how things work. During setup of a user-defined class, if the class doesn't define its own __new__
, its tp_new
is copied from the "dominant base". You can see the code for this in inherit_special
:
if (base != &PyBaseObject_Type ||
(type->tp_flags & Py_TPFLAGS_HEAPTYPE)) {
if (type->tp_new == NULL)
type->tp_new = base->tp_new;
}
There is no need for the class itself to be PyBaseObject_Type
, or "a PyBaseObject_Type
variable".