]> granicus.if.org Git - python/commitdiff
Issue #13959: Simplify imp.reload() by relying on a module's
authorBrett Cannon <brett@python.org>
Sun, 15 Apr 2012 21:56:09 +0000 (17:56 -0400)
committerBrett Cannon <brett@python.org>
Sun, 15 Apr 2012 21:56:09 +0000 (17:56 -0400)
__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.

Misc/NEWS
Python/import.c

index 36b82d4aa606306096d738d3199efa315a539732..e2e14b7ae241f9fd5a98eeac27714c0f7c1a50d0 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -32,6 +32,9 @@ Core and Builtins
 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.
 
index a930382fc7d6a7388e3a2abe433e6eb490a68ed9..747b0ddff46f0d6faaf1b8273c9d8af7ace12c87 100644 (file)
@@ -153,7 +153,6 @@ static const struct filedescr _PyImport_StandardFiletab[] = {
 };
 
 static PyObject *initstr = NULL;
-_Py_IDENTIFIER(__path__);
 
 /* Initialize things */
 
@@ -3106,12 +3105,12 @@ PyImport_ReloadModule(PyObject *m)
     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 @@ PyImport_ReloadModule(PyObject *m)
 
     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