From: Antoine Pitrou Date: Thu, 1 Aug 2013 20:07:06 +0000 (+0200) Subject: Issue #10241: Clear extension module dict copies at interpreter shutdown. X-Git-Tag: v3.4.0a1~19 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=84f31a567627bc69204caf2d801a63c7f96207eb;p=python Issue #10241: Clear extension module dict copies at interpreter shutdown. Patch by Neil Schemenauer, minimally modified. --- diff --git a/Include/pystate.h b/Include/pystate.h index cd1d7765be..e41fe4c0d5 100644 --- a/Include/pystate.h +++ b/Include/pystate.h @@ -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 *); diff --git a/Misc/NEWS b/Misc/NEWS index e6bbd30fa9..2491ef17e5 100644 --- 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. diff --git a/Python/import.c b/Python/import.c index 09106555a3..ce09ebedd4 100644 --- a/Python/import.c +++ b/Python/import.c @@ -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 diff --git a/Python/pystate.c b/Python/pystate.c index 40606bf1ca..924b6a2909 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -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) {