@@ -1546,6 +1546,10 @@ static PyObject*
15461546finalize_remove_modules (PyObject * modules , int verbose )
15471547{
15481548 PyObject * weaklist = PyList_New (0 );
1549+ PyObject * weak_ext = PyList_New (0 ); // for extending the weaklist
1550+ if (weak_ext == NULL ) {
1551+ Py_CLEAR (weaklist );
1552+ }
15491553 if (weaklist == NULL ) {
15501554 PyErr_FormatUnraisable ("Exception ignored while removing modules" );
15511555 }
@@ -1554,17 +1558,19 @@ finalize_remove_modules(PyObject *modules, int verbose)
15541558 if (weaklist != NULL) { \
15551559 PyObject *wr = PyWeakref_NewRef(mod, NULL); \
15561560 if (wr) { \
1557- if (Py_REFCNT(wr) > 1) { \
1561+ PyObject *list = Py_REFCNT(wr) <= 1 ? weaklist : weak_ext; \
1562+ PyObject *tup = PyTuple_Pack(2, name, wr); \
1563+ if (!tup || PyList_Append(list, tup) < 0) { \
1564+ PyErr_FormatUnraisable("Exception ignored while removing modules"); \
1565+ } \
1566+ if (list == weak_ext) { \
15581567 /* gh-132413: When the weakref is already used elsewhere,
15591568 * finalize_modules_clear_weaklist() rather than the GC
15601569 * should clear the referenced module since the GC tries
1561- * to clear the wrakref first. */ \
1570+ * to clear the wrakref first. The weaklist requires the
1571+ * order in which such modules are cleared first. */ \
15621572 _PyObject_GC_UNTRACK (mod ); \
15631573 } \
1564- PyObject * tup = PyTuple_Pack (2 , name , wr ); \
1565- if (!tup || PyList_Append (weaklist , tup ) < 0 ) { \
1566- PyErr_FormatUnraisable ("Exception ignored while removing modules" ); \
1567- } \
15681574 Py_XDECREF (tup ); \
15691575 Py_DECREF (wr ); \
15701576 } \
@@ -1614,6 +1620,12 @@ finalize_remove_modules(PyObject *modules, int verbose)
16141620 Py_DECREF (iterator );
16151621 }
16161622 }
1623+
1624+ if (PyList_Extend (weaklist , weak_ext ) < 0 ) {
1625+ PyErr_FormatUnraisable ("Exception ignored while removing modules" );
1626+ }
1627+ Py_DECREF (weak_ext );
1628+
16171629#undef CLEAR_MODULE
16181630#undef STORE_MODULE_WEAKREF
16191631
0 commit comments