summaryrefslogtreecommitdiffstats
path: root/Objects
diff options
context:
space:
mode:
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>2024-06-03 23:37:28 (GMT)
committerGitHub <noreply@github.com>2024-06-03 23:37:28 (GMT)
commite5fb3a2385809f6cbdba2061b40fecf5b234f549 (patch)
tree67c4389e236f0864c2ce5fd4ed93703ced68cbe2 /Objects
parentc348e27cc1b1e7468f9c0c7d5d6e7f6160d25613 (diff)
downloadcpython-e5fb3a2385809f6cbdba2061b40fecf5b234f549.zip
cpython-e5fb3a2385809f6cbdba2061b40fecf5b234f549.tar.gz
cpython-e5fb3a2385809f6cbdba2061b40fecf5b234f549.tar.bz2
[3.13] gh-117398: Use Per-Interpreter State for the _datetime Static Types (gh-120009)
We make use of the same mechanism that we use for the static builtin types. This required a few tweaks. This change is the final piece needed to make _datetime support multiple interpreters. I've updated the module slot accordingly. (cherry picked from commit 105f22ea46ac16866e6df18ebae2a8ba422b7f45, AKA gh-119929) Co-authored-by: Eric Snow <ericsnowcurrently@gmail.com>
Diffstat (limited to 'Objects')
-rw-r--r--Objects/exceptions.c2
-rw-r--r--Objects/object.c2
-rw-r--r--Objects/structseq.c2
-rw-r--r--Objects/typeobject.c278
-rw-r--r--Objects/unicodeobject.c6
-rw-r--r--Objects/weakrefobject.c2
6 files changed, 194 insertions, 98 deletions
diff --git a/Objects/exceptions.c b/Objects/exceptions.c
index 63c461d..f27ca2f 100644
--- a/Objects/exceptions.c
+++ b/Objects/exceptions.c
@@ -3685,7 +3685,7 @@ _PyExc_FiniTypes(PyInterpreterState *interp)
{
for (Py_ssize_t i=Py_ARRAY_LENGTH(static_exceptions) - 1; i >= 0; i--) {
PyTypeObject *exc = static_exceptions[i].exc;
- _PyStaticType_Dealloc(interp, exc);
+ _PyStaticType_FiniBuiltin(interp, exc);
}
}
diff --git a/Objects/object.c b/Objects/object.c
index ce3df37..9c74d54 100644
--- a/Objects/object.c
+++ b/Objects/object.c
@@ -2359,7 +2359,7 @@ _PyTypes_FiniTypes(PyInterpreterState *interp)
// their base classes.
for (Py_ssize_t i=Py_ARRAY_LENGTH(static_types)-1; i>=0; i--) {
PyTypeObject *type = static_types[i];
- _PyStaticType_Dealloc(interp, type);
+ _PyStaticType_FiniBuiltin(interp, type);
}
}
diff --git a/Objects/structseq.c b/Objects/structseq.c
index ec5c5ab..d8289f2 100644
--- a/Objects/structseq.c
+++ b/Objects/structseq.c
@@ -718,7 +718,7 @@ _PyStructSequence_FiniBuiltin(PyInterpreterState *interp, PyTypeObject *type)
return;
}
- _PyStaticType_Dealloc(interp, type);
+ _PyStaticType_FiniBuiltin(interp, type);
if (_Py_IsMainInterpreter(interp)) {
// Undo _PyStructSequence_InitBuiltinWithFlags().
diff --git a/Objects/typeobject.c b/Objects/typeobject.c
index 14c43a7..18b7dfc 100644
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -131,93 +131,159 @@ type_from_ref(PyObject *ref)
#ifndef NDEBUG
static inline int
-static_builtin_index_is_set(PyTypeObject *self)
+managed_static_type_index_is_set(PyTypeObject *self)
{
return self->tp_subclasses != NULL;
}
#endif
static inline size_t
-static_builtin_index_get(PyTypeObject *self)
+managed_static_type_index_get(PyTypeObject *self)
{
- assert(static_builtin_index_is_set(self));
+ assert(managed_static_type_index_is_set(self));
/* We store a 1-based index so 0 can mean "not initialized". */
return (size_t)self->tp_subclasses - 1;
}
static inline void
-static_builtin_index_set(PyTypeObject *self, size_t index)
+managed_static_type_index_set(PyTypeObject *self, size_t index)
{
- assert(index < _Py_MAX_STATIC_BUILTIN_TYPES);
+ assert(index < _Py_MAX_MANAGED_STATIC_BUILTIN_TYPES);
/* We store a 1-based index so 0 can mean "not initialized". */
self->tp_subclasses = (PyObject *)(index + 1);
}
static inline void
-static_builtin_index_clear(PyTypeObject *self)
+managed_static_type_index_clear(PyTypeObject *self)
{
self->tp_subclasses = NULL;
}
-static inline static_builtin_state *
+static inline managed_static_type_state *
static_builtin_state_get(PyInterpreterState *interp, PyTypeObject *self)
{
- return &(interp->types.builtins[static_builtin_index_get(self)]);
+ return &(interp->types.builtins.initialized[
+ managed_static_type_index_get(self)]);
+}
+
+static inline managed_static_type_state *
+static_ext_type_state_get(PyInterpreterState *interp, PyTypeObject *self)
+{
+ return &(interp->types.for_extensions.initialized[
+ managed_static_type_index_get(self)]);
+}
+
+static managed_static_type_state *
+managed_static_type_state_get(PyInterpreterState *interp, PyTypeObject *self)
+{
+ // It's probably a builtin type.
+ size_t index = managed_static_type_index_get(self);
+ managed_static_type_state *state =
+ &(interp->types.builtins.initialized[index]);
+ if (state->type == self) {
+ return state;
+ }
+ if (index > _Py_MAX_MANAGED_STATIC_EXT_TYPES) {
+ return state;
+ }
+ return &(interp->types.for_extensions.initialized[index]);
}
/* For static types we store some state in an array on each interpreter. */
-static_builtin_state *
+managed_static_type_state *
_PyStaticType_GetState(PyInterpreterState *interp, PyTypeObject *self)
{
assert(self->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN);
- return static_builtin_state_get(interp, self);
+ return managed_static_type_state_get(interp, self);
}
/* Set the type's per-interpreter state. */
static void
-static_builtin_state_init(PyInterpreterState *interp, PyTypeObject *self)
+managed_static_type_state_init(PyInterpreterState *interp, PyTypeObject *self,
+ int isbuiltin, int initial)
{
- if (_Py_IsMainInterpreter(interp)) {
- assert(!static_builtin_index_is_set(self));
- static_builtin_index_set(self, interp->types.num_builtins_initialized);
+ size_t index;
+ if (initial) {
+ assert(!managed_static_type_index_is_set(self));
+ if (isbuiltin) {
+ index = interp->types.builtins.num_initialized;
+ assert(index < _Py_MAX_MANAGED_STATIC_BUILTIN_TYPES);
+ }
+ else {
+ PyMutex_Lock(&interp->types.mutex);
+ index = interp->types.for_extensions.next_index;
+ interp->types.for_extensions.next_index++;
+ PyMutex_Unlock(&interp->types.mutex);
+ assert(index < _Py_MAX_MANAGED_STATIC_EXT_TYPES);
+ }
+ managed_static_type_index_set(self, index);
}
else {
- assert(static_builtin_index_get(self) ==
- interp->types.num_builtins_initialized);
+ index = managed_static_type_index_get(self);
+ if (isbuiltin) {
+ assert(index == interp->types.builtins.num_initialized);
+ assert(index < _Py_MAX_MANAGED_STATIC_BUILTIN_TYPES);
+ }
+ else {
+ assert(index < _Py_MAX_MANAGED_STATIC_EXT_TYPES);
+ }
}
- static_builtin_state *state = static_builtin_state_get(interp, self);
- /* It should only be called once for each builtin type. */
+ managed_static_type_state *state = isbuiltin
+ ? &(interp->types.builtins.initialized[index])
+ : &(interp->types.for_extensions.initialized[index]);
+
+ /* It should only be called once for each builtin type per interpreter. */
assert(state->type == NULL);
state->type = self;
+ state->isbuiltin = isbuiltin;
/* state->tp_subclasses is left NULL until init_subclasses() sets it. */
/* state->tp_weaklist is left NULL until insert_head() or insert_after()
(in weakrefobject.c) sets it. */
- interp->types.num_builtins_initialized++;
+ if (isbuiltin) {
+ interp->types.builtins.num_initialized++;
+ }
+ else {
+ interp->types.for_extensions.num_initialized++;
+ }
}
/* Reset the type's per-interpreter state.
- This basically undoes what static_builtin_state_init() did. */
+ This basically undoes what managed_static_type_state_init() did. */
static void
-static_builtin_state_clear(PyInterpreterState *interp, PyTypeObject *self)
+managed_static_type_state_clear(PyInterpreterState *interp, PyTypeObject *self,
+ int isbuiltin, int final)
{
- static_builtin_state *state = static_builtin_state_get(interp, self);
+ managed_static_type_state *state = isbuiltin
+ ? static_builtin_state_get(interp, self)
+ : static_ext_type_state_get(interp, self);
assert(state->type != NULL);
state->type = NULL;
assert(state->tp_weaklist == NULL); // It was already cleared out.
- if (_Py_IsMainInterpreter(interp)) {
- static_builtin_index_clear(self);
+ if (final) {
+ managed_static_type_index_clear(self);
}
- assert(interp->types.num_builtins_initialized > 0);
- interp->types.num_builtins_initialized--;
+ if (isbuiltin) {
+ assert(interp->types.builtins.num_initialized > 0);
+ interp->types.builtins.num_initialized--;
+ }
+ else {
+ PyMutex_Lock(&interp->types.mutex);
+ assert(interp->types.for_extensions.num_initialized > 0);
+ interp->types.for_extensions.num_initialized--;
+ if (interp->types.for_extensions.num_initialized == 0) {
+ interp->types.for_extensions.next_index = 0;
+ }
+ PyMutex_Unlock(&interp->types.mutex);
+ }
}
-// Also see _PyStaticType_InitBuiltin() and _PyStaticType_Dealloc().
+// Also see _PyStaticType_InitBuiltin() and _PyStaticType_FiniBuiltin().
/* end static builtin helpers */
@@ -227,7 +293,7 @@ start_readying(PyTypeObject *type)
{
if (type->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) {
PyInterpreterState *interp = _PyInterpreterState_GET();
- static_builtin_state *state = static_builtin_state_get(interp, type);
+ managed_static_type_state *state = managed_static_type_state_get(interp, type);
assert(state != NULL);
assert(!state->readying);
state->readying = 1;
@@ -242,7 +308,7 @@ stop_readying(PyTypeObject *type)
{
if (type->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) {
PyInterpreterState *interp = _PyInterpreterState_GET();
- static_builtin_state *state = static_builtin_state_get(interp, type);
+ managed_static_type_state *state = managed_static_type_state_get(interp, type);
assert(state != NULL);
assert(state->readying);
state->readying = 0;
@@ -257,7 +323,7 @@ is_readying(PyTypeObject *type)
{
if (type->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) {
PyInterpreterState *interp = _PyInterpreterState_GET();
- static_builtin_state *state = static_builtin_state_get(interp, type);
+ managed_static_type_state *state = managed_static_type_state_get(interp, type);
assert(state != NULL);
return state->readying;
}
@@ -272,7 +338,7 @@ lookup_tp_dict(PyTypeObject *self)
{
if (self->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) {
PyInterpreterState *interp = _PyInterpreterState_GET();
- static_builtin_state *state = _PyStaticType_GetState(interp, self);
+ managed_static_type_state *state = _PyStaticType_GetState(interp, self);
assert(state != NULL);
return state->tp_dict;
}
@@ -298,7 +364,7 @@ set_tp_dict(PyTypeObject *self, PyObject *dict)
{
if (self->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) {
PyInterpreterState *interp = _PyInterpreterState_GET();
- static_builtin_state *state = _PyStaticType_GetState(interp, self);
+ managed_static_type_state *state = _PyStaticType_GetState(interp, self);
assert(state != NULL);
state->tp_dict = dict;
return;
@@ -311,7 +377,7 @@ clear_tp_dict(PyTypeObject *self)
{
if (self->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) {
PyInterpreterState *interp = _PyInterpreterState_GET();
- static_builtin_state *state = _PyStaticType_GetState(interp, self);
+ managed_static_type_state *state = _PyStaticType_GetState(interp, self);
assert(state != NULL);
Py_CLEAR(state->tp_dict);
return;
@@ -340,13 +406,13 @@ _PyType_GetBases(PyTypeObject *self)
}
static inline void
-set_tp_bases(PyTypeObject *self, PyObject *bases)
+set_tp_bases(PyTypeObject *self, PyObject *bases, int initial)
{
assert(PyTuple_CheckExact(bases));
if (self->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) {
// XXX tp_bases can probably be statically allocated for each
// static builtin type.
- assert(_Py_IsMainInterpreter(_PyInterpreterState_GET()));
+ assert(initial);
assert(self->tp_bases == NULL);
if (PyTuple_GET_SIZE(bases) == 0) {
assert(self->tp_base == NULL);
@@ -363,10 +429,10 @@ set_tp_bases(PyTypeObject *self, PyObject *bases)
}
static inline void
-clear_tp_bases(PyTypeObject *self)
+clear_tp_bases(PyTypeObject *self, int final)
{
if (self->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) {
- if (_Py_IsMainInterpreter(_PyInterpreterState_GET())) {
+ if (final) {
if (self->tp_bases != NULL) {
if (PyTuple_GET_SIZE(self->tp_bases) == 0) {
Py_CLEAR(self->tp_bases);
@@ -413,13 +479,13 @@ _PyType_GetMRO(PyTypeObject *self)
}
static inline void
-set_tp_mro(PyTypeObject *self, PyObject *mro)
+set_tp_mro(PyTypeObject *self, PyObject *mro, int initial)
{
assert(PyTuple_CheckExact(mro));
if (self->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) {
// XXX tp_mro can probably be statically allocated for each
// static builtin type.
- assert(_Py_IsMainInterpreter(_PyInterpreterState_GET()));
+ assert(initial);
assert(self->tp_mro == NULL);
/* Other checks are done via set_tp_bases. */
_Py_SetImmortal(mro);
@@ -428,10 +494,10 @@ set_tp_mro(PyTypeObject *self, PyObject *mro)
}
static inline void
-clear_tp_mro(PyTypeObject *self)
+clear_tp_mro(PyTypeObject *self, int final)
{
if (self->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) {
- if (_Py_IsMainInterpreter(_PyInterpreterState_GET())) {
+ if (final) {
if (self->tp_mro != NULL) {
if (PyTuple_GET_SIZE(self->tp_mro) == 0) {
Py_CLEAR(self->tp_mro);
@@ -457,7 +523,7 @@ init_tp_subclasses(PyTypeObject *self)
}
if (self->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) {
PyInterpreterState *interp = _PyInterpreterState_GET();
- static_builtin_state *state = _PyStaticType_GetState(interp, self);
+ managed_static_type_state *state = _PyStaticType_GetState(interp, self);
state->tp_subclasses = subclasses;
return subclasses;
}
@@ -473,7 +539,7 @@ clear_tp_subclasses(PyTypeObject *self)
has no subclass. */
if (self->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) {
PyInterpreterState *interp = _PyInterpreterState_GET();
- static_builtin_state *state = _PyStaticType_GetState(interp, self);
+ managed_static_type_state *state = _PyStaticType_GetState(interp, self);
Py_CLEAR(state->tp_subclasses);
return;
}
@@ -485,7 +551,7 @@ lookup_tp_subclasses(PyTypeObject *self)
{
if (self->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) {
PyInterpreterState *interp = _PyInterpreterState_GET();
- static_builtin_state *state = _PyStaticType_GetState(interp, self);
+ managed_static_type_state *state = _PyStaticType_GetState(interp, self);
assert(state != NULL);
return state->tp_subclasses;
}
@@ -774,10 +840,10 @@ _PyTypes_Fini(PyInterpreterState *interp)
struct type_cache *cache = &interp->types.type_cache;
type_cache_clear(cache, NULL);
- assert(interp->types.num_builtins_initialized == 0);
+ assert(interp->types.builtins.num_initialized == 0);
// All the static builtin types should have been finalized already.
- for (size_t i = 0; i < _Py_MAX_STATIC_BUILTIN_TYPES; i++) {
- assert(interp->types.builtins[i].type == NULL);
+ for (size_t i = 0; i < _Py_MAX_MANAGED_STATIC_BUILTIN_TYPES; i++) {
+ assert(interp->types.builtins.initialized[i].type == NULL);
}
}
@@ -1444,7 +1510,7 @@ mro_hierarchy(PyTypeObject *type, PyObject *temp)
Py_XDECREF(tuple);
if (res < 0) {
- set_tp_mro(type, old_mro);
+ set_tp_mro(type, old_mro, 0);
Py_DECREF(new_mro);
return -1;
}
@@ -1545,7 +1611,7 @@ type_set_bases_unlocked(PyTypeObject *type, PyObject *new_bases, void *context)
assert(old_bases != NULL);
PyTypeObject *old_base = type->tp_base;
- set_tp_bases(type, Py_NewRef(new_bases));
+ set_tp_bases(type, Py_NewRef(new_bases), 0);
type->tp_base = (PyTypeObject *)Py_NewRef(new_base);
PyObject *temp = PyList_New(0);
@@ -1593,7 +1659,7 @@ type_set_bases_unlocked(PyTypeObject *type, PyObject *new_bases, void *context)
"", 2, 3, &cls, &new_mro, &old_mro);
/* Do not rollback if cls has a newer version of MRO. */
if (lookup_tp_mro(cls) == new_mro) {
- set_tp_mro(cls, Py_XNewRef(old_mro));
+ set_tp_mro(cls, Py_XNewRef(old_mro), 0);
Py_DECREF(new_mro);
}
}
@@ -1603,7 +1669,7 @@ type_set_bases_unlocked(PyTypeObject *type, PyObject *new_bases, void *context)
if (lookup_tp_bases(type) == new_bases) {
assert(type->tp_base == new_base);
- set_tp_bases(type, old_bases);
+ set_tp_bases(type, old_bases, 0);
type->tp_base = old_base;
Py_DECREF(new_bases);
@@ -2977,7 +3043,7 @@ mro_invoke(PyTypeObject *type)
- Returns -1 in case of an error.
*/
static int
-mro_internal_unlocked(PyTypeObject *type, PyObject **p_old_mro)
+mro_internal_unlocked(PyTypeObject *type, int initial, PyObject **p_old_mro)
{
ASSERT_TYPE_LOCK_HELD();
@@ -3000,7 +3066,7 @@ mro_internal_unlocked(PyTypeObject *type, PyObject **p_old_mro)
return 0;
}
- set_tp_mro(type, new_mro);
+ set_tp_mro(type, new_mro, initial);
type_mro_modified(type, new_mro);
/* corner case: the super class might have been hidden
@@ -3030,7 +3096,7 @@ mro_internal(PyTypeObject *type, PyObject **p_old_mro)
{
int res;
BEGIN_TYPE_LOCK()
- res = mro_internal_unlocked(type, p_old_mro);
+ res = mro_internal_unlocked(type, 0, p_old_mro);
END_TYPE_LOCK()
return res;
}
@@ -3625,7 +3691,7 @@ type_new_alloc(type_new_ctx *ctx)
type->tp_as_mapping = &et->as_mapping;
type->tp_as_buffer = &et->as_buffer;
- set_tp_bases(type, Py_NewRef(ctx->bases));
+ set_tp_bases(type, Py_NewRef(ctx->bases), 1);
type->tp_base = (PyTypeObject *)Py_NewRef(ctx->base);
type->tp_dealloc = subtype_dealloc;
@@ -4619,7 +4685,7 @@ _PyType_FromMetaclass_impl(
/* Set slots we have prepared */
type->tp_base = (PyTypeObject *)Py_NewRef(base);
- set_tp_bases(type, bases);
+ set_tp_bases(type, bases, 1);
bases = NULL; // We give our reference to bases to the type
type->tp_doc = tp_doc;
@@ -5524,7 +5590,7 @@ type_dealloc_common(PyTypeObject *type)
static void
-clear_static_tp_subclasses(PyTypeObject *type)
+clear_static_tp_subclasses(PyTypeObject *type, int isbuiltin)
{
PyObject *subclasses = lookup_tp_subclasses(type);
if (subclasses == NULL) {
@@ -5561,47 +5627,64 @@ clear_static_tp_subclasses(PyTypeObject *type)
continue;
}
// All static builtin subtypes should have been finalized already.
- assert(!(subclass->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN));
+ assert(!isbuiltin || !(subclass->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN));
Py_DECREF(subclass);
}
+#else
+ (void)isbuiltin;
#endif
clear_tp_subclasses(type);
}
static void
-clear_static_type_objects(PyInterpreterState *interp, PyTypeObject *type)
+clear_static_type_objects(PyInterpreterState *interp, PyTypeObject *type,
+ int isbuiltin, int final)
{
- if (_Py_IsMainInterpreter(interp)) {
+ if (final) {
Py_CLEAR(type->tp_cache);
}
clear_tp_dict(type);
- clear_tp_bases(type);
- clear_tp_mro(type);
- clear_static_tp_subclasses(type);
+ clear_tp_bases(type, final);
+ clear_tp_mro(type, final);
+ clear_static_tp_subclasses(type, isbuiltin);
}
-void
-_PyStaticType_Dealloc(PyInterpreterState *interp, PyTypeObject *type)
+
+static void
+fini_static_type(PyInterpreterState *interp, PyTypeObject *type,
+ int isbuiltin, int final)
{
assert(type->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN);
assert(_Py_IsImmortal((PyObject *)type));
type_dealloc_common(type);
- clear_static_type_objects(interp, type);
+ clear_static_type_objects(interp, type, isbuiltin, final);
- if (_Py_IsMainInterpreter(interp)) {
+ if (final) {
type->tp_flags &= ~Py_TPFLAGS_READY;
type->tp_flags &= ~Py_TPFLAGS_VALID_VERSION_TAG;
type->tp_version_tag = 0;
}
_PyStaticType_ClearWeakRefs(interp, type);
- static_builtin_state_clear(interp, type);
+ managed_static_type_state_clear(interp, type, isbuiltin, final);
/* We leave _Py_TPFLAGS_STATIC_BUILTIN set on tp_flags. */
}
+void
+_PyStaticType_FiniForExtension(PyInterpreterState *interp, PyTypeObject *type, int final)
+{
+ fini_static_type(interp, type, 0, final);
+}
+
+void
+_PyStaticType_FiniBuiltin(PyInterpreterState *interp, PyTypeObject *type)
+{
+ fini_static_type(interp, type, 1, _Py_IsMainInterpreter(interp));
+}
+
static void
type_dealloc(PyObject *self)
@@ -7655,10 +7738,10 @@ type_ready_set_type(PyTypeObject *type)
}
static int
-type_ready_set_bases(PyTypeObject *type)
+type_ready_set_bases(PyTypeObject *type, int initial)
{
if (type->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) {
- if (!_Py_IsMainInterpreter(_PyInterpreterState_GET())) {
+ if (!initial) {
assert(lookup_tp_bases(type) != NULL);
return 0;
}
@@ -7677,7 +7760,7 @@ type_ready_set_bases(PyTypeObject *type)
if (bases == NULL) {
return -1;
}
- set_tp_bases(type, bases);
+ set_tp_bases(type, bases, 1);
}
return 0;
}
@@ -7787,12 +7870,12 @@ type_ready_preheader(PyTypeObject *type)
}
static int
-type_ready_mro(PyTypeObject *type)
+type_ready_mro(PyTypeObject *type, int initial)
{
ASSERT_TYPE_LOCK_HELD();
if (type->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) {
- if (!_Py_IsMainInterpreter(_PyInterpreterState_GET())) {
+ if (!initial) {
assert(lookup_tp_mro(type) != NULL);
return 0;
}
@@ -7800,7 +7883,7 @@ type_ready_mro(PyTypeObject *type)
}
/* Calculate method resolution order */
- if (mro_internal_unlocked(type, NULL) < 0) {
+ if (mro_internal_unlocked(type, initial, NULL) < 0) {
return -1;
}
PyObject *mro = lookup_tp_mro(type);
@@ -7955,7 +8038,7 @@ type_ready_add_subclasses(PyTypeObject *type)
// Set tp_new and the "__new__" key in the type dictionary.
// Use the Py_TPFLAGS_DISALLOW_INSTANTIATION flag.
static int
-type_ready_set_new(PyTypeObject *type, int rerunbuiltin)
+type_ready_set_new(PyTypeObject *type, int initial)
{
PyTypeObject *base = type->tp_base;
/* The condition below could use some explanation.
@@ -7977,7 +8060,7 @@ type_ready_set_new(PyTypeObject *type, int rerunbuiltin)
if (!(type->tp_flags & Py_TPFLAGS_DISALLOW_INSTANTIATION)) {
if (type->tp_new != NULL) {
- if (!rerunbuiltin || base == NULL || type->tp_new != base->tp_new) {
+ if (initial || base == NULL || type->tp_new != base->tp_new) {
// If "__new__" key does not exists in the type dictionary,
// set it to tp_new_wrapper().
if (add_tp_new_wrapper(type) < 0) {
@@ -8059,7 +8142,7 @@ type_ready_post_checks(PyTypeObject *type)
static int
-type_ready(PyTypeObject *type, int rerunbuiltin)
+type_ready(PyTypeObject *type, int initial)
{
ASSERT_TYPE_LOCK_HELD();
@@ -8089,19 +8172,19 @@ type_ready(PyTypeObject *type, int rerunbuiltin)
if (type_ready_set_type(type) < 0) {
goto error;
}
- if (type_ready_set_bases(type) < 0) {
+ if (type_ready_set_bases(type, initial) < 0) {
goto error;
}
- if (type_ready_mro(type) < 0) {
+ if (type_ready_mro(type, initial) < 0) {
goto error;
}
- if (type_ready_set_new(type, rerunbuiltin) < 0) {
+ if (type_ready_set_new(type, initial) < 0) {
goto error;
}
if (type_ready_fill_dict(type) < 0) {
goto error;
}
- if (!rerunbuiltin) {
+ if (initial) {
if (type_ready_inherit(type) < 0) {
goto error;
}
@@ -8115,7 +8198,7 @@ type_ready(PyTypeObject *type, int rerunbuiltin)
if (type_ready_add_subclasses(type) < 0) {
goto error;
}
- if (!rerunbuiltin) {
+ if (initial) {
if (type_ready_managed_dict(type) < 0) {
goto error;
}
@@ -8155,7 +8238,7 @@ PyType_Ready(PyTypeObject *type)
int res;
BEGIN_TYPE_LOCK()
if (!(type->tp_flags & Py_TPFLAGS_READY)) {
- res = type_ready(type, 0);
+ res = type_ready(type, 1);
} else {
res = 0;
assert(_PyType_CheckConsistency(type));
@@ -8164,17 +8247,18 @@ PyType_Ready(PyTypeObject *type)
return res;
}
-int
-_PyStaticType_InitBuiltin(PyInterpreterState *interp, PyTypeObject *self)
+
+static int
+init_static_type(PyInterpreterState *interp, PyTypeObject *self,
+ int isbuiltin, int initial)
{
assert(_Py_IsImmortal((PyObject *)self));
assert(!(self->tp_flags & Py_TPFLAGS_HEAPTYPE));
assert(!(self->tp_flags & Py_TPFLAGS_MANAGED_DICT));
assert(!(self->tp_flags & Py_TPFLAGS_MANAGED_WEAKREF));
- int ismain = _Py_IsMainInterpreter(interp);
if ((self->tp_flags & Py_TPFLAGS_READY) == 0) {
- assert(ismain);
+ assert(initial);
self->tp_flags |= _Py_TPFLAGS_STATIC_BUILTIN;
self->tp_flags |= Py_TPFLAGS_IMMUTABLETYPE;
@@ -8184,24 +8268,36 @@ _PyStaticType_InitBuiltin(PyInterpreterState *interp, PyTypeObject *self)
self->tp_flags |= Py_TPFLAGS_VALID_VERSION_TAG;
}
else {
- assert(!ismain);
+ assert(!initial);
assert(self->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN);
assert(self->tp_flags & Py_TPFLAGS_VALID_VERSION_TAG);
}
- static_builtin_state_init(interp, self);
+ managed_static_type_state_init(interp, self, isbuiltin, initial);
int res;
BEGIN_TYPE_LOCK();
- res = type_ready(self, !ismain);
+ res = type_ready(self, initial);
END_TYPE_LOCK()
if (res < 0) {
_PyStaticType_ClearWeakRefs(interp, self);
- static_builtin_state_clear(interp, self);
+ managed_static_type_state_clear(interp, self, isbuiltin, initial);
}
return res;
}
+int
+_PyStaticType_InitForExtension(PyInterpreterState *interp, PyTypeObject *self)
+{
+ return init_static_type(interp, self, 0, ((self->tp_flags & Py_TPFLAGS_READY) == 0));
+}
+
+int
+_PyStaticType_InitBuiltin(PyInterpreterState *interp, PyTypeObject *self)
+{
+ return init_static_type(interp, self, 1, _Py_IsMainInterpreter(interp));
+}
+
static int
add_subclass(PyTypeObject *base, PyTypeObject *type)
diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c
index 240f4e7..59ca344 100644
--- a/Objects/unicodeobject.c
+++ b/Objects/unicodeobject.c
@@ -15510,9 +15510,9 @@ unicode_is_finalizing(void)
void
_PyUnicode_FiniTypes(PyInterpreterState *interp)
{
- _PyStaticType_Dealloc(interp, &EncodingMapType);
- _PyStaticType_Dealloc(interp, &PyFieldNameIter_Type);
- _PyStaticType_Dealloc(interp, &PyFormatterIter_Type);
+ _PyStaticType_FiniBuiltin(interp, &EncodingMapType);
+ _PyStaticType_FiniBuiltin(interp, &PyFieldNameIter_Type);
+ _PyStaticType_FiniBuiltin(interp, &PyFormatterIter_Type);
}
diff --git a/Objects/weakrefobject.c b/Objects/weakrefobject.c
index 88afaec..3b027e1 100644
--- a/Objects/weakrefobject.c
+++ b/Objects/weakrefobject.c
@@ -1066,7 +1066,7 @@ PyObject_ClearWeakRefs(PyObject *object)
void
_PyStaticType_ClearWeakRefs(PyInterpreterState *interp, PyTypeObject *type)
{
- static_builtin_state *state = _PyStaticType_GetState(interp, type);
+ managed_static_type_state *state = _PyStaticType_GetState(interp, type);
PyObject **list = _PyStaticType_GET_WEAKREFS_LISTPTR(state);
// This is safe to do without holding the lock in free-threaded builds;
// there is only one thread running and no new threads can be created.