Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit b7f1be3

Browse files
Merge from 3.4 (for #21226).
2 parents 38d3d22 + 08197a4 commit b7f1be3

5 files changed

Lines changed: 4319 additions & 4269 deletions

File tree

Doc/c-api/import.rst

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,8 +132,14 @@ Importing Modules
132132
such modules have no way to know that the module object is an unknown (and
133133
probably damaged with respect to the module author's intents) state.
134134
135+
The module's :attr:`__spec__` and :attr:`__loader__` will be set, if
136+
not set already, with the appropriate values. The spec's loader will
137+
be set to the module's ``__loader__`` (if set) and to an instance of
138+
:class:`SourceFileLoader` otherwise.
139+
135140
The module's :attr:`__file__` attribute will be set to the code object's
136-
:c:member:`co_filename`.
141+
:c:member:`co_filename`. If applicable, :attr:`__cached__` will also
142+
be set.
137143
138144
This function will reload the module if it was already imported. See
139145
:c:func:`PyImport_ReloadModule` for the intended way to reload a module.

Lib/importlib/_bootstrap.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1221,6 +1221,29 @@ def load(self):
12211221
return self._load_unlocked()
12221222

12231223

1224+
def _fix_up_module(ns, name, pathname, cpathname=None):
1225+
# This function is used by PyImport_ExecCodeModuleObject().
1226+
loader = ns.get('__loader__')
1227+
spec = ns.get('__spec__')
1228+
if not loader:
1229+
if spec:
1230+
loader = spec.loader
1231+
elif pathname == cpathname:
1232+
loader = SourcelessFileLoader(name, pathname)
1233+
else:
1234+
loader = SourceFileLoader(name, pathname)
1235+
if not spec:
1236+
spec = spec_from_file_location(name, pathname, loader=loader)
1237+
try:
1238+
ns['__spec__'] = spec
1239+
ns['__loader__'] = loader
1240+
ns['__file__'] = pathname
1241+
ns['__cached__'] = cpathname
1242+
except Exception:
1243+
# Not important enough to report.
1244+
pass
1245+
1246+
12241247
# Loaders #####################################################################
12251248

12261249
class BuiltinImporter:

Misc/NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,8 @@ Extension Modules
364364
- Issue #21407: _decimal: The module now supports function signatures.
365365

366366
- Issue #21276: posixmodule: Don't define USE_XATTRS on KFreeBSD and the Hurd.
367+
- Issue #21226: Set up modules properly in PyImport_ExecCodeModuleObject
368+
(and friends).
367369

368370
IDLE
369371
----

Python/import.c

Lines changed: 12 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -856,7 +856,7 @@ module_dict_for_exec(PyObject *name)
856856
}
857857
}
858858

859-
return d;
859+
return d; /* Return a borrowed reference. */
860860
}
861861

862862
static PyObject *
@@ -888,33 +888,25 @@ PyObject*
888888
PyImport_ExecCodeModuleObject(PyObject *name, PyObject *co, PyObject *pathname,
889889
PyObject *cpathname)
890890
{
891-
PyObject *d, *v;
891+
PyObject *d, *res;
892+
PyInterpreterState *interp = PyThreadState_GET()->interp;
893+
_Py_IDENTIFIER(_fix_up_module);
892894

893895
d = module_dict_for_exec(name);
894896
if (d == NULL) {
895897
return NULL;
896898
}
897899

898-
if (pathname != NULL) {
899-
v = pathname;
900+
if (pathname == NULL) {
901+
pathname = ((PyCodeObject *)co)->co_filename;
900902
}
901-
else {
902-
v = ((PyCodeObject *)co)->co_filename;
903+
res = _PyObject_CallMethodIdObjArgs(interp->importlib,
904+
&PyId__fix_up_module,
905+
d, name, pathname, cpathname, NULL);
906+
if (res != NULL) {
907+
res = exec_code_in_module(name, d, co);
903908
}
904-
Py_INCREF(v);
905-
if (PyDict_SetItemString(d, "__file__", v) != 0)
906-
PyErr_Clear(); /* Not important enough to report */
907-
Py_DECREF(v);
908-
909-
/* Remember the pyc path name as the __cached__ attribute. */
910-
if (cpathname != NULL)
911-
v = cpathname;
912-
else
913-
v = Py_None;
914-
if (PyDict_SetItemString(d, "__cached__", v) != 0)
915-
PyErr_Clear(); /* Not important enough to report */
916-
917-
return exec_code_in_module(name, d, co);
909+
return res;
918910
}
919911

920912

0 commit comments

Comments
 (0)