[Python-checkins] cpython (merge 3.4 -> default): Merge from 3.4 (for #21226).

eric.snow python-checkins at python.org
Tue May 13 02:27:34 CEST 2014


http://hg.python.org/cpython/rev/bc324a49d0fc
changeset:   90674:bc324a49d0fc
parent:      90672:3424d65ad5ce
parent:      90673:7d20e30bd540
user:        Eric Snow <ericsnowcurrently at gmail.com>
date:        Mon May 12 18:25:00 2014 -0600
summary:
  Merge from 3.4 (for #21226).

files:
  Doc/c-api/import.rst        |     8 +-
  Lib/importlib/_bootstrap.py |    23 +
  Misc/NEWS                   |     2 +
  Python/import.c             |    32 +-
  Python/importlib.h          |  8555 +++++++++++-----------
  5 files changed, 4335 insertions(+), 4285 deletions(-)


diff --git a/Doc/c-api/import.rst b/Doc/c-api/import.rst
--- a/Doc/c-api/import.rst
+++ b/Doc/c-api/import.rst
@@ -132,8 +132,14 @@
    such modules have no way to know that the module object is an unknown (and
    probably damaged with respect to the module author's intents) state.
 
+   The module's :attr:`__spec__` and :attr:`__loader__` will be set, if
+   not set already, with the appropriate values.  The spec's loader will
+   be set to the module's ``__loader__`` (if set) and to an instance of
+   :class:`SourceFileLoader` otherwise.
+
    The module's :attr:`__file__` attribute will be set to the code object's
-   :c:member:`co_filename`.
+   :c:member:`co_filename`.  If applicable, :attr:`__cached__` will also
+   be set.
 
    This function will reload the module if it was already imported.  See
    :c:func:`PyImport_ReloadModule` for the intended way to reload a module.
diff --git a/Lib/importlib/_bootstrap.py b/Lib/importlib/_bootstrap.py
--- a/Lib/importlib/_bootstrap.py
+++ b/Lib/importlib/_bootstrap.py
@@ -1221,6 +1221,29 @@
             return self._load_unlocked()
 
 
+def _fix_up_module(ns, name, pathname, cpathname=None):
+    # This function is used by PyImport_ExecCodeModuleObject().
+    loader = ns.get('__loader__')
+    spec = ns.get('__spec__')
+    if not loader:
+        if spec:
+            loader = spec.loader
+        elif pathname == cpathname:
+            loader = SourcelessFileLoader(name, pathname)
+        else:
+            loader = SourceFileLoader(name, pathname)
+    if not spec:
+        spec = spec_from_file_location(name, pathname, loader=loader)
+    try:
+        ns['__spec__'] = spec
+        ns['__loader__'] = loader
+        ns['__file__'] = pathname
+        ns['__cached__'] = cpathname
+    except Exception:
+        # Not important enough to report.
+        pass
+
+
 # Loaders #####################################################################
 
 class BuiltinImporter:
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -364,6 +364,8 @@
 - Issue #21407: _decimal: The module now supports function signatures.
 
 - Issue #21276: posixmodule: Don't define USE_XATTRS on KFreeBSD and the Hurd.
+- Issue #21226: Set up modules properly in PyImport_ExecCodeModuleObject
+  (and friends).
 
 IDLE
 ----
diff --git a/Python/import.c b/Python/import.c
--- a/Python/import.c
+++ b/Python/import.c
@@ -856,7 +856,7 @@
         }
     }
 
-    return d;
+    return d;  /* Return a borrowed reference. */
 }
 
 static PyObject *
@@ -888,33 +888,25 @@
 PyImport_ExecCodeModuleObject(PyObject *name, PyObject *co, PyObject *pathname,
                               PyObject *cpathname)
 {
-    PyObject *d, *v;
+    PyObject *d, *res;
+    PyInterpreterState *interp = PyThreadState_GET()->interp;
+    _Py_IDENTIFIER(_fix_up_module);
 
     d = module_dict_for_exec(name);
     if (d == NULL) {
         return NULL;
     }
 
-    if (pathname != NULL) {
-        v = pathname;
+    if (pathname == NULL) {
+        pathname = ((PyCodeObject *)co)->co_filename;
     }
-    else {
-        v = ((PyCodeObject *)co)->co_filename;
+    res = _PyObject_CallMethodIdObjArgs(interp->importlib,
+                                        &PyId__fix_up_module,
+                                        d, name, pathname, cpathname, NULL);
+    if (res != NULL) {
+        res = exec_code_in_module(name, d, co);
     }
-    Py_INCREF(v);
-    if (PyDict_SetItemString(d, "__file__", v) != 0)
-        PyErr_Clear(); /* Not important enough to report */
-    Py_DECREF(v);
-
-    /* Remember the pyc path name as the __cached__ attribute. */
-    if (cpathname != NULL)
-        v = cpathname;
-    else
-        v = Py_None;
-    if (PyDict_SetItemString(d, "__cached__", v) != 0)
-        PyErr_Clear(); /* Not important enough to report */
-
-    return exec_code_in_module(name, d, co);
+    return res;
 }
 
 
diff --git a/Python/importlib.h b/Python/importlib.h
--- a/Python/importlib.h
+++ b/Python/importlib.h
[stripped]

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


More information about the Python-checkins mailing list