]> granicus.if.org Git - python/commitdiff
bpo-37521: No longer treat insertion into sys.modules as optional in importlib exampl...
authorBrett Cannon <54418+brettcannon@users.noreply.github.com>
Fri, 12 Jul 2019 22:35:34 +0000 (15:35 -0700)
committerMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Fri, 12 Jul 2019 22:35:34 +0000 (15:35 -0700)
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

Doc/library/importlib.rst
Misc/NEWS.d/next/Documentation/2019-07-12-15-09-56.bpo-37521.7tiFR-.rst [new file with mode: 0644]

index df184b33d0e73243a846604a0dcf94590511af15..9fab0779aa74211cab77339a061380bf9a1d3022 100644 (file)
@@ -1638,15 +1638,16 @@ import, then you should use :func:`importlib.util.find_spec`.
   # For illustrative purposes.
   name = 'itertools'
 
-  spec = importlib.util.find_spec(name)
-  if spec is None:
-      print("can't find the itertools module")
+  if name in sys.modules:
+      print(f"{name!r} already in sys.modules")
+  elif (spec := importlib.util.find_spec(name)) is None:
+      print(f"can't find the {name!r} module")
   else:
       # If you chose to perform the actual import ...
       module = importlib.util.module_from_spec(spec)
-      spec.loader.exec_module(module)
-      # Adding the module to sys.modules is optional.
       sys.modules[name] = module
+      spec.loader.exec_module(module)
+      print(f"{name!r} has been imported")
 
 
 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)
   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
+  spec.loader.exec_module(module)
+
 
 
 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}'
           raise ModuleNotFoundError(msg, name=absolute_name)
       module = importlib.util.module_from_spec(spec)
-      spec.loader.exec_module(module)
       sys.modules[absolute_name] = module
+      spec.loader.exec_module(module)
       if path is not None:
           setattr(parent_module, child_name, module)
       return module
diff --git a/Misc/NEWS.d/next/Documentation/2019-07-12-15-09-56.bpo-37521.7tiFR-.rst b/Misc/NEWS.d/next/Documentation/2019-07-12-15-09-56.bpo-37521.7tiFR-.rst
new file mode 100644 (file)
index 0000000..35d7f56
--- /dev/null
@@ -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.