summaryrefslogtreecommitdiffstats
path: root/Python/import.c
diff options
context:
space:
mode:
Diffstat (limited to 'Python/import.c')
-rw-r--r--Python/import.c39
1 files changed, 36 insertions, 3 deletions
diff --git a/Python/import.c b/Python/import.c
index 6d65703..2350800 100644
--- a/Python/import.c
+++ b/Python/import.c
@@ -4,6 +4,7 @@
#include "Python.h"
#include "Python-ast.h"
+#undef Yield /* undefine macro conflicting with winbase.h */
#include "pyarena.h"
#include "pythonrun.h"
#include "errcode.h"
@@ -347,6 +348,14 @@ imp_release_lock(PyObject *self, PyObject *noargs)
return Py_None;
}
+static void
+imp_modules_reloading_clear(void)
+{
+ PyInterpreterState *interp = PyThreadState_Get()->interp;
+ if (interp->modules_reloading != NULL)
+ PyDict_Clear(interp->modules_reloading);
+}
+
/* Helper for sys */
PyObject *
@@ -506,6 +515,7 @@ PyImport_Cleanup(void)
PyDict_Clear(modules);
interp->modules = NULL;
Py_DECREF(modules);
+ Py_CLEAR(interp->modules_reloading);
}
@@ -2408,13 +2418,21 @@ import_submodule(PyObject *mod, char *subname, char *fullname)
PyObject *
PyImport_ReloadModule(PyObject *m)
{
+ PyInterpreterState *interp = PyThreadState_Get()->interp;
+ PyObject *modules_reloading = interp->modules_reloading;
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;
FILE *fp = NULL;
PyObject *newm;
+
+ if (modules_reloading == NULL) {
+ Py_FatalError("PyImport_ReloadModule: "
+ "no modules_reloading dictionary!");
+ return NULL;
+ }
if (m == NULL || !PyModule_Check(m)) {
PyErr_SetString(PyExc_TypeError,
@@ -2430,20 +2448,33 @@ PyImport_ReloadModule(PyObject *m)
name);
return NULL;
}
+ existing_m = PyDict_GetItemString(modules_reloading, name);
+ if (existing_m != NULL) {
+ /* Due to a recursive reload, this module is already
+ being reloaded. */
+ Py_INCREF(existing_m);
+ return existing_m;
+ }
+ if (PyDict_SetItemString(modules_reloading, name, m) < 0)
+ return NULL;
+
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);
@@ -2458,6 +2489,7 @@ PyImport_ReloadModule(PyObject *m)
if (fdp == NULL) {
Py_XDECREF(loader);
+ imp_modules_reloading_clear();
return NULL;
}
@@ -2474,6 +2506,7 @@ PyImport_ReloadModule(PyObject *m)
*/
PyDict_SetItemString(modules, name, m);
}
+ imp_modules_reloading_clear();
return newm;
}
@@ -2543,7 +2576,7 @@ PyImport_Import(PyObject *module_name)
if (import == NULL)
goto err;
- /* Call the _import__ function with the proper argument list */
+ /* Call the __import__ function with the proper argument list */
r = PyObject_CallFunctionObjArgs(import, module_name, globals,
globals, silly_list, NULL);