]> granicus.if.org Git - python/commitdiff
Issue #10241: Clear extension module dict copies at interpreter shutdown.
authorAntoine Pitrou <solipsis@pitrou.net>
Thu, 1 Aug 2013 20:07:06 +0000 (22:07 +0200)
committerAntoine Pitrou <solipsis@pitrou.net>
Thu, 1 Aug 2013 20:07:06 +0000 (22:07 +0200)
Patch by Neil Schemenauer, minimally modified.

Include/pystate.h
Misc/NEWS
Python/import.c
Python/pystate.c

index cd1d7765be0c9dfb3c4febf2ee91c9ee1b220af1..e41fe4c0d5f085fdd2dfc7b0b73704ce6ee1d187 100644 (file)
@@ -134,6 +134,9 @@ PyAPI_FUNC(int) PyState_AddModule(PyObject*, struct PyModuleDef*);
 PyAPI_FUNC(int) PyState_RemoveModule(struct PyModuleDef*);
 #endif
 PyAPI_FUNC(PyObject*) PyState_FindModule(struct PyModuleDef*);
+#ifndef Py_LIMITED_API
+PyAPI_FUNC(void) _PyState_ClearModules(void);
+#endif
 
 PyAPI_FUNC(PyThreadState *) PyThreadState_New(PyInterpreterState *);
 PyAPI_FUNC(PyThreadState *) _PyThreadState_Prealloc(PyInterpreterState *);
index e6bbd30fa9d0d94cf834985947cb732b7f27bfd1..2491ef17e5d769e733cff762fd150dd550cf3a0e 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -10,6 +10,9 @@ What's New in Python 3.4.0 Alpha 1?
 Core and Builtins
 -----------------
 
+- Issue #10241: Clear extension module dict copies at interpreter shutdown.
+  Patch by Neil Schemenauer, minimally modified.
+
 - Issue #9035: ismount now recognises volumes mounted below a drive root
   on Windows. Original patch by Atsuo Ishimoto.
 
index 09106555a3b87494cf9de2f8d403cbba8cddb279..ce09ebedd4915308b861ec69a4d39b783197ab01 100644 (file)
@@ -380,6 +380,8 @@ PyImport_Cleanup(void)
     builtins = interp->builtins;
     interp->builtins = PyDict_New();
     Py_DECREF(builtins);
+    /* Clear module dict copies stored in the interpreter state */
+    _PyState_ClearModules();
     /* Collect references */
     _PyGC_CollectNoFail();
     /* Dump GC stats before it's too late, since it uses the warnings
index 40606bf1ca71f7457801dbce434b82d8d9c65cfa..924b6a29090644218a876d0ace68ba074a776fdc 100644 (file)
@@ -320,6 +320,31 @@ PyState_RemoveModule(struct PyModuleDef* def)
     return PyList_SetItem(state->modules_by_index, index, Py_None);
 }
 
+/* used by import.c:PyImport_Cleanup */
+void
+_PyState_ClearModules(void)
+{
+    PyInterpreterState *state = PyThreadState_GET()->interp;
+    if (state->modules_by_index) {
+        Py_ssize_t i;
+        for (i = 0; i < PyList_GET_SIZE(state->modules_by_index); i++) {
+            PyObject *m = PyList_GET_ITEM(state->modules_by_index, i);
+            if (PyModule_Check(m)) {
+                /* cleanup the saved copy of module dicts */
+                PyModuleDef *md = PyModule_GetDef(m);
+                if (md)
+                    Py_CLEAR(md->m_base.m_copy);
+            }
+        }
+        /* Setting modules_by_index to NULL could be dangerous, so we
+           clear the list instead. */
+        if (PyList_SetSlice(state->modules_by_index,
+                            0, PyList_GET_SIZE(state->modules_by_index),
+                            NULL))
+            PyErr_WriteUnraisable(state->modules_by_index);
+    }
+}
+
 void
 PyThreadState_Clear(PyThreadState *tstate)
 {