[Python-checkins] bpo-41006: importlib.util no longer imports typing (GH-20938)

Victor Stinner webhook-mailer at python.org
Wed Jun 17 17:16:08 EDT 2020


https://github.com/python/cpython/commit/9e09849d20987c131b28bcdd252e53440d4cd1b3
commit: 9e09849d20987c131b28bcdd252e53440d4cd1b3
branch: master
author: Victor Stinner <vstinner at python.org>
committer: GitHub <noreply at github.com>
date: 2020-06-17T23:15:59+02:00
summary:

bpo-41006: importlib.util no longer imports typing (GH-20938)

Create importlib._abc submodule to avoid importing typing when
importlib.util is imported. Move Loader ABC into importlib._abc.

files:
A Lib/importlib/_abc.py
M Lib/importlib/abc.py
M Lib/importlib/util.py
M Lib/test/test_importlib/test_spec.py

diff --git a/Lib/importlib/_abc.py b/Lib/importlib/_abc.py
new file mode 100644
index 0000000000000..fb5ec727cea6e
--- /dev/null
+++ b/Lib/importlib/_abc.py
@@ -0,0 +1,50 @@
+"""Subset of importlib.abc used to reduce importlib.util imports."""
+from . import _bootstrap
+import abc
+
+
+class Loader(metaclass=abc.ABCMeta):
+
+    """Abstract base class for import loaders."""
+
+    def create_module(self, spec):
+        """Return a module to initialize and into which to load.
+
+        This method should raise ImportError if anything prevents it
+        from creating a new module.  It may return None to indicate
+        that the spec should create the new module.
+        """
+        # By default, defer to default semantics for the new module.
+        return None
+
+    # We don't define exec_module() here since that would break
+    # hasattr checks we do to support backward compatibility.
+
+    def load_module(self, fullname):
+        """Return the loaded module.
+
+        The module must be added to sys.modules and have import-related
+        attributes set properly.  The fullname is a str.
+
+        ImportError is raised on failure.
+
+        This method is deprecated in favor of loader.exec_module(). If
+        exec_module() exists then it is used to provide a backwards-compatible
+        functionality for this method.
+
+        """
+        if not hasattr(self, 'exec_module'):
+            raise ImportError
+        return _bootstrap._load_module_shim(self, fullname)
+
+    def module_repr(self, module):
+        """Return a module's repr.
+
+        Used by the module type when the method does not raise
+        NotImplementedError.
+
+        This method is deprecated.
+
+        """
+        # The exception will cause ModuleType.__repr__ to ignore this method.
+        raise NotImplementedError
diff --git a/Lib/importlib/abc.py b/Lib/importlib/abc.py
index 0b20e7c13f282..97d5afa300193 100644
--- a/Lib/importlib/abc.py
+++ b/Lib/importlib/abc.py
@@ -12,6 +12,7 @@
     import _frozen_importlib_external
 except ImportError:
     _frozen_importlib_external = _bootstrap_external
+from ._abc import Loader
 import abc
 import warnings
 from typing import Protocol, runtime_checkable
@@ -134,53 +135,6 @@ def invalidate_caches(self):
 _register(PathEntryFinder, machinery.FileFinder)
 
 
-class Loader(metaclass=abc.ABCMeta):
-
-    """Abstract base class for import loaders."""
-
-    def create_module(self, spec):
-        """Return a module to initialize and into which to load.
-
-        This method should raise ImportError if anything prevents it
-        from creating a new module.  It may return None to indicate
-        that the spec should create the new module.
-        """
-        # By default, defer to default semantics for the new module.
-        return None
-
-    # We don't define exec_module() here since that would break
-    # hasattr checks we do to support backward compatibility.
-
-    def load_module(self, fullname):
-        """Return the loaded module.
-
-        The module must be added to sys.modules and have import-related
-        attributes set properly.  The fullname is a str.
-
-        ImportError is raised on failure.
-
-        This method is deprecated in favor of loader.exec_module(). If
-        exec_module() exists then it is used to provide a backwards-compatible
-        functionality for this method.
-
-        """
-        if not hasattr(self, 'exec_module'):
-            raise ImportError
-        return _bootstrap._load_module_shim(self, fullname)
-
-    def module_repr(self, module):
-        """Return a module's repr.
-
-        Used by the module type when the method does not raise
-        NotImplementedError.
-
-        This method is deprecated.
-
-        """
-        # The exception will cause ModuleType.__repr__ to ignore this method.
-        raise NotImplementedError
-
-
 class ResourceLoader(Loader):
 
     """Abstract base class for loaders which can return data from their
diff --git a/Lib/importlib/util.py b/Lib/importlib/util.py
index 269a6fa930aab..1e44843a687f2 100644
--- a/Lib/importlib/util.py
+++ b/Lib/importlib/util.py
@@ -1,5 +1,5 @@
 """Utility code for constructing importers, etc."""
-from . import abc
+from ._abc import Loader
 from ._bootstrap import module_from_spec
 from ._bootstrap import _resolve_name
 from ._bootstrap import spec_from_loader
@@ -263,7 +263,7 @@ def __delattr__(self, attr):
         delattr(self, attr)
 
 
-class LazyLoader(abc.Loader):
+class LazyLoader(Loader):
 
     """A loader that creates a module which defers loading until attribute access."""
 
diff --git a/Lib/test/test_importlib/test_spec.py b/Lib/test/test_importlib/test_spec.py
index 5a16a03de60fa..20dacec8664e1 100644
--- a/Lib/test/test_importlib/test_spec.py
+++ b/Lib/test/test_importlib/test_spec.py
@@ -650,8 +650,8 @@ def test_spec_from_file_location_default(self):
         # Need to use a circuitous route to get at importlib.machinery to make
         # sure the same class object is used in the isinstance() check as
         # would have been used to create the loader.
-        self.assertIsInstance(spec.loader,
-                              self.util.abc.machinery.SourceFileLoader)
+        SourceFileLoader = self.util.spec_from_file_location.__globals__['SourceFileLoader']
+        self.assertIsInstance(spec.loader, SourceFileLoader)
         self.assertEqual(spec.loader.name, self.name)
         self.assertEqual(spec.loader.path, self.path)
         self.assertEqual(spec.origin, self.path)



More information about the Python-checkins mailing list