bpo-37521: No longer treat insertion into sys.modules as optional in importlib examples (GH-14723)
Fix importlib examples to insert any newly created modules via importlib.util.module_from_spec() immediately into sys.modules instead of after calling loader.exec_module(). Thanks to Benjamin Mintz for finding the bug. https://bugs.python.org/issue37521
This commit is contained in:
parent
a65c977552
commit
0827064c95
|
@ -1638,15 +1638,16 @@ import, then you should use :func:`importlib.util.find_spec`.
|
||||||
# For illustrative purposes.
|
# For illustrative purposes.
|
||||||
name = 'itertools'
|
name = 'itertools'
|
||||||
|
|
||||||
spec = importlib.util.find_spec(name)
|
if name in sys.modules:
|
||||||
if spec is None:
|
print(f"{name!r} already in sys.modules")
|
||||||
print("can't find the itertools module")
|
elif (spec := importlib.util.find_spec(name)) is None:
|
||||||
|
print(f"can't find the {name!r} module")
|
||||||
else:
|
else:
|
||||||
# If you chose to perform the actual import ...
|
# If you chose to perform the actual import ...
|
||||||
module = importlib.util.module_from_spec(spec)
|
module = importlib.util.module_from_spec(spec)
|
||||||
spec.loader.exec_module(module)
|
|
||||||
# Adding the module to sys.modules is optional.
|
|
||||||
sys.modules[name] = module
|
sys.modules[name] = module
|
||||||
|
spec.loader.exec_module(module)
|
||||||
|
print(f"{name!r} has been imported")
|
||||||
|
|
||||||
|
|
||||||
Importing a source file directly
|
Importing a source file directly
|
||||||
|
@ -1665,10 +1666,9 @@ To import a Python source file directly, use the following recipe
|
||||||
|
|
||||||
spec = importlib.util.spec_from_file_location(module_name, file_path)
|
spec = importlib.util.spec_from_file_location(module_name, file_path)
|
||||||
module = importlib.util.module_from_spec(spec)
|
module = importlib.util.module_from_spec(spec)
|
||||||
spec.loader.exec_module(module)
|
|
||||||
# Optional; only necessary if you want to be able to import the module
|
|
||||||
# by name later.
|
|
||||||
sys.modules[module_name] = module
|
sys.modules[module_name] = module
|
||||||
|
spec.loader.exec_module(module)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Setting up an importer
|
Setting up an importer
|
||||||
|
@ -1740,8 +1740,8 @@ Python 3.6 and newer for other parts of the code).
|
||||||
msg = f'No module named {absolute_name!r}'
|
msg = f'No module named {absolute_name!r}'
|
||||||
raise ModuleNotFoundError(msg, name=absolute_name)
|
raise ModuleNotFoundError(msg, name=absolute_name)
|
||||||
module = importlib.util.module_from_spec(spec)
|
module = importlib.util.module_from_spec(spec)
|
||||||
spec.loader.exec_module(module)
|
|
||||||
sys.modules[absolute_name] = module
|
sys.modules[absolute_name] = module
|
||||||
|
spec.loader.exec_module(module)
|
||||||
if path is not None:
|
if path is not None:
|
||||||
setattr(parent_module, child_name, module)
|
setattr(parent_module, child_name, module)
|
||||||
return module
|
return module
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
Fix `importlib` examples to insert any newly created modules via
|
||||||
|
importlib.util.module_from_spec() immediately into sys.modules instead of
|
||||||
|
after calling loader.exec_module().
|
||||||
|
|
||||||
|
Thanks to Benjamin Mintz for finding the bug.
|
Loading…
Reference in New Issue