mirror of
				https://github.com/python/cpython.git
				synced 2025-11-03 19:34:08 +00:00 
			
		
		
		
	Issue #15502: Bring the importlib ABCs into line with the current state of the import protocols given PEP 420. Original patch by Eric Snow.
This commit is contained in:
		
							parent
							
								
									a90f311d05
								
							
						
					
					
						commit
						8a9080feff
					
				
					 5 changed files with 127 additions and 65 deletions
				
			
		| 
						 | 
				
			
			@ -125,32 +125,49 @@ are also provided to help in implementing the core ABCs.
 | 
			
		|||
 | 
			
		||||
.. class:: Finder
 | 
			
		||||
 | 
			
		||||
    An abstract base class representing a :term:`finder`.
 | 
			
		||||
    See :pep:`302` for the exact definition for a finder.
 | 
			
		||||
 | 
			
		||||
    .. method:: find_loader(self, fullname):
 | 
			
		||||
 | 
			
		||||
        An abstract method for finding a :term:`loader` for the specified
 | 
			
		||||
        module.  Returns a 2-tuple of ``(loader, portion)`` where portion is a
 | 
			
		||||
        sequence of file system locations contributing to part of a namespace
 | 
			
		||||
        package.  The sequence may be empty.  When present, `find_loader()` is
 | 
			
		||||
        preferred over `find_module()`.
 | 
			
		||||
 | 
			
		||||
        .. versionadded: 3.3
 | 
			
		||||
 | 
			
		||||
    .. method:: find_module(fullname, path=None)
 | 
			
		||||
 | 
			
		||||
        An abstract method for finding a :term:`loader` for the specified
 | 
			
		||||
        module. If the :term:`finder` is found on :data:`sys.meta_path` and the
 | 
			
		||||
        module to be searched for is a subpackage or module then *path* will
 | 
			
		||||
        be the value of :attr:`__path__` from the parent package. If a loader
 | 
			
		||||
        cannot be found, ``None`` is returned.
 | 
			
		||||
   An abstract base class representing a :term:`finder`.  Finder
 | 
			
		||||
   implementations should derive from (or register with) the more specific
 | 
			
		||||
   :class:`MetaPathFinder` or :class:`PathEntryFinder` ABCs.
 | 
			
		||||
 | 
			
		||||
   .. method:: invalidate_caches()
 | 
			
		||||
 | 
			
		||||
        An optional method which, when called, should invalidate any internal
 | 
			
		||||
        cache used by the finder. Used by :func:`invalidate_caches()` when
 | 
			
		||||
        invalidating the caches of all cached finders.
 | 
			
		||||
      An optional method which, when called, should invalidate any internal
 | 
			
		||||
      cache used by the finder. Used by :func:`invalidate_caches()` when
 | 
			
		||||
      invalidating the caches of all cached finders.
 | 
			
		||||
 | 
			
		||||
   .. versionchanged:: 3.3
 | 
			
		||||
      The API signatures for meta path finders and path entry finders
 | 
			
		||||
      were separated by PEP 420. Accordingly, the Finder ABC no
 | 
			
		||||
      longer requires implementation of a ``find_module()`` method.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
.. class:: MetaPathFinder(Finder)
 | 
			
		||||
 | 
			
		||||
   An abstract base class representing a :term:`meta path finder`.
 | 
			
		||||
 | 
			
		||||
   .. versionadded:: 3.3
 | 
			
		||||
 | 
			
		||||
   .. method:: find_module(fullname, path)
 | 
			
		||||
 | 
			
		||||
      An abstract method for finding a :term:`loader` for the specified
 | 
			
		||||
      module.  If this is a top-level import, *path* will be ``None``.
 | 
			
		||||
      Otheriwse, this is a search for a subpackage or module and *path*
 | 
			
		||||
      will be the value of :attr:`__path__` from the parent
 | 
			
		||||
      package. If a loader cannot be found, ``None`` is returned.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
