Skip to content

Commit 1626bf4

Browse files
authored
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.
1 parent 621a45c commit 1626bf4

File tree

6 files changed

+25
-22
lines changed

6 files changed

+25
-22
lines changed

Include/internal/pycore_unicodeobject.h

+1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ extern void _PyUnicode_InitState(PyInterpreterState *);
1717
extern PyStatus _PyUnicode_InitGlobalObjects(PyInterpreterState *);
1818
extern PyStatus _PyUnicode_InitTypes(PyInterpreterState *);
1919
extern void _PyUnicode_Fini(PyInterpreterState *);
20+
extern void _PyUnicode_FiniTypes(PyInterpreterState *);
2021

2122

2223
/* other API */

Objects/exceptions.c

-6
Original file line numberDiff line numberDiff line change
@@ -3545,12 +3545,6 @@ _PyExc_FiniTypes(PyInterpreterState *interp)
35453545

35463546
for (Py_ssize_t i=Py_ARRAY_LENGTH(static_exceptions) - 1; i >= 0; i--) {
35473547
PyTypeObject *exc = static_exceptions[i].exc;
3548-
3549-
// Cannot delete a type if it still has subclasses
3550-
if (exc->tp_subclasses != NULL) {
3551-
continue;
3552-
}
3553-
35543548
_PyStaticType_Dealloc(exc);
35553549
}
35563550
}

Objects/object.c

-4
Original file line numberDiff line numberDiff line change
@@ -1994,10 +1994,6 @@ _PyTypes_FiniTypes(PyInterpreterState *interp)
19941994
// their base classes.
19951995
for (Py_ssize_t i=Py_ARRAY_LENGTH(static_types)-1; i>=0; i--) {
19961996
PyTypeObject *type = static_types[i];
1997-
// Cannot delete a type if it still has subclasses
1998-
if (type->tp_subclasses != NULL) {
1999-
continue;
2000-
}
20011997
_PyStaticType_Dealloc(type);
20021998
}
20031999
}

Objects/typeobject.c

+4-2
Original file line numberDiff line numberDiff line change
@@ -4079,10 +4079,12 @@ type_dealloc_common(PyTypeObject *type)
40794079
void
40804080
_PyStaticType_Dealloc(PyTypeObject *type)
40814081
{
4082-
// _PyStaticType_Dealloc() must not be called if a type has subtypes.
4082+
// If a type still has subtypes, it cannot be deallocated.
40834083
// A subtype can inherit attributes and methods of its parent type,
40844084
// and a type must no longer be used once it's deallocated.
4085-
assert(type->tp_subclasses == NULL);
4085+
if (type->tp_subclasses != NULL) {
4086+
return;
4087+
}
40864088

40874089
type_dealloc_common(type);
40884090

Objects/unicodeobject.c

+19-10
Original file line numberDiff line numberDiff line change
@@ -15567,23 +15567,19 @@ _PyUnicode_InitTypes(PyInterpreterState *interp)
1556715567
return _PyStatus_OK();
1556815568
}
1556915569

15570-
if (PyType_Ready(&PyUnicode_Type) < 0) {
15571-
return _PyStatus_ERR("Can't initialize unicode type");
15572-
}
15573-
if (PyType_Ready(&PyUnicodeIter_Type) < 0) {
15574-
return _PyStatus_ERR("Can't initialize unicode iterator type");
15575-
}
15576-
1557715570
if (PyType_Ready(&EncodingMapType) < 0) {
15578-
return _PyStatus_ERR("Can't initialize encoding map type");
15571+
goto error;
1557915572
}
1558015573
if (PyType_Ready(&PyFieldNameIter_Type) < 0) {
15581-
return _PyStatus_ERR("Can't initialize field name iterator type");
15574+
goto error;
1558215575
}
1558315576
if (PyType_Ready(&PyFormatterIter_Type) < 0) {
15584-
return _PyStatus_ERR("Can't initialize formatter iter type");
15577+
goto error;
1558515578
}
1558615579
return _PyStatus_OK();
15580+
15581+
error:
15582+
return _PyStatus_ERR("Can't initialize unicode types");
1558715583
}
1558815584

1558915585

@@ -16111,6 +16107,19 @@ unicode_is_finalizing(void)
1611116107
#endif
1611216108

1611316109

16110+
void
16111+
_PyUnicode_FiniTypes(PyInterpreterState *interp)
16112+
{
16113+
if (!_Py_IsMainInterpreter(interp)) {
16114+
return;
16115+
}
16116+
16117+
_PyStaticType_Dealloc(&EncodingMapType);
16118+
_PyStaticType_Dealloc(&PyFieldNameIter_Type);
16119+
_PyStaticType_Dealloc(&PyFormatterIter_Type);
16120+
}
16121+
16122+
1611416123
void
1611516124
_PyUnicode_Fini(PyInterpreterState *interp)
1611616125
{

Python/pylifecycle.c

+1
Original file line numberDiff line numberDiff line change
@@ -1664,6 +1664,7 @@ flush_std_files(void)
16641664
static void
16651665
finalize_interp_types(PyInterpreterState *interp)
16661666
{
1667+
_PyUnicode_FiniTypes(interp);
16671668
_PySys_Fini(interp);
16681669
_PyExc_Fini(interp);
16691670
_PyFrame_Fini(interp);

0 commit comments

Comments
 (0)