Merge from 3.4 (for #21226).

This commit is contained in:
Eric Snow 2014-05-12 18:25:00 -06:00
commit b7f1be309e
5 changed files with 4331 additions and 4281 deletions

View file

@ -132,8 +132,14 @@ Importing Modules
such modules have no way to know that the module object is an unknown (and 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. 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 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 This function will reload the module if it was already imported. See
:c:func:`PyImport_ReloadModule` for the intended way to reload a module. :c:func:`PyImport_ReloadModule` for the intended way to reload a module.

View file

@ -1221,6 +1221,29 @@ class _SpecMethods:
return self._load_unlocked() 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 ##################################################################### # Loaders #####################################################################
class BuiltinImporter: class BuiltinImporter:

View file

@ -364,6 +364,8 @@ Extension Modules
- Issue #21407: _decimal: The module now supports function signatures. - Issue #21407: _decimal: The module now supports function signatures.
- Issue #21276: posixmodule: Don't define USE_XATTRS on KFreeBSD and the Hurd. - 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 IDLE
---- ----

View file

@ -856,7 +856,7 @@ module_dict_for_exec(PyObject *name)
} }
} }
return d; return d; /* Return a borrowed reference. */
} }
static PyObject * static PyObject *
@ -888,33 +888,25 @@ PyObject*
PyImport_ExecCodeModuleObject(PyObject *name, PyObject *co, PyObject *pathname, PyImport_ExecCodeModuleObject(PyObject *name, PyObject *co, PyObject *pathname,
PyObject *cpathname) PyObject *cpathname)
{ {
PyObject *d, *v; PyObject *d, *res;
PyInterpreterState *interp = PyThreadState_GET()->interp;
_Py_IDENTIFIER(_fix_up_module);
d = module_dict_for_exec(name); d = module_dict_for_exec(name);
if (d == NULL) { if (d == NULL) {
return NULL; return NULL;
} }
if (pathname != NULL) { if (pathname == NULL) {
v = pathname; pathname = ((PyCodeObject *)co)->co_filename;
} }
else { res = _PyObject_CallMethodIdObjArgs(interp->importlib,
v = ((PyCodeObject *)co)->co_filename; &PyId__fix_up_module,
d, name, pathname, cpathname, NULL);
if (res != NULL) {
res = exec_code_in_module(name, d, co);
} }
Py_INCREF(v); return res;
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);
} }

File diff suppressed because it is too large Load diff