.. class:: PathEntryFinder(Finder)
 | 
			
		||||
 | 
			
		||||
   An abstract base class representing a :term:`path entry finder`.
 | 
			
		||||
 | 
			
		||||
   .. versionadded:: 3.3
 | 
			
		||||
 | 
			
		||||
   .. method:: find_loader(self, fullname):
 | 
			
		||||
 | 
			
		||||
      An abstract method for finding a :term:`loader` for the specified
 | 
			
		||||
      module.  Returns a 2-tuple of ``(loader, portion)`` where portion is a
 | 
			
		||||
      sequence of file system locations contributing to part of a namespace
 | 
			
		||||
      package.  The sequence may be empty.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
.. class:: Loader
 | 
			
		||||
| 
						 | 
				
			
			@ -569,8 +586,8 @@ find and load modules.
 | 
			
		|||
 | 
			
		||||
    An :term:`importer` for built-in modules. All known built-in modules are
 | 
			
		||||
    listed in :data:`sys.builtin_module_names`. This class implements the
 | 
			
		||||
    :class:`importlib.abc.Finder` and :class:`importlib.abc.InspectLoader`
 | 
			
		||||
    ABCs.
 | 
			
		||||
    :class:`importlib.abc.MetaPathFinder` and
 | 
			
		||||
    :class:`importlib.abc.InspectLoader` ABCs.
 | 
			
		||||
 | 
			
		||||
    Only class methods are defined by this class to alleviate the need for
 | 
			
		||||
    instantiation.
 | 
			
		||||
| 
						 | 
				
			
			@ -579,8 +596,8 @@ find and load modules.
 | 
			
		|||
.. class:: FrozenImporter
 | 
			
		||||
 | 
			
		||||
    An :term:`importer` for frozen modules. This class implements the
 | 
			
		||||
    :class:`importlib.abc.Finder` and :class:`importlib.abc.InspectLoader`
 | 
			
		||||
    ABCs.
 | 
			
		||||
    :class:`importlib.abc.MetaPathFinder` and
 | 
			
		||||
    :class:`importlib.abc.InspectLoader` ABCs.
 | 
			
		||||
 | 
			
		||||
    Only class methods are defined by this class to alleviate the need for
 | 
			
		||||
    instantiation.
 | 
			
		||||
| 
						 | 
				
			
			@ -589,7 +606,7 @@ find and load modules.
 | 
			
		|||
.. class:: PathFinder
 | 
			
		||||
 | 
			
		||||
    :term:`Finder` for :data:`sys.path`. This class implements the
 | 
			
		||||
    :class:`importlib.abc.Finder` ABC.
 | 
			
		||||
    :class:`importlib.abc.MetaPathFinder` ABC.
 | 
			
		||||
 | 
			
		||||
    This class does not perfectly mirror the semantics of :keyword:`import` in
 | 
			
		||||
    terms of :data:`sys.path`. No implicit path hooks are assumed for
 | 
			
		||||
| 
						 | 
				
			
			@ -616,8 +633,8 @@ find and load modules.
 | 
			
		|||
 | 
			
		||||
