[Python-checkins] cpython: Issue #15502: Bring the importlib ABCs into line with the current state of the

Brett Cannon brett at python.org
Thu Aug 2 17:35:55 CEST 2012


Mostly as a note to myself (although if someone else wants to change this,
then great), PathEntryFinder.find_loader() specifies self while the other
docs don't bother to list it.

And I just realized that the other classes defined in the importlib docs
don't list their superclasses like MetaPathFinder and PathEntryFinder now
do.

On Thu, Aug 2, 2012 at 7:26 AM, nick.coghlan <python-checkins at python.org>wrote:

> http://hg.python.org/cpython/rev/184700df5b6a
> changeset:   78379:184700df5b6a
> parent:      78376:8ace059cdffd
> user:        Nick Coghlan <ncoghlan at gmail.com>
> date:        Thu Aug 02 21:26:03 2012 +1000
> summary:
>   Issue #15502: Bring the importlib ABCs into line with the current state
> of the import protocols given PEP 420. Original patch by Eric Snow.
>
> files:
>   Doc/library/importlib.rst                         |  77 +++++---
>   Lib/importlib/abc.py                              |  82 ++++++---
>   Lib/test/test_importlib/source/test_abc_loader.py |  23 +-
>   Lib/test/test_importlib/test_abc.py               |   7 +-
>   Misc/NEWS                                         |   3 +
>   5 files changed, 127 insertions(+), 65 deletions(-)
>
>
> diff --git a/Doc/library/importlib.rst b/Doc/library/importlib.rst
> --- a/Doc/library/importlib.rst
> +++ b/Doc/library/importlib.rst
> @@ -125,32 +125,49 @@
>
>  .. 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 @@
>
>      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 @@
>  .. 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 @@
>  .. 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 @@
>
>  .. 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.
> diff --git a/Lib/importlib/abc.py b/Lib/importlib/abc.py
> --- a/Lib/importlib/abc.py
> +++ b/Lib/importlib/abc.py
> @@ -23,6 +23,61 @@
>              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 @@
>          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
> diff --git a/Lib/test/test_importlib/source/test_abc_loader.py
> b/Lib/test/test_importlib/source/test_abc_loader.py
> --- a/Lib/test/test_importlib/source/test_abc_loader.py
> +++ b/Lib/test/test_importlib/source/test_abc_loader.py
> @@ -778,23 +778,32 @@
>          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(_)
> diff --git a/Lib/test/test_importlib/test_abc.py
> b/Lib/test/test_importlib/test_abc.py
> --- a/Lib/test/test_importlib/test_abc.py
> +++ b/Lib/test/test_importlib/test_abc.py
> @@ -30,11 +30,16 @@
>                 "{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):
>
> diff --git a/Misc/NEWS b/Misc/NEWS
> --- a/Misc/NEWS
> +++ b/Misc/NEWS
> @@ -72,6 +72,9 @@
>  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.
>
>
> --
> Repository URL: http://hg.python.org/cpython
>
> _______________________________________________
> Python-checkins mailing list
> Python-checkins at python.org
> http://mail.python.org/mailman/listinfo/python-checkins
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-checkins/attachments/20120802/b00d7ae0/attachment-0001.html>


More information about the Python-checkins mailing list