Skip to content
Next Next commit
Add a note about the static builtin types to struct types_state.
  • Loading branch information
ericsnowcurrently committed Apr 11, 2024
commit c0b035e86ac4d9ac23c4fc4b23d450b5ee28e8df
34 changes: 34 additions & 0 deletions Include/internal/pycore_typeobject.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,40 @@ struct types_state {
unsigned int next_version_tag;

struct type_cache type_cache;

/* Every static builtin type is initialized for each interpreter
during its own initialization, including for the main interpreter
during global runtime initialization. This is done by calling
_PyStaticType_InitBuiltin().

The first time a static builtin type is initialized, all the
normal PyType_Ready() stuff happens. The only difference from
normal is that there are three PyTypeObject fields holding
objects which are stored here (on PyInterpreterState) rather
than in the corresponding PyTypeObject fields. Those are:
tp_dict (cls.__dict__), tp_subclasses (cls.__subclasses__),
and tp_weaklist.

When a subinterpreter is initialized, each static builtin type
is still initialized, but only the interpreter-specific portion,
namely those three objects.

Those objects are stored in the PyInterpreterState.types.builtins
array, at the index corresponding to each specific static builtin
type. That index (a size_t value) is stored in the tp_subclasses
field (defined as PyObject*). We re-purposed the now-unused
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, it's void *.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

tp_subclasses to avoid adding another field to PyTypeObject.

The index for each static builtin type isn't statically assigned.
Instead it is calculated the first time a type is initialized
(by the main interpreter). The index matches the order in which
the type was initialized relative to the others. The actual
value comes from the current value of num_builtins_initialized,
as each type is initialized for the main interpreter.

num_builtins_initialized is incremented once for each static
builtin type. Once initialization is over for a subinterpreter,
the value will be the same as for all other interpreters. */
size_t num_builtins_initialized;
static_builtin_state builtins[_Py_MAX_STATIC_BUILTIN_TYPES];
PyMutex mutex;
Expand Down