mirror of https://github.com/python/cpython
gh-94673: Properly Initialize and Finalize Static Builtin Types for Each Interpreter (gh-104072)
Until now, we haven't been initializing nor finalizing the per-interpreter state properly.
This commit is contained in:
parent
b1ca34d4d5
commit
fdd878650d
|
@ -272,8 +272,9 @@ _PyObject_GET_WEAKREFS_LISTPTR(PyObject *op)
|
||||||
{
|
{
|
||||||
if (PyType_Check(op) &&
|
if (PyType_Check(op) &&
|
||||||
((PyTypeObject *)op)->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) {
|
((PyTypeObject *)op)->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) {
|
||||||
|
PyInterpreterState *interp = _PyInterpreterState_GET();
|
||||||
static_builtin_state *state = _PyStaticType_GetState(
|
static_builtin_state *state = _PyStaticType_GetState(
|
||||||
(PyTypeObject *)op);
|
interp, (PyTypeObject *)op);
|
||||||
return _PyStaticType_GET_WEAKREFS_LISTPTR(state);
|
return _PyStaticType_GET_WEAKREFS_LISTPTR(state);
|
||||||
}
|
}
|
||||||
// Essentially _PyObject_GET_WEAKREFS_LISTPTR_FROM_OFFSET():
|
// Essentially _PyObject_GET_WEAKREFS_LISTPTR_FROM_OFFSET():
|
||||||
|
|
|
@ -39,7 +39,7 @@ extern PyStatus _PySys_Create(
|
||||||
extern PyStatus _PySys_ReadPreinitWarnOptions(PyWideStringList *options);
|
extern PyStatus _PySys_ReadPreinitWarnOptions(PyWideStringList *options);
|
||||||
extern PyStatus _PySys_ReadPreinitXOptions(PyConfig *config);
|
extern PyStatus _PySys_ReadPreinitXOptions(PyConfig *config);
|
||||||
extern int _PySys_UpdateConfig(PyThreadState *tstate);
|
extern int _PySys_UpdateConfig(PyThreadState *tstate);
|
||||||
extern void _PySys_Fini(PyInterpreterState *interp);
|
extern void _PySys_FiniTypes(PyInterpreterState *interp);
|
||||||
extern int _PyBuiltins_AddExceptions(PyObject * bltinmod);
|
extern int _PyBuiltins_AddExceptions(PyObject * bltinmod);
|
||||||
extern PyStatus _Py_HashRandomization_Init(const PyConfig *);
|
extern PyStatus _Py_HashRandomization_Init(const PyConfig *);
|
||||||
|
|
||||||
|
|
|
@ -16,18 +16,22 @@ PyAPI_FUNC(PyTypeObject *) _PyStructSequence_NewType(
|
||||||
unsigned long tp_flags);
|
unsigned long tp_flags);
|
||||||
|
|
||||||
extern int _PyStructSequence_InitBuiltinWithFlags(
|
extern int _PyStructSequence_InitBuiltinWithFlags(
|
||||||
|
PyInterpreterState *interp,
|
||||||
PyTypeObject *type,
|
PyTypeObject *type,
|
||||||
PyStructSequence_Desc *desc,
|
PyStructSequence_Desc *desc,
|
||||||
unsigned long tp_flags);
|
unsigned long tp_flags);
|
||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
_PyStructSequence_InitBuiltin(PyTypeObject *type,
|
_PyStructSequence_InitBuiltin(PyInterpreterState *interp,
|
||||||
|
PyTypeObject *type,
|
||||||
PyStructSequence_Desc *desc)
|
PyStructSequence_Desc *desc)
|
||||||
{
|
{
|
||||||
return _PyStructSequence_InitBuiltinWithFlags(type, desc, 0);
|
return _PyStructSequence_InitBuiltinWithFlags(interp, type, desc, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern void _PyStructSequence_FiniBuiltin(PyTypeObject *type);
|
extern void _PyStructSequence_FiniBuiltin(
|
||||||
|
PyInterpreterState *interp,
|
||||||
|
PyTypeObject *type);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -104,10 +104,10 @@ _PyType_GetModuleState(PyTypeObject *type)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
extern int _PyStaticType_InitBuiltin(PyTypeObject *type);
|
extern int _PyStaticType_InitBuiltin(PyInterpreterState *, PyTypeObject *type);
|
||||||
extern static_builtin_state * _PyStaticType_GetState(PyTypeObject *);
|
extern static_builtin_state * _PyStaticType_GetState(PyInterpreterState *, PyTypeObject *);
|
||||||
extern void _PyStaticType_ClearWeakRefs(PyTypeObject *type);
|
extern void _PyStaticType_ClearWeakRefs(PyInterpreterState *, PyTypeObject *type);
|
||||||
extern void _PyStaticType_Dealloc(PyTypeObject *type);
|
extern void _PyStaticType_Dealloc(PyInterpreterState *, PyTypeObject *);
|
||||||
|
|
||||||
PyObject *
|
PyObject *
|
||||||
_Py_type_getattro_impl(PyTypeObject *type, PyObject *name, int *suppress_missing_attribute);
|
_Py_type_getattro_impl(PyTypeObject *type, PyObject *name, int *suppress_missing_attribute);
|
||||||
|
|
|
@ -680,7 +680,7 @@ _PyIO_InitTypes(PyInterpreterState *interp)
|
||||||
|
|
||||||
for (size_t i=0; i < Py_ARRAY_LENGTH(static_types); i++) {
|
for (size_t i=0; i < Py_ARRAY_LENGTH(static_types); i++) {
|
||||||
PyTypeObject *type = static_types[i];
|
PyTypeObject *type = static_types[i];
|
||||||
if (_PyStaticType_InitBuiltin(type) < 0) {
|
if (_PyStaticType_InitBuiltin(interp, type) < 0) {
|
||||||
return _PyStatus_ERR("Can't initialize builtin type");
|
return _PyStatus_ERR("Can't initialize builtin type");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -691,15 +691,11 @@ _PyIO_InitTypes(PyInterpreterState *interp)
|
||||||
void
|
void
|
||||||
_PyIO_FiniTypes(PyInterpreterState *interp)
|
_PyIO_FiniTypes(PyInterpreterState *interp)
|
||||||
{
|
{
|
||||||
if (!_Py_IsMainInterpreter(interp)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deallocate types in the reverse order to deallocate subclasses before
|
// Deallocate types in the reverse order to deallocate subclasses before
|
||||||
// their base classes.
|
// their base classes.
|
||||||
for (Py_ssize_t i=Py_ARRAY_LENGTH(static_types) - 1; i >= 0; i--) {
|
for (Py_ssize_t i=Py_ARRAY_LENGTH(static_types) - 1; i >= 0; i--) {
|
||||||
PyTypeObject *type = static_types[i];
|
PyTypeObject *type = static_types[i];
|
||||||
_PyStaticType_Dealloc(type);
|
_PyStaticType_Dealloc(interp, type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3598,7 +3598,7 @@ _PyExc_InitTypes(PyInterpreterState *interp)
|
||||||
{
|
{
|
||||||
for (size_t i=0; i < Py_ARRAY_LENGTH(static_exceptions); i++) {
|
for (size_t i=0; i < Py_ARRAY_LENGTH(static_exceptions); i++) {
|
||||||
PyTypeObject *exc = static_exceptions[i].exc;
|
PyTypeObject *exc = static_exceptions[i].exc;
|
||||||
if (_PyStaticType_InitBuiltin(exc) < 0) {
|
if (_PyStaticType_InitBuiltin(interp, exc) < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3609,13 +3609,9 @@ _PyExc_InitTypes(PyInterpreterState *interp)
|
||||||
static void
|
static void
|
||||||
_PyExc_FiniTypes(PyInterpreterState *interp)
|
_PyExc_FiniTypes(PyInterpreterState *interp)
|
||||||
{
|
{
|
||||||
if (!_Py_IsMainInterpreter(interp)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Py_ssize_t i=Py_ARRAY_LENGTH(static_exceptions) - 1; i >= 0; i--) {
|
for (Py_ssize_t i=Py_ARRAY_LENGTH(static_exceptions) - 1; i >= 0; i--) {
|
||||||
PyTypeObject *exc = static_exceptions[i].exc;
|
PyTypeObject *exc = static_exceptions[i].exc;
|
||||||
_PyStaticType_Dealloc(exc);
|
_PyStaticType_Dealloc(interp, exc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1991,8 +1991,9 @@ PyStatus
|
||||||
_PyFloat_InitTypes(PyInterpreterState *interp)
|
_PyFloat_InitTypes(PyInterpreterState *interp)
|
||||||
{
|
{
|
||||||
/* Init float info */
|
/* Init float info */
|
||||||
if (_PyStructSequence_InitBuiltin(&FloatInfoType,
|
if (_PyStructSequence_InitBuiltin(interp, &FloatInfoType,
|
||||||
&floatinfo_desc) < 0) {
|
&floatinfo_desc) < 0)
|
||||||
|
{
|
||||||
return _PyStatus_ERR("can't init float info type");
|
return _PyStatus_ERR("can't init float info type");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2028,9 +2029,7 @@ _PyFloat_Fini(PyInterpreterState *interp)
|
||||||
void
|
void
|
||||||
_PyFloat_FiniType(PyInterpreterState *interp)
|
_PyFloat_FiniType(PyInterpreterState *interp)
|
||||||
{
|
{
|
||||||
if (_Py_IsMainInterpreter(interp)) {
|
_PyStructSequence_FiniBuiltin(interp, &FloatInfoType);
|
||||||
_PyStructSequence_FiniBuiltin(&FloatInfoType);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Print summary info about the state of the optimized allocator */
|
/* Print summary info about the state of the optimized allocator */
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
#include "pycore_initconfig.h" // _PyStatus_OK()
|
#include "pycore_initconfig.h" // _PyStatus_OK()
|
||||||
#include "pycore_long.h" // _Py_SmallInts
|
#include "pycore_long.h" // _Py_SmallInts
|
||||||
#include "pycore_object.h" // _PyObject_Init()
|
#include "pycore_object.h" // _PyObject_Init()
|
||||||
#include "pycore_pystate.h" // _Py_IsMainInterpreter()
|
|
||||||
#include "pycore_runtime.h" // _PY_NSMALLPOSINTS
|
#include "pycore_runtime.h" // _PY_NSMALLPOSINTS
|
||||||
#include "pycore_structseq.h" // _PyStructSequence_FiniBuiltin()
|
#include "pycore_structseq.h" // _PyStructSequence_FiniBuiltin()
|
||||||
|
|
||||||
|
@ -6352,7 +6351,9 @@ PyStatus
|
||||||
_PyLong_InitTypes(PyInterpreterState *interp)
|
_PyLong_InitTypes(PyInterpreterState *interp)
|
||||||
{
|
{
|
||||||
/* initialize int_info */
|
/* initialize int_info */
|
||||||
if (_PyStructSequence_InitBuiltin(&Int_InfoType, &int_info_desc) < 0) {
|
if (_PyStructSequence_InitBuiltin(interp, &Int_InfoType,
|
||||||
|
&int_info_desc) < 0)
|
||||||
|
{
|
||||||
return _PyStatus_ERR("can't init int info type");
|
return _PyStatus_ERR("can't init int info type");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6363,9 +6364,5 @@ _PyLong_InitTypes(PyInterpreterState *interp)
|
||||||
void
|
void
|
||||||
_PyLong_FiniTypes(PyInterpreterState *interp)
|
_PyLong_FiniTypes(PyInterpreterState *interp)
|
||||||
{
|
{
|
||||||
if (!_Py_IsMainInterpreter(interp)) {
|
_PyStructSequence_FiniBuiltin(interp, &Int_InfoType);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_PyStructSequence_FiniBuiltin(&Int_InfoType);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2105,7 +2105,7 @@ _PyTypes_InitTypes(PyInterpreterState *interp)
|
||||||
// All other static types (unless initialized elsewhere)
|
// All other static types (unless initialized elsewhere)
|
||||||
for (size_t i=0; i < Py_ARRAY_LENGTH(static_types); i++) {
|
for (size_t i=0; i < Py_ARRAY_LENGTH(static_types); i++) {
|
||||||
PyTypeObject *type = static_types[i];
|
PyTypeObject *type = static_types[i];
|
||||||
if (_PyStaticType_InitBuiltin(type) < 0) {
|
if (_PyStaticType_InitBuiltin(interp, type) < 0) {
|
||||||
return _PyStatus_ERR("Can't initialize builtin type");
|
return _PyStatus_ERR("Can't initialize builtin type");
|
||||||
}
|
}
|
||||||
if (type == &PyType_Type) {
|
if (type == &PyType_Type) {
|
||||||
|
@ -2128,15 +2128,11 @@ _PyTypes_InitTypes(PyInterpreterState *interp)
|
||||||
void
|
void
|
||||||
_PyTypes_FiniTypes(PyInterpreterState *interp)
|
_PyTypes_FiniTypes(PyInterpreterState *interp)
|
||||||
{
|
{
|
||||||
if (!_Py_IsMainInterpreter(interp)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deallocate types in the reverse order to deallocate subclasses before
|
// Deallocate types in the reverse order to deallocate subclasses before
|
||||||
// their base classes.
|
// their base classes.
|
||||||
for (Py_ssize_t i=Py_ARRAY_LENGTH(static_types)-1; i>=0; i--) {
|
for (Py_ssize_t i=Py_ARRAY_LENGTH(static_types)-1; i>=0; i--) {
|
||||||
PyTypeObject *type = static_types[i];
|
PyTypeObject *type = static_types[i];
|
||||||
_PyStaticType_Dealloc(type);
|
_PyStaticType_Dealloc(interp, type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -502,7 +502,8 @@ initialize_static_type(PyTypeObject *type, PyStructSequence_Desc *desc,
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
_PyStructSequence_InitBuiltinWithFlags(PyTypeObject *type,
|
_PyStructSequence_InitBuiltinWithFlags(PyInterpreterState *interp,
|
||||||
|
PyTypeObject *type,
|
||||||
PyStructSequence_Desc *desc,
|
PyStructSequence_Desc *desc,
|
||||||
unsigned long tp_flags)
|
unsigned long tp_flags)
|
||||||
{
|
{
|
||||||
|
@ -536,7 +537,7 @@ _PyStructSequence_InitBuiltinWithFlags(PyTypeObject *type,
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (_PyStaticType_InitBuiltin(type) < 0) {
|
if (_PyStaticType_InitBuiltin(interp, type) < 0) {
|
||||||
PyErr_Format(PyExc_RuntimeError,
|
PyErr_Format(PyExc_RuntimeError,
|
||||||
"Can't initialize builtin type %s",
|
"Can't initialize builtin type %s",
|
||||||
desc->name);
|
desc->name);
|
||||||
|
@ -606,7 +607,7 @@ PyStructSequence_InitType(PyTypeObject *type, PyStructSequence_Desc *desc)
|
||||||
initialized via _PyStructSequence_InitBuiltinWithFlags(). */
|
initialized via _PyStructSequence_InitBuiltinWithFlags(). */
|
||||||
|
|
||||||
void
|
void
|
||||||
_PyStructSequence_FiniBuiltin(PyTypeObject *type)
|
_PyStructSequence_FiniBuiltin(PyInterpreterState *interp, PyTypeObject *type)
|
||||||
{
|
{
|
||||||
// Ensure that the type is initialized
|
// Ensure that the type is initialized
|
||||||
assert(type->tp_name != NULL);
|
assert(type->tp_name != NULL);
|
||||||
|
@ -620,13 +621,15 @@ _PyStructSequence_FiniBuiltin(PyTypeObject *type)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_PyStaticType_Dealloc(type);
|
_PyStaticType_Dealloc(interp, type);
|
||||||
|
|
||||||
// Undo _PyStructSequence_InitBuiltinWithFlags().
|
if (_Py_IsMainInterpreter(interp)) {
|
||||||
type->tp_name = NULL;
|
// Undo _PyStructSequence_InitBuiltinWithFlags().
|
||||||
PyMem_Free(type->tp_members);
|
type->tp_name = NULL;
|
||||||
type->tp_members = NULL;
|
PyMem_Free(type->tp_members);
|
||||||
type->tp_base = NULL;
|
type->tp_members = NULL;
|
||||||
|
type->tp_base = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -69,13 +69,11 @@ static inline PyTypeObject * subclass_from_ref(PyObject *ref);
|
||||||
|
|
||||||
/* helpers for for static builtin types */
|
/* helpers for for static builtin types */
|
||||||
|
|
||||||
#ifndef NDEBUG
|
|
||||||
static inline int
|
static inline int
|
||||||
static_builtin_index_is_set(PyTypeObject *self)
|
static_builtin_index_is_set(PyTypeObject *self)
|
||||||
{
|
{
|
||||||
return self->tp_subclasses != NULL;
|
return self->tp_subclasses != NULL;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
static inline size_t
|
static inline size_t
|
||||||
static_builtin_index_get(PyTypeObject *self)
|
static_builtin_index_get(PyTypeObject *self)
|
||||||
|
@ -107,43 +105,46 @@ static_builtin_state_get(PyInterpreterState *interp, PyTypeObject *self)
|
||||||
|
|
||||||
/* For static types we store some state in an array on each interpreter. */
|
/* For static types we store some state in an array on each interpreter. */
|
||||||
static_builtin_state *
|
static_builtin_state *
|
||||||
_PyStaticType_GetState(PyTypeObject *self)
|
_PyStaticType_GetState(PyInterpreterState *interp, PyTypeObject *self)
|
||||||
{
|
{
|
||||||
assert(self->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN);
|
assert(self->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN);
|
||||||
PyInterpreterState *interp = _PyInterpreterState_GET();
|
|
||||||
return static_builtin_state_get(interp, self);
|
return static_builtin_state_get(interp, self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Set the type's per-interpreter state. */
|
||||||
static void
|
static void
|
||||||
static_builtin_state_init(PyTypeObject *self)
|
static_builtin_state_init(PyInterpreterState *interp, PyTypeObject *self)
|
||||||
{
|
{
|
||||||
/* Set the type's per-interpreter state. */
|
if (!static_builtin_index_is_set(self)) {
|
||||||
PyInterpreterState *interp = _PyInterpreterState_GET();
|
static_builtin_index_set(self, interp->types.num_builtins_initialized);
|
||||||
|
}
|
||||||
|
static_builtin_state *state = static_builtin_state_get(interp, self);
|
||||||
|
|
||||||
/* It should only be called once for each builtin type. */
|
/* It should only be called once for each builtin type. */
|
||||||
assert(!static_builtin_index_is_set(self));
|
assert(state->type == NULL);
|
||||||
|
|
||||||
static_builtin_index_set(self, interp->types.num_builtins_initialized);
|
|
||||||
interp->types.num_builtins_initialized++;
|
|
||||||
|
|
||||||
static_builtin_state *state = static_builtin_state_get(interp, self);
|
|
||||||
state->type = self;
|
state->type = self;
|
||||||
|
|
||||||
/* state->tp_subclasses is left NULL until init_subclasses() sets it. */
|
/* state->tp_subclasses is left NULL until init_subclasses() sets it. */
|
||||||
/* state->tp_weaklist is left NULL until insert_head() or insert_after()
|
/* state->tp_weaklist is left NULL until insert_head() or insert_after()
|
||||||
(in weakrefobject.c) sets it. */
|
(in weakrefobject.c) sets it. */
|
||||||
|
|
||||||
|
interp->types.num_builtins_initialized++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Reset the type's per-interpreter state.
|
||||||
|
This basically undoes what static_builtin_state_init() did. */
|
||||||
static void
|
static void
|
||||||
static_builtin_state_clear(PyTypeObject *self)
|
static_builtin_state_clear(PyInterpreterState *interp, PyTypeObject *self)
|
||||||
{
|
{
|
||||||
/* Reset the type's per-interpreter state.
|
|
||||||
This basically undoes what static_builtin_state_init() did. */
|
|
||||||
PyInterpreterState *interp = _PyInterpreterState_GET();
|
|
||||||
|
|
||||||
static_builtin_state *state = static_builtin_state_get(interp, self);
|
static_builtin_state *state = static_builtin_state_get(interp, self);
|
||||||
|
|
||||||
|
assert(state->type != NULL);
|
||||||
state->type = NULL;
|
state->type = NULL;
|
||||||
assert(state->tp_weaklist == NULL); // It was already cleared out.
|
assert(state->tp_weaklist == NULL); // It was already cleared out.
|
||||||
static_builtin_index_clear(self);
|
|
||||||
|
if (_Py_IsMainInterpreter(interp)) {
|
||||||
|
static_builtin_index_clear(self);
|
||||||
|
}
|
||||||
|
|
||||||
assert(interp->types.num_builtins_initialized > 0);
|
assert(interp->types.num_builtins_initialized > 0);
|
||||||
interp->types.num_builtins_initialized--;
|
interp->types.num_builtins_initialized--;
|
||||||
|
@ -4491,33 +4492,37 @@ clear_static_tp_subclasses(PyTypeObject *type)
|
||||||
clear_subclasses(type);
|
clear_subclasses(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void
|
||||||
_PyStaticType_Dealloc(PyTypeObject *type)
|
clear_static_type_objects(PyInterpreterState *interp, PyTypeObject *type)
|
||||||
{
|
{
|
||||||
assert(!(type->tp_flags & Py_TPFLAGS_HEAPTYPE));
|
if (_Py_IsMainInterpreter(interp)) {
|
||||||
|
Py_CLEAR(type->tp_dict);
|
||||||
|
Py_CLEAR(type->tp_bases);
|
||||||
|
Py_CLEAR(type->tp_mro);
|
||||||
|
Py_CLEAR(type->tp_cache);
|
||||||
|
}
|
||||||
|
clear_static_tp_subclasses(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_PyStaticType_Dealloc(PyInterpreterState *interp, PyTypeObject *type)
|
||||||
|
{
|
||||||
|
assert(type->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN);
|
||||||
|
assert(_Py_IsImmortal((PyObject *)type));
|
||||||
|
|
||||||
type_dealloc_common(type);
|
type_dealloc_common(type);
|
||||||
|
|
||||||
Py_CLEAR(type->tp_dict);
|
clear_static_type_objects(interp, type);
|
||||||
Py_CLEAR(type->tp_bases);
|
|
||||||
Py_CLEAR(type->tp_mro);
|
|
||||||
Py_CLEAR(type->tp_cache);
|
|
||||||
clear_static_tp_subclasses(type);
|
|
||||||
|
|
||||||
// PyObject_ClearWeakRefs() raises an exception if Py_REFCNT() != 0
|
if (_Py_IsMainInterpreter(interp)) {
|
||||||
if (Py_REFCNT(type) == 0) {
|
type->tp_flags &= ~Py_TPFLAGS_READY;
|
||||||
PyObject_ClearWeakRefs((PyObject *)type);
|
type->tp_flags &= ~Py_TPFLAGS_VALID_VERSION_TAG;
|
||||||
|
type->tp_version_tag = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
type->tp_flags &= ~Py_TPFLAGS_READY;
|
_PyStaticType_ClearWeakRefs(interp, type);
|
||||||
type->tp_flags &= ~Py_TPFLAGS_VALID_VERSION_TAG;
|
static_builtin_state_clear(interp, type);
|
||||||
type->tp_version_tag = 0;
|
/* We leave _Py_TPFLAGS_STATIC_BUILTIN set on tp_flags. */
|
||||||
|
|
||||||
if (type->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) {
|
|
||||||
_PyStaticType_ClearWeakRefs(type);
|
|
||||||
static_builtin_state_clear(type);
|
|
||||||
/* We leave _Py_TPFLAGS_STATIC_BUILTIN set on tp_flags. */
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -4564,7 +4569,8 @@ static PyObject *
|
||||||
lookup_subclasses(PyTypeObject *self)
|
lookup_subclasses(PyTypeObject *self)
|
||||||
{
|
{
|
||||||
if (self->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) {
|
if (self->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) {
|
||||||
static_builtin_state *state = _PyStaticType_GetState(self);
|
PyInterpreterState *interp = _PyInterpreterState_GET();
|
||||||
|
static_builtin_state *state = _PyStaticType_GetState(interp, self);
|
||||||
assert(state != NULL);
|
assert(state != NULL);
|
||||||
return state->tp_subclasses;
|
return state->tp_subclasses;
|
||||||
}
|
}
|
||||||
|
@ -4574,8 +4580,9 @@ lookup_subclasses(PyTypeObject *self)
|
||||||
int
|
int
|
||||||
_PyType_HasSubclasses(PyTypeObject *self)
|
_PyType_HasSubclasses(PyTypeObject *self)
|
||||||
{
|
{
|
||||||
|
PyInterpreterState *interp = _PyInterpreterState_GET();
|
||||||
if (self->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN &&
|
if (self->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN &&
|
||||||
_PyStaticType_GetState(self) == NULL) {
|
_PyStaticType_GetState(interp, self) == NULL) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (lookup_subclasses(self) == NULL) {
|
if (lookup_subclasses(self) == NULL) {
|
||||||
|
@ -6938,7 +6945,8 @@ type_ready_post_checks(PyTypeObject *type)
|
||||||
else if (type->tp_dictoffset < (Py_ssize_t)sizeof(PyObject)) {
|
else if (type->tp_dictoffset < (Py_ssize_t)sizeof(PyObject)) {
|
||||||
if (type->tp_dictoffset + type->tp_basicsize <= 0) {
|
if (type->tp_dictoffset + type->tp_basicsize <= 0) {
|
||||||
PyErr_Format(PyExc_SystemError,
|
PyErr_Format(PyExc_SystemError,
|
||||||
"type %s has a tp_dictoffset that is too small");
|
"type %s has a tp_dictoffset that is too small",
|
||||||
|
type->tp_name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -7029,17 +7037,32 @@ PyType_Ready(PyTypeObject *type)
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
_PyStaticType_InitBuiltin(PyTypeObject *self)
|
_PyStaticType_InitBuiltin(PyInterpreterState *interp, PyTypeObject *self)
|
||||||
{
|
{
|
||||||
assert(_Py_IsImmortal((PyObject *)self));
|
assert(_Py_IsImmortal((PyObject *)self));
|
||||||
assert(!(self->tp_flags & Py_TPFLAGS_HEAPTYPE));
|
assert(!(self->tp_flags & Py_TPFLAGS_HEAPTYPE));
|
||||||
|
assert(!(self->tp_flags & Py_TPFLAGS_MANAGED_DICT));
|
||||||
|
assert(!(self->tp_flags & Py_TPFLAGS_MANAGED_WEAKREF));
|
||||||
|
|
||||||
|
#ifndef NDEBUG
|
||||||
|
int ismain = _Py_IsMainInterpreter(interp);
|
||||||
|
#endif
|
||||||
if (self->tp_flags & Py_TPFLAGS_READY) {
|
if (self->tp_flags & Py_TPFLAGS_READY) {
|
||||||
|
assert(!ismain);
|
||||||
assert(self->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN);
|
assert(self->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN);
|
||||||
|
assert(self->tp_flags & Py_TPFLAGS_VALID_VERSION_TAG);
|
||||||
|
|
||||||
|
static_builtin_state_init(interp, self);
|
||||||
|
|
||||||
|
/* Per-interpreter tp_subclasses is done lazily.
|
||||||
|
Otherwise we would initialize it here. */
|
||||||
|
|
||||||
assert(_PyType_CheckConsistency(self));
|
assert(_PyType_CheckConsistency(self));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
assert(ismain);
|
||||||
|
|
||||||
self->tp_flags |= _Py_TPFLAGS_STATIC_BUILTIN;
|
self->tp_flags |= _Py_TPFLAGS_STATIC_BUILTIN;
|
||||||
self->tp_flags |= Py_TPFLAGS_IMMUTABLETYPE;
|
self->tp_flags |= Py_TPFLAGS_IMMUTABLETYPE;
|
||||||
|
|
||||||
|
@ -7047,11 +7070,11 @@ _PyStaticType_InitBuiltin(PyTypeObject *self)
|
||||||
self->tp_version_tag = NEXT_GLOBAL_VERSION_TAG++;
|
self->tp_version_tag = NEXT_GLOBAL_VERSION_TAG++;
|
||||||
self->tp_flags |= Py_TPFLAGS_VALID_VERSION_TAG;
|
self->tp_flags |= Py_TPFLAGS_VALID_VERSION_TAG;
|
||||||
|
|
||||||
static_builtin_state_init(self);
|
static_builtin_state_init(interp, self);
|
||||||
|
|
||||||
int res = type_ready(self);
|
int res = type_ready(self);
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
static_builtin_state_clear(self);
|
static_builtin_state_clear(interp, self);
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
@ -7065,7 +7088,8 @@ init_subclasses(PyTypeObject *self)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (self->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) {
|
if (self->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) {
|
||||||
static_builtin_state *state = _PyStaticType_GetState(self);
|
PyInterpreterState *interp = _PyInterpreterState_GET();
|
||||||
|
static_builtin_state *state = _PyStaticType_GetState(interp, self);
|
||||||
state->tp_subclasses = subclasses;
|
state->tp_subclasses = subclasses;
|
||||||
return subclasses;
|
return subclasses;
|
||||||
}
|
}
|
||||||
|
@ -7080,7 +7104,8 @@ clear_subclasses(PyTypeObject *self)
|
||||||
callers also test if tp_subclasses is NULL to check if a static type
|
callers also test if tp_subclasses is NULL to check if a static type
|
||||||
has no subclass. */
|
has no subclass. */
|
||||||
if (self->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) {
|
if (self->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) {
|
||||||
static_builtin_state *state = _PyStaticType_GetState(self);
|
PyInterpreterState *interp = _PyInterpreterState_GET();
|
||||||
|
static_builtin_state *state = _PyStaticType_GetState(interp, self);
|
||||||
Py_CLEAR(state->tp_subclasses);
|
Py_CLEAR(state->tp_subclasses);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -14573,13 +14573,13 @@ _PyUnicode_InitGlobalObjects(PyInterpreterState *interp)
|
||||||
PyStatus
|
PyStatus
|
||||||
_PyUnicode_InitTypes(PyInterpreterState *interp)
|
_PyUnicode_InitTypes(PyInterpreterState *interp)
|
||||||
{
|
{
|
||||||
if (_PyStaticType_InitBuiltin(&EncodingMapType) < 0) {
|
if (_PyStaticType_InitBuiltin(interp, &EncodingMapType) < 0) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
if (_PyStaticType_InitBuiltin(&PyFieldNameIter_Type) < 0) {
|
if (_PyStaticType_InitBuiltin(interp, &PyFieldNameIter_Type) < 0) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
if (_PyStaticType_InitBuiltin(&PyFormatterIter_Type) < 0) {
|
if (_PyStaticType_InitBuiltin(interp, &PyFormatterIter_Type) < 0) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
return _PyStatus_OK();
|
return _PyStatus_OK();
|
||||||
|
@ -15158,13 +15158,9 @@ unicode_is_finalizing(void)
|
||||||
void
|
void
|
||||||
_PyUnicode_FiniTypes(PyInterpreterState *interp)
|
_PyUnicode_FiniTypes(PyInterpreterState *interp)
|
||||||
{
|
{
|
||||||
if (!_Py_IsMainInterpreter(interp)) {
|
_PyStaticType_Dealloc(interp, &EncodingMapType);
|
||||||
return;
|
_PyStaticType_Dealloc(interp, &PyFieldNameIter_Type);
|
||||||
}
|
_PyStaticType_Dealloc(interp, &PyFormatterIter_Type);
|
||||||
|
|
||||||
_PyStaticType_Dealloc(&EncodingMapType);
|
|
||||||
_PyStaticType_Dealloc(&PyFieldNameIter_Type);
|
|
||||||
_PyStaticType_Dealloc(&PyFormatterIter_Type);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1017,9 +1017,9 @@ PyObject_ClearWeakRefs(PyObject *object)
|
||||||
* or anything else.
|
* or anything else.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
_PyStaticType_ClearWeakRefs(PyTypeObject *type)
|
_PyStaticType_ClearWeakRefs(PyInterpreterState *interp, PyTypeObject *type)
|
||||||
{
|
{
|
||||||
static_builtin_state *state = _PyStaticType_GetState(type);
|
static_builtin_state *state = _PyStaticType_GetState(interp, type);
|
||||||
PyObject **list = _PyStaticType_GET_WEAKREFS_LISTPTR(state);
|
PyObject **list = _PyStaticType_GET_WEAKREFS_LISTPTR(state);
|
||||||
while (*list != NULL) {
|
while (*list != NULL) {
|
||||||
/* Note that clear_weakref() pops the first ref off the type's
|
/* Note that clear_weakref() pops the first ref off the type's
|
||||||
|
|
|
@ -1342,8 +1342,9 @@ static PyStructSequence_Desc UnraisableHookArgs_desc = {
|
||||||
PyStatus
|
PyStatus
|
||||||
_PyErr_InitTypes(PyInterpreterState *interp)
|
_PyErr_InitTypes(PyInterpreterState *interp)
|
||||||
{
|
{
|
||||||
if (_PyStructSequence_InitBuiltin(&UnraisableHookArgsType,
|
if (_PyStructSequence_InitBuiltin(interp, &UnraisableHookArgsType,
|
||||||
&UnraisableHookArgs_desc) < 0) {
|
&UnraisableHookArgs_desc) < 0)
|
||||||
|
{
|
||||||
return _PyStatus_ERR("failed to initialize UnraisableHookArgs type");
|
return _PyStatus_ERR("failed to initialize UnraisableHookArgs type");
|
||||||
}
|
}
|
||||||
return _PyStatus_OK();
|
return _PyStatus_OK();
|
||||||
|
@ -1353,11 +1354,7 @@ _PyErr_InitTypes(PyInterpreterState *interp)
|
||||||
void
|
void
|
||||||
_PyErr_FiniTypes(PyInterpreterState *interp)
|
_PyErr_FiniTypes(PyInterpreterState *interp)
|
||||||
{
|
{
|
||||||
if (!_Py_IsMainInterpreter(interp)) {
|
_PyStructSequence_FiniBuiltin(interp, &UnraisableHookArgsType);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_PyStructSequence_FiniBuiltin(&UnraisableHookArgsType);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1663,8 +1663,10 @@ flush_std_files(void)
|
||||||
static void
|
static void
|
||||||
finalize_interp_types(PyInterpreterState *interp)
|
finalize_interp_types(PyInterpreterState *interp)
|
||||||
{
|
{
|
||||||
|
_PyIO_FiniTypes(interp);
|
||||||
|
|
||||||
_PyUnicode_FiniTypes(interp);
|
_PyUnicode_FiniTypes(interp);
|
||||||
_PySys_Fini(interp);
|
_PySys_FiniTypes(interp);
|
||||||
_PyExc_Fini(interp);
|
_PyExc_Fini(interp);
|
||||||
_PyAsyncGen_Fini(interp);
|
_PyAsyncGen_Fini(interp);
|
||||||
_PyContext_Fini(interp);
|
_PyContext_Fini(interp);
|
||||||
|
@ -1706,8 +1708,6 @@ finalize_interp_clear(PyThreadState *tstate)
|
||||||
/* Clear interpreter state and all thread states */
|
/* Clear interpreter state and all thread states */
|
||||||
_PyInterpreterState_Clear(tstate);
|
_PyInterpreterState_Clear(tstate);
|
||||||
|
|
||||||
_PyIO_FiniTypes(tstate->interp);
|
|
||||||
|
|
||||||
/* Clear all loghooks */
|
/* Clear all loghooks */
|
||||||
/* Both _PySys_Audit function and users still need PyObject, such as tuple.
|
/* Both _PySys_Audit function and users still need PyObject, such as tuple.
|
||||||
Call _PySys_ClearAuditHooks when PyObject available. */
|
Call _PySys_ClearAuditHooks when PyObject available. */
|
||||||
|
|
|
@ -3141,6 +3141,7 @@ _PySys_InitCore(PyThreadState *tstate, PyObject *sysdict)
|
||||||
{
|
{
|
||||||
PyObject *version_info;
|
PyObject *version_info;
|
||||||
int res;
|
int res;
|
||||||
|
PyInterpreterState *interp = tstate->interp;
|
||||||
|
|
||||||
/* stdin/stdout/stderr are set in pylifecycle.c */
|
/* stdin/stdout/stderr are set in pylifecycle.c */
|
||||||
|
|
||||||
|
@ -3166,7 +3167,9 @@ _PySys_InitCore(PyThreadState *tstate, PyObject *sysdict)
|
||||||
SET_SYS("float_info", PyFloat_GetInfo());
|
SET_SYS("float_info", PyFloat_GetInfo());
|
||||||
SET_SYS("int_info", PyLong_GetInfo());
|
SET_SYS("int_info", PyLong_GetInfo());
|
||||||
/* initialize hash_info */
|
/* initialize hash_info */
|
||||||
if (_PyStructSequence_InitBuiltin(&Hash_InfoType, &hash_info_desc) < 0) {
|
if (_PyStructSequence_InitBuiltin(interp, &Hash_InfoType,
|
||||||
|
&hash_info_desc) < 0)
|
||||||
|
{
|
||||||
goto type_init_failed;
|
goto type_init_failed;
|
||||||
}
|
}
|
||||||
SET_SYS("hash_info", get_hash_info(tstate));
|
SET_SYS("hash_info", get_hash_info(tstate));
|
||||||
|
@ -3190,7 +3193,7 @@ _PySys_InitCore(PyThreadState *tstate, PyObject *sysdict)
|
||||||
#define ENSURE_INFO_TYPE(TYPE, DESC) \
|
#define ENSURE_INFO_TYPE(TYPE, DESC) \
|
||||||
do { \
|
do { \
|
||||||
if (_PyStructSequence_InitBuiltinWithFlags( \
|
if (_PyStructSequence_InitBuiltinWithFlags( \
|
||||||
&TYPE, &DESC, Py_TPFLAGS_DISALLOW_INSTANTIATION) < 0) { \
|
interp, &TYPE, &DESC, Py_TPFLAGS_DISALLOW_INSTANTIATION) < 0) { \
|
||||||
goto type_init_failed; \
|
goto type_init_failed; \
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
@ -3226,8 +3229,9 @@ _PySys_InitCore(PyThreadState *tstate, PyObject *sysdict)
|
||||||
SET_SYS("thread_info", PyThread_GetInfo());
|
SET_SYS("thread_info", PyThread_GetInfo());
|
||||||
|
|
||||||
/* initialize asyncgen_hooks */
|
/* initialize asyncgen_hooks */
|
||||||
if (_PyStructSequence_InitBuiltin(
|
if (_PyStructSequence_InitBuiltin(interp, &AsyncGenHooksType,
|
||||||
&AsyncGenHooksType, &asyncgen_hooks_desc) < 0) {
|
&asyncgen_hooks_desc) < 0)
|
||||||
|
{
|
||||||
goto type_init_failed;
|
goto type_init_failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3489,20 +3493,20 @@ error:
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
_PySys_Fini(PyInterpreterState *interp)
|
_PySys_FiniTypes(PyInterpreterState *interp)
|
||||||
{
|
{
|
||||||
if (_Py_IsMainInterpreter(interp)) {
|
_PyStructSequence_FiniBuiltin(interp, &VersionInfoType);
|
||||||
_PyStructSequence_FiniBuiltin(&VersionInfoType);
|
_PyStructSequence_FiniBuiltin(interp, &FlagsType);
|
||||||
_PyStructSequence_FiniBuiltin(&FlagsType);
|
|
||||||
#if defined(MS_WINDOWS)
|
#if defined(MS_WINDOWS)
|
||||||
_PyStructSequence_FiniBuiltin(&WindowsVersionType);
|
_PyStructSequence_FiniBuiltin(interp, &WindowsVersionType);
|
||||||
#endif
|
#endif
|
||||||
_PyStructSequence_FiniBuiltin(&Hash_InfoType);
|
_PyStructSequence_FiniBuiltin(interp, &Hash_InfoType);
|
||||||
_PyStructSequence_FiniBuiltin(&AsyncGenHooksType);
|
_PyStructSequence_FiniBuiltin(interp, &AsyncGenHooksType);
|
||||||
#ifdef __EMSCRIPTEN__
|
#ifdef __EMSCRIPTEN__
|
||||||
|
if (_Py_IsMainInterpreter(interp)) {
|
||||||
Py_CLEAR(EmscriptenInfoType);
|
Py_CLEAR(EmscriptenInfoType);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -137,7 +137,8 @@ PyThread_GetInfo(void)
|
||||||
int len;
|
int len;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (_PyStructSequence_InitBuiltin(&ThreadInfoType, &threadinfo_desc) < 0) {
|
PyInterpreterState *interp = _PyInterpreterState_GET();
|
||||||
|
if (_PyStructSequence_InitBuiltin(interp, &ThreadInfoType, &threadinfo_desc) < 0) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -191,9 +192,5 @@ PyThread_GetInfo(void)
|
||||||
void
|
void
|
||||||
_PyThread_FiniType(PyInterpreterState *interp)
|
_PyThread_FiniType(PyInterpreterState *interp)
|
||||||
{
|
{
|
||||||
if (!_Py_IsMainInterpreter(interp)) {
|
_PyStructSequence_FiniBuiltin(interp, &ThreadInfoType);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_PyStructSequence_FiniBuiltin(&ThreadInfoType);
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue