Commit 08197a46 authored by Eric Snow's avatar Eric Snow

Issue #21226: Set all attrs in PyImport_ExecCodeModuleObject.

parent 0cc45baa
...@@ -132,8 +132,14 @@ Importing Modules ...@@ -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.
......
...@@ -1220,6 +1220,29 @@ class _SpecMethods: ...@@ -1220,6 +1220,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:
......
...@@ -247,6 +247,8 @@ Extension Modules ...@@ -247,6 +247,8 @@ Extension Modules
----------------- -----------------
- 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
---- ----
......
...@@ -856,7 +856,7 @@ module_dict_for_exec(PyObject *name) ...@@ -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* ...@@ -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);
} }
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment