[Python-checkins] cpython: Issue #13959: Simplify imp.reload() by relying on a module's

brett.cannon python-checkins at python.org
Sun Apr 15 23:56:19 CEST 2012


http://hg.python.org/cpython/rev/4dce3afc392c
changeset:   76333:4dce3afc392c
user:        Brett Cannon <brett at python.org>
date:        Sun Apr 15 17:56:09 2012 -0400
summary:
  Issue #13959: Simplify imp.reload() by relying on a module's
__loader__.

Since import now sets __loader__ on all modules it creates and
imp.reload() already relied on the attribute for modules that import
didn't create, the only potential compatibility issue is if people
were deleting the attribute on modules and expecting imp.reload() to
continue to work.

files:
  Misc/NEWS       |   3 ++
  Python/import.c |  46 ++++++++----------------------------
  2 files changed, 14 insertions(+), 35 deletions(-)


diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -32,6 +32,9 @@
 Library
 -------
 
+- Issue #13959: Make imp.reload() always use a module's __loader__ to perform
+  the reload.
+
 - Issue #13959: Add imp.py and rename the built-in module to _imp, allowing for
   re-implementing parts of the module in pure Python.
 
diff --git a/Python/import.c b/Python/import.c
--- a/Python/import.c
+++ b/Python/import.c
@@ -153,7 +153,6 @@
 };
 
 static PyObject *initstr = NULL;
-_Py_IDENTIFIER(__path__);
 
 /* Initialize things */
 
@@ -3106,12 +3105,12 @@
     PyInterpreterState *interp = PyThreadState_Get()->interp;
     PyObject *modules_reloading = interp->modules_reloading;
     PyObject *modules = PyImport_GetModuleDict();
-    PyObject *path_list = NULL, *loader = NULL, *existing_m = NULL;
-    PyObject *name, *bufobj, *subname;
+    PyObject *loader = NULL, *existing_m = NULL;
+    PyObject *name;
     Py_ssize_t subname_start;
-    struct filedescr *fdp;
-    FILE *fp = NULL;
     PyObject *newm = NULL;
+    _Py_IDENTIFIER(__loader__);
+    _Py_IDENTIFIER(load_module);
 
     if (modules_reloading == NULL) {
         Py_FatalError("PyImport_ReloadModule: "
@@ -3149,51 +3148,28 @@
 
     subname_start = PyUnicode_FindChar(name, '.', 0,
                                        PyUnicode_GET_LENGTH(name), -1);
-    if (subname_start == -1) {
-        Py_INCREF(name);
-        subname = name;
-    }
-    else {
+    if (subname_start != -1) {
         PyObject *parentname, *parent;
-        Py_ssize_t len;
         parentname = PyUnicode_Substring(name, 0, subname_start);
         if (parentname == NULL) {
             goto error;
         }
         parent = PyDict_GetItem(modules, parentname);
+        Py_XDECREF(parent);
         if (parent == NULL) {
             PyErr_Format(PyExc_ImportError,
                 "reload(): parent %R not in sys.modules",
                  parentname);
-            Py_DECREF(parentname);
             goto error;
         }
-        Py_DECREF(parentname);
-        path_list = _PyObject_GetAttrId(parent, &PyId___path__);
-        if (path_list == NULL)
-            PyErr_Clear();
-        subname_start++;
-        len = PyUnicode_GET_LENGTH(name) - (subname_start + 1);
-        subname = PyUnicode_Substring(name, subname_start, len);
     }
-    if (subname == NULL)
-        goto error;
-    fdp = find_module(name, subname, path_list,
-                      &bufobj, &fp, &loader);
-    Py_DECREF(subname);
-    Py_XDECREF(path_list);
-
-    if (fdp == NULL) {
-        Py_XDECREF(loader);
+
+    loader = _PyObject_GetAttrId(m, &PyId___loader__);
+    if (loader == NULL) {
         goto error;
     }
-
-    newm = load_module(name, fp, bufobj, fdp->type, loader);
-    Py_XDECREF(bufobj);
-    Py_XDECREF(loader);
-
-    if (fp)
-        fclose(fp);
+    newm = _PyObject_CallMethodId(loader, &PyId_load_module, "O", name);
+    Py_DECREF(loader);
     if (newm == NULL) {
         /* load_module probably removed name from modules because of
          * the error.  Put back the original module object.  We're

-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list