diff options
author | Collin Winter <collinw@gmail.com> | 2007-03-12 16:11:39 (GMT) |
---|---|---|
committer | Collin Winter <collinw@gmail.com> | 2007-03-12 16:11:39 (GMT) |
commit | 276887b16dc86e3423760c6ed9353591708fba17 (patch) | |
tree | 04e9896ffc00c0291959b4be71a83273e790b4ad /Python/import.c | |
parent | f567ca3e1ae851ea6e7418da3df47e034841a08d (diff) | |
download | cpython-276887b16dc86e3423760c6ed9353591708fba17.zip cpython-276887b16dc86e3423760c6ed9353591708fba17.tar.gz cpython-276887b16dc86e3423760c6ed9353591708fba17.tar.bz2 |
Bug #742342: make Python stop segfaulting on infinitely-recursive reload()s. Fixed by patch #922167.
Will backport.
Diffstat (limited to 'Python/import.c')
-rw-r--r-- | Python/import.c | 37 |
1 files changed, 35 insertions, 2 deletions
diff --git a/Python/import.c b/Python/import.c index db39cc4..d7f012a 100644 --- a/Python/import.c +++ b/Python/import.c @@ -340,6 +340,25 @@ imp_release_lock(PyObject *self, PyObject *noargs) return Py_None; } +PyObject * +PyImport_GetModulesReloading(void) +{ + PyInterpreterState *interp = PyThreadState_Get()->interp; + if (interp->modules_reloading == NULL) + Py_FatalError("PyImport_GetModuleDict: no modules_reloading dictionary!"); + return interp->modules_reloading; +} + +static void +imp_modules_reloading_clear (void) +{ + PyInterpreterState *interp = PyThreadState_Get()->interp; + if (interp->modules_reloading == NULL) + return; + PyDict_Clear(interp->modules_reloading); + return; +} + /* Helper for sys */ PyObject * @@ -499,6 +518,7 @@ PyImport_Cleanup(void) PyDict_Clear(modules); interp->modules = NULL; Py_DECREF(modules); + Py_CLEAR(interp->modules_reloading); } @@ -2401,8 +2421,9 @@ import_submodule(PyObject *mod, char *subname, char *fullname) PyObject * PyImport_ReloadModule(PyObject *m) { + PyObject *modules_reloading = PyImport_GetModulesReloading(); PyObject *modules = PyImport_GetModuleDict(); - PyObject *path = NULL, *loader = NULL; + PyObject *path = NULL, *loader = NULL, *existing_m = NULL; char *name, *subname; char buf[MAXPATHLEN+1]; struct filedescr *fdp; @@ -2423,20 +2444,30 @@ PyImport_ReloadModule(PyObject *m) name); return NULL; } + if ((existing_m = PyDict_GetItemString(modules_reloading, name)) != NULL) { + /* Due to a recursive reload, this module is already being reloaded. */ + Py_INCREF(existing_m); + return existing_m; + } + PyDict_SetItemString(modules_reloading, name, m); + subname = strrchr(name, '.'); if (subname == NULL) subname = name; else { PyObject *parentname, *parent; parentname = PyString_FromStringAndSize(name, (subname-name)); - if (parentname == NULL) + if (parentname == NULL) { + imp_modules_reloading_clear(); return NULL; + } parent = PyDict_GetItem(modules, parentname); if (parent == NULL) { PyErr_Format(PyExc_ImportError, "reload(): parent %.200s not in sys.modules", PyString_AS_STRING(parentname)); Py_DECREF(parentname); + imp_modules_reloading_clear(); return NULL; } Py_DECREF(parentname); @@ -2451,6 +2482,7 @@ PyImport_ReloadModule(PyObject *m) if (fdp == NULL) { Py_XDECREF(loader); + imp_modules_reloading_clear(); return NULL; } @@ -2467,6 +2499,7 @@ PyImport_ReloadModule(PyObject *m) */ PyDict_SetItemString(modules, name, m); } + imp_modules_reloading_clear (); return newm; } |