Issue #21226: Set all attrs in PyImport_ExecCodeModuleObject.

This commit is contained in:
Eric Snow 2014-05-12 17:54:55 -06:00
parent 0cc45baa3d
commit 08197a4616
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
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.

View File

@ -1220,6 +1220,29 @@ class _SpecMethods:
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:

View File

@ -247,6 +247,8 @@ Extension Modules
-----------------
- 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
----

View File

@ -856,7 +856,7 @@ module_dict_for_exec(PyObject *name)
}
}
return d;
return d; /* Return a borrowed reference. */
}
static PyObject *
@ -888,33 +888,25 @@ PyObject*
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;
}

File diff suppressed because it is too large Load Diff