bpo-46417: Clear Unicode static types at exit (GH-30806)

Add _PyUnicode_FiniTypes() function, called by
finalize_interp_types(). It clears these static types:

* EncodingMapType
* PyFieldNameIter_Type
* PyFormatterIter_Type

_PyStaticType_Dealloc() now does nothing if tp_subclasses
is not NULL.
This commit is contained in:
Victor Stinner 2022-01-22 22:55:39 +01:00 committed by GitHub
parent 621a45ccac
commit 1626bf4ac7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 25 additions and 22 deletions

View File

@ -17,6 +17,7 @@ extern void _PyUnicode_InitState(PyInterpreterState *);
extern PyStatus _PyUnicode_InitGlobalObjects(PyInterpreterState *); extern PyStatus _PyUnicode_InitGlobalObjects(PyInterpreterState *);
extern PyStatus _PyUnicode_InitTypes(PyInterpreterState *); extern PyStatus _PyUnicode_InitTypes(PyInterpreterState *);
extern void _PyUnicode_Fini(PyInterpreterState *); extern void _PyUnicode_Fini(PyInterpreterState *);
extern void _PyUnicode_FiniTypes(PyInterpreterState *);
/* other API */ /* other API */

View File

@ -3545,12 +3545,6 @@ _PyExc_FiniTypes(PyInterpreterState *interp)
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;
// Cannot delete a type if it still has subclasses
if (exc->tp_subclasses != NULL) {
continue;
}
_PyStaticType_Dealloc(exc); _PyStaticType_Dealloc(exc);
} }
} }

View File

@ -1994,10 +1994,6 @@ _PyTypes_FiniTypes(PyInterpreterState *interp)
// 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];
// Cannot delete a type if it still has subclasses
if (type->tp_subclasses != NULL) {
continue;
}
_PyStaticType_Dealloc(type); _PyStaticType_Dealloc(type);
} }
} }

View File

@ -4079,10 +4079,12 @@ type_dealloc_common(PyTypeObject *type)
void void
_PyStaticType_Dealloc(PyTypeObject *type) _PyStaticType_Dealloc(PyTypeObject *type)
{ {
// _PyStaticType_Dealloc() must not be called if a type has subtypes. // If a type still has subtypes, it cannot be deallocated.
// A subtype can inherit attributes and methods of its parent type, // A subtype can inherit attributes and methods of its parent type,
// and a type must no longer be used once it's deallocated. // and a type must no longer be used once it's deallocated.
assert(type->tp_subclasses == NULL); if (type->tp_subclasses != NULL) {
return;
}
type_dealloc_common(type); type_dealloc_common(type);

View File

@ -15567,23 +15567,19 @@ _PyUnicode_InitTypes(PyInterpreterState *interp)
return _PyStatus_OK(); return _PyStatus_OK();
} }
if (PyType_Ready(&PyUnicode_Type) < 0) {
return _PyStatus_ERR("Can't initialize unicode type");
}
if (PyType_Ready(&PyUnicodeIter_Type) < 0) {
return _PyStatus_ERR("Can't initialize unicode iterator type");
}
if (PyType_Ready(&EncodingMapType) < 0) { if (PyType_Ready(&EncodingMapType) < 0) {
return _PyStatus_ERR("Can't initialize encoding map type"); goto error;
} }
if (PyType_Ready(&PyFieldNameIter_Type) < 0) { if (PyType_Ready(&PyFieldNameIter_Type) < 0) {
return _PyStatus_ERR("Can't initialize field name iterator type"); goto error;
} }
if (PyType_Ready(&PyFormatterIter_Type) < 0) { if (PyType_Ready(&PyFormatterIter_Type) < 0) {
return _PyStatus_ERR("Can't initialize formatter iter type"); goto error;
} }
return _PyStatus_OK(); return _PyStatus_OK();
error:
return _PyStatus_ERR("Can't initialize unicode types");
} }
@ -16111,6 +16107,19 @@ unicode_is_finalizing(void)
#endif #endif
void
_PyUnicode_FiniTypes(PyInterpreterState *interp)
{
if (!_Py_IsMainInterpreter(interp)) {
return;
}
_PyStaticType_Dealloc(&EncodingMapType);
_PyStaticType_Dealloc(&PyFieldNameIter_Type);
_PyStaticType_Dealloc(&PyFormatterIter_Type);
}
void void
_PyUnicode_Fini(PyInterpreterState *interp) _PyUnicode_Fini(PyInterpreterState *interp)
{ {

View File

@ -1664,6 +1664,7 @@ flush_std_files(void)
static void static void
finalize_interp_types(PyInterpreterState *interp) finalize_interp_types(PyInterpreterState *interp)
{ {
_PyUnicode_FiniTypes(interp);
_PySys_Fini(interp); _PySys_Fini(interp);
_PyExc_Fini(interp); _PyExc_Fini(interp);
_PyFrame_Fini(interp); _PyFrame_Fini(interp);