bpo-38858: Factorize Py_EndInterpreter() code (GH-17273) · python/cpython@7eee5be
@@ -1161,6 +1161,78 @@ flush_std_files(void)
1161116111621162*/
116311631164+1165+static void
1166+finalize_interp_types(PyThreadState *tstate, int is_main_interp)
1167+{
1168+if (is_main_interp) {
1169+/* Sundry finalizers */
1170+_PyMethod_Fini();
1171+_PyFrame_Fini();
1172+_PyCFunction_Fini();
1173+_PyTuple_Fini();
1174+_PyList_Fini();
1175+_PySet_Fini();
1176+_PyBytes_Fini();
1177+_PyLong_Fini();
1178+_PyFloat_Fini();
1179+_PyDict_Fini();
1180+_PySlice_Fini();
1181+ }
1182+1183+_PyWarnings_Fini(tstate->interp);
1184+1185+if (is_main_interp) {
1186+_Py_HashRandomization_Fini();
1187+_PyArg_Fini();
1188+_PyAsyncGen_Fini();
1189+_PyContext_Fini();
1190+1191+/* Cleanup Unicode implementation */
1192+_PyUnicode_Fini();
1193+_Py_ClearFileSystemEncoding();
1194+ }
1195+}
1196+1197+1198+static void
1199+finalize_interp_clear(PyThreadState *tstate, int is_main_interp)
1200+{
1201+/* Clear interpreter state and all thread states */
1202+PyInterpreterState_Clear(tstate->interp);
1203+1204+finalize_interp_types(tstate, is_main_interp);
1205+1206+if (is_main_interp) {
1207+/* XXX Still allocated:
1208+ - various static ad-hoc pointers to interned strings
1209+ - int and float free list blocks
1210+ - whatever various modules and libraries allocate
1211+ */
1212+1213+PyGrammar_RemoveAccelerators(&_PyParser_Grammar);
1214+1215+_PyExc_Fini();
1216+_PyGC_Fini(tstate);
1217+ }
1218+}
1219+1220+1221+static void
1222+finalize_interp_delete(PyThreadState *tstate, int is_main_interp)
1223+{
1224+if (is_main_interp) {
1225+/* Cleanup auto-thread-state */
1226+_PyGILState_Fini(tstate);
1227+ }
1228+1229+/* Delete current thread. After this, many C API calls become crashy. */
1230+PyThreadState_Swap(NULL);
1231+1232+PyInterpreterState_Delete(tstate->interp);
1233+}
1234+1235+11641236int
11651237Py_FinalizeEx(void)
11661238{
@@ -1314,56 +1386,9 @@ Py_FinalizeEx(void)
13141386 }
13151387#endif /* Py_TRACE_REFS */
131613881317-/* Clear interpreter state and all thread states. */
1318-PyInterpreterState_Clear(interp);
1389+finalize_interp_clear(tstate, 1);
131913901320-/* Now we decref the exception classes. After this point nothing
1321- can raise an exception. That's okay, because each Fini() method
1322- below has been checked to make sure no exceptions are ever
1323- raised.
1324- */
1325-1326-_PyExc_Fini();
1327-1328-/* Sundry finalizers */
1329-_PyMethod_Fini();
1330-_PyFrame_Fini();
1331-_PyCFunction_Fini();
1332-_PyTuple_Fini();
1333-_PyList_Fini();
1334-_PySet_Fini();
1335-_PyBytes_Fini();
1336-_PyLong_Fini();
1337-_PyFloat_Fini();
1338-_PyDict_Fini();
1339-_PySlice_Fini();
1340-_PyGC_Fini(runtime);
1341-_PyWarnings_Fini(interp);
1342-_Py_HashRandomization_Fini();
1343-_PyArg_Fini();
1344-_PyAsyncGen_Fini();
1345-_PyContext_Fini();
1346-1347-/* Cleanup Unicode implementation */
1348-_PyUnicode_Fini();
1349-1350-_Py_ClearFileSystemEncoding();
1351-1352-/* XXX Still allocated:
1353- - various static ad-hoc pointers to interned strings
1354- - int and float free list blocks
1355- - whatever various modules and libraries allocate
1356- */
1357-1358-PyGrammar_RemoveAccelerators(&_PyParser_Grammar);
1359-1360-/* Cleanup auto-thread-state */
1361-_PyGILState_Fini(runtime);
1362-1363-/* Delete current thread. After this, many C API calls become crashy. */
1364-PyThreadState_Swap(NULL);
1365-1366-PyInterpreterState_Delete(interp);
1391+finalize_interp_delete(tstate, 1);
1367139213681393#ifdef Py_TRACE_REFS
13691394/* Display addresses (& refcnts) of all objects still alive.
@@ -1607,9 +1632,8 @@ Py_EndInterpreter(PyThreadState *tstate)
16071632 }
1608163316091634_PyImport_Cleanup(tstate);
1610-PyInterpreterState_Clear(interp);
1611-PyThreadState_Swap(NULL);
1612-PyInterpreterState_Delete(interp);
1635+finalize_interp_clear(tstate, 0);
1636+finalize_interp_delete(tstate, 0);
16131637}
1614163816151639/* Add the __main__ module */