.. class:: FileFinder(path, \*loader_details)
 | 
			
		||||
 | 
			
		||||
   A concrete implementation of :class:`importlib.abc.Finder` which caches
 | 
			
		||||
   results from the file system.
 | 
			
		||||
   A concrete implementation of :class:`importlib.abc.PathEntryFinder` which
 | 
			
		||||
   caches results from the file system.
 | 
			
		||||
 | 
			
		||||
   The *path* argument is the directory for which the finder is in charge of
 | 
			
		||||
   searching.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -23,6 +23,61 @@ def _register(abstract_cls, *classes):
 | 
			
		|||
            abstract_cls.register(frozen_cls)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Finder(metaclass=abc.ABCMeta):
 | 
			
		||||
 | 
			
		||||
    """Common abstract base class for import finders.
 | 
			
		||||
 | 
			
		||||
    Finder implementations should derive from the more specific
 | 
			
		||||
    MetaPathFinder or PathEntryFinder ABCs rather than directly from Finder.
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    def find_module(self, fullname, path=None):
 | 
			
		||||
        """An optional legacy method that should find a module.
 | 
			
		||||
        The fullname is a str and the optional path is a str or None.
 | 
			
		||||
        Returns a Loader object.
 | 
			
		||||
 | 
			
		||||
        The path finder will use this method only if find_loader() does
 | 
			
		||||
        not exist. It may optionally be implemented for compatibility
 | 
			
		||||
        with legacy third party reimplementations of the import system.
 | 
			
		||||
        """
 | 
			
		||||
        raise NotImplementedError
 | 
			
		||||
 | 
			
		||||
    # invalidate_caches() is a completely optional method, so no default
 | 
			
		||||
    # implementation is provided. See the docs for details.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class MetaPathFinder(Finder):
 | 
			
		||||
 | 
			
		||||
    """Abstract base class for import finders on sys.meta_path."""
 | 
			
		||||
 | 
			
		||||
    @abc.abstractmethod
 | 
			
		||||
    def find_module(self, fullname, path):
 | 
			
		||||
        """Abstract method which when implemented should find a module.
 | 
			
		||||
        The fullname is a str and the path is a str or None.
 | 
			
		||||
        Returns a Loader object.
 | 
			
		||||
        """
 | 
			
		||||
        raise NotImplementedError
 | 
			
		||||
 | 
			
		||||
_register(MetaPathFinder, machinery.BuiltinImporter, machinery.FrozenImporter,
 | 
			
		||||
          machinery.PathFinder)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class PathEntryFinder(Finder):
 | 
			
		||||
 | 
			
		||||
    """Abstract base class for path entry finders used by PathFinder."""
 | 
			
		||||
 | 
			
		||||
    @abc.abstractmethod
 | 
			
		||||
    def find_loader(self, fullname):
 | 
			
		||||
        """Abstract method which when implemented returns a module loader.
 | 
			
		||||
        The fullname is a str.  Returns a 2-tuple of (Loader, portion) where
 | 
			
		||||
        portion is a sequence of file system locations contributing to part of
 | 
			
		||||
        a namespace package.  The sequence may be empty.
 | 
			
		||||
        """
 | 
			
		||||
        raise NotImplementedError
 | 
			
		||||
 | 
			
		||||
_register(PathEntryFinder, machinery.FileFinder)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Loader(metaclass=abc.ABCMeta):
 | 
			
		||||
 | 
			
		||||
    """Abstract base class for import loaders."""
 | 
			
		||||
| 
						 | 
				
			
			@ -40,33 +95,6 @@ class Loader(metaclass=abc.ABCMeta):
 | 
			
		|||
        raise NotImplementedError
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Finder(metaclass=abc.ABCMeta):
 | 
			
		||||
 | 
			
		||||
    """Abstract base class for import finders."""
 | 
			
		||||
 | 
			
		||||
    @abc.abstractmethod
 | 
			
		||||
    def find_loader(self, fullname):
 | 
			
		||||
        """Abstract method which when implemented returns a module loader.
 | 
			
		||||
        The fullname is a str.  Returns a 2-tuple of (Loader, portion) where
 | 
			
		||||
        portion is a sequence of file system locations contributing to part of
 | 
			
		||||
        a namespace package.  The sequence may be empty.  When present,
 | 
			
		||||
        `find_loader()` is preferred over `find_module()`.
 | 
			
		||||
        """
 | 
			
		||||
        raise NotImplementedError
 | 
			
		||||
 | 
			
		||||
    @abc.abstractmethod
 | 
			
		||||
    def find_module(self, fullname, path=None):
 | 
			
		||||
        """Abstract method which when implemented should find a module.
 | 
			
		||||
        The fullname is a str and the optional path is a str or None.
 | 
			
		||||
        Returns a Loader object.  This method is only called if
 | 
			
		||||
        `find_loader()` is not present.
 | 
			
		||||
        """
 | 
			
		||||
        raise NotImplementedError
 | 
			
		||||
 | 
			
		||||
_register(Finder, machinery.BuiltinImporter, machinery.FrozenImporter,
 | 
			
		||||
          machinery.PathFinder, machinery.FileFinder)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ResourceLoader(Loader):
 | 
			
		||||
 | 
			
		||||
    """Abstract base class for loaders which can return data from their
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -778,23 +778,32 @@ class SourceLoaderGetSourceTests(unittest.TestCase):
 | 
			
		|||
        expect = io.IncrementalNewlineDecoder(None, True).decode(source)
 | 
			
		||||
        self.assertEqual(mock.get_source(name), expect)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class AbstractMethodImplTests(unittest.TestCase):
 | 
			
		||||
 | 
			
		||||
    """Test the concrete abstractmethod implementations."""
 | 
			
		||||
 | 
			
		||||
    class MetaPathFinder(abc.MetaPathFinder):
 | 
			
		||||
        def find_module(self, fullname, path):
 | 
			
		||||
            super().find_module(fullname, path)
 | 
			
		||||
 | 
			
		||||
    class PathEntryFinder(abc.PathEntryFinder):
 | 
			
		||||
        def find_module(self, _):
 | 
			
		||||
            super().find_module(_)
 | 
			
		||||
 | 
			
		||||
        def find_loader(self, _):
 | 
			
		||||
            super().find_loader(_)
 | 
			
		||||
 | 
			
		||||
    class Finder(abc.Finder):
 | 
			
		||||
        def find_module(self, fullname, path):
 | 
			
		||||
            super().find_module(fullname, path)
 | 
			
		||||
 | 
			
		||||
    class Loader(abc.Loader):
 | 
			
		||||
        def load_module(self, fullname):
 | 
			
		||||
            super().load_module(fullname)
 | 
			
		||||
        def module_repr(self, module):
 | 
			
		||||
            super().module_repr(module)
 | 
			
		||||
 | 
			
		||||
    class Finder(abc.Finder):
 | 
			
		||||
        def find_module(self, _):
 | 
			
		||||
            super().find_module(_)
 | 
			
		||||
 | 
			
		||||
        def find_loader(self, _):
 | 
			
		||||
            super().find_loader(_)
 | 
			
		||||
 | 
			
		||||
    class ResourceLoader(Loader, abc.ResourceLoader):
 | 
			
		||||
        def get_data(self, _):
 | 
			
		||||
            super().get_data(_)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -30,11 +30,16 @@ class InheritanceTests:
 | 
			
		|||
               "{0} is not a superclass of {1}".format(superclass, self.__test))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Finder(InheritanceTests, unittest.TestCase):
 | 
			
		||||
class MetaPathFinder(InheritanceTests, unittest.TestCase):
 | 
			
		||||
 | 
			
		||||
    superclasses = [abc.Finder]
 | 
			
		||||
    subclasses = [machinery.BuiltinImporter, machinery.FrozenImporter,
 | 
			
		||||
                    machinery.PathFinder]
 | 
			
		||||
 | 
			
		||||
class PathEntryFinder(InheritanceTests, unittest.TestCase):
 | 
			
		||||
 | 
			
		||||
    superclasses = [abc.Finder]
 | 
			
		||||
    subclasses = [machinery.FileFinder]
 | 
			
		||||
 | 
			
		||||
class Loader(InheritanceTests, unittest.TestCase):
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -72,6 +72,9 @@ Core and Builtins
 | 
			
		|||
Library
 | 
			
		||||
-------
 | 
			
		||||
 | 
			
		||||
- Issue #15502: Bring the importlib ABCs into line with the current state
 | 
			
		||||
  of the import protocols given PEP 420. Original patch by Eric Snow.
 | 
			
		||||
 | 
			
		||||
- Issue #15499: Launching a webbrowser in Unix used to sleep for a few
 | 
			
		||||
  seconds.  Original patch by Anton Barkovsky.
 | 
			
		||||
  
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue