[Python-checkins] bpo-32248: Introduce the concept of Loader.get_resource_reader() (GH-5108)

Brett Cannon webhook-mailer at python.org
Fri Jan 12 18:09:02 EST 2018


https://github.com/python/cpython/commit/bca42186b69e2e615d29d0d4fdb493c9fe71c48b
commit: bca42186b69e2e615d29d0d4fdb493c9fe71c48b
branch: master
author: Brett Cannon <brettcannon at users.noreply.github.com>
committer: GitHub <noreply at github.com>
date: 2018-01-12T15:08:59-08:00
summary:

bpo-32248: Introduce the concept of Loader.get_resource_reader() (GH-5108)

files:
A Misc/NEWS.d/next/Library/2017-12-15-15-34-12.bpo-32248.zmO8G2.rst
M Doc/library/importlib.rst
M Doc/whatsnew/3.7.rst
M Lib/importlib/abc.py

diff --git a/Doc/library/importlib.rst b/Doc/library/importlib.rst
index e99c6067a3d..5fa1d7d869d 100644
--- a/Doc/library/importlib.rst
+++ b/Doc/library/importlib.rst
@@ -233,7 +233,6 @@ ABC hierarchy::
      |    +-- MetaPathFinder
      |    +-- PathEntryFinder
      +-- Loader
-          +-- ResourceReader
           +-- ResourceLoader --------+
           +-- InspectLoader          |
                +-- ExecutionLoader --+
@@ -370,6 +369,13 @@ ABC hierarchy::
     An abstract base class for a :term:`loader`.
     See :pep:`302` for the exact definition for a loader.
 
+    For loaders that wish to support resource reading, they should
+    implement a ``get_resource_reader(fullname)`` method as specified
+    by :class:`importlib.abc.ResourceReader`.
+
+    .. versionchanged:: 3.7
+       Introduced the optional ``get_resource_reader()`` method.
+
     .. method:: create_module(spec)
 
        A method that returns the module object to use when
@@ -471,8 +477,7 @@ ABC hierarchy::
 
 .. class:: ResourceReader
 
-    An :term:`abstract base class` for :term:`package`
-    :term:`loaders <loader>` to provide the ability to read
+    An :term:`abstract base class` to provide the ability to read
     *resources*.
 
     From the perspective of this ABC, a *resource* is a binary
@@ -487,13 +492,20 @@ ABC hierarchy::
     expected to be a :term:`path-like object` which represents
     conceptually just a file name. This means that no subdirectory
     paths should be included in the *resource* argument. This is
-    because the location of the package that the loader is for acts
-    as the "directory". Hence the metaphor for directories and file
+    because the location of the package the reader is for, acts as the
+    "directory". Hence the metaphor for directories and file
     names is packages and resources, respectively. This is also why
     instances of this class are expected to directly correlate to
     a specific package (instead of potentially representing multiple
     packages or a module).
 
+    Loaders that wish to support resource reading are expected to
+    provide a method called ``get_resource_loader(fullname)`` which
+    returns an object implementing this ABC's interface. If the module
+    specified by fullname is not a package, this method should return
+    :const:`None`. An object compatible with this ABC should only be
+    returned when the specified module is a package.
+
     .. versionadded:: 3.7
 
     .. abstractmethod:: open_resource(resource)
@@ -529,9 +541,10 @@ ABC hierarchy::
         are known a priori and the non-resource names would be useful.
         For instance, returning subdirectory names is allowed so that
         when it is known that the package and resources are stored on
-        the file system then those subdirectory names can be used.
+        the file system then those subdirectory names can be used
+        directly.
 
-        The abstract method returns an empty iterator.
+        The abstract method returns an iterator of no items.
 
 
 .. class:: ResourceLoader
@@ -540,6 +553,10 @@ ABC hierarchy::
     :pep:`302` protocol for loading arbitrary resources from the storage
     back-end.
 
+    .. deprecated:: 3.7
+       This ABC is deprecated in favour of supporting resource loading
+       through :class:`importlib.abc.ResourceReader`.
+
     .. abstractmethod:: get_data(path)
 
         An abstract method to return the bytes for the data located at *path*.
diff --git a/Doc/whatsnew/3.7.rst b/Doc/whatsnew/3.7.rst
index 992d9ba6e58..1041d31f302 100644
--- a/Doc/whatsnew/3.7.rst
+++ b/Doc/whatsnew/3.7.rst
@@ -328,8 +328,8 @@ importlib.resources
 This module provides several new APIs and one new ABC for access to, opening,
 and reading *resources* inside packages.  Resources are roughly akin to files
 inside of packages, but they needn't be actual files on the physical file
-system.  Module loaders can implement the
-:class:`importlib.abc.ResourceReader` ABC to support this new module's API.
+system.  Module loaders can provide :class:`importlib.abc.ResourceReader`
+implementations to support this new module's API.
 
 
 Improved Modules
@@ -429,6 +429,12 @@ and the ``--directory`` to the command line of the module :mod:`~http.server`.
 With this parameter, the server serves the specified directory, by default it uses the current working directory.
 (Contributed by Stéphane Wirtel and Julien Palard in :issue:`28707`.)
 
+importlib
+---------
+
+The :class:`importlib.abc.ResourceReader` ABC was introduced to
+support the loading of resource from packages.
+
 locale
 ------
 
@@ -761,6 +767,9 @@ Deprecated
 
 - The :mod:`macpath` is now deprecated and will be removed in Python 3.8.
 
+- The :class:`importlib.abc.ResourceLoader` ABC has been deprecated in
+  favour of :class:`importlib.abc.ResourceReader`.
+
 
 Changes in the C API
 --------------------
@@ -785,8 +794,8 @@ Windows Only
   been used. If the specified version is not available py.exe will error exit.
   (Contributed by Steve Barnes in :issue:`30291`.)
 
-- The launcher can be run as "py -0" to produce a list of the installed pythons,
-  *with default marked with an asterix*. Running "py -0p" will include the paths.
+- The launcher can be run as ``py -0`` to produce a list of the installed pythons,
+  *with default marked with an asterisk*. Running ``py -0p`` will include the paths.
   If py is run with a version specifier that cannot be matched it will also print
   the *short form* list of available specifiers.
   (Contributed by Steve Barnes in :issue:`30362`.)
diff --git a/Lib/importlib/abc.py b/Lib/importlib/abc.py
index b772db3758c..bbff7af5885 100644
--- a/Lib/importlib/abc.py
+++ b/Lib/importlib/abc.py
@@ -342,9 +342,14 @@ def set_data(self, path, data):
 _register(SourceLoader, machinery.SourceFileLoader)
 
 
-class ResourceReader(Loader):
+class ResourceReader:
 
-    """Abstract base class for loaders to provide resource reading support."""
+    """Abstract base class to provide resource-reading support.
+
+    Loaders that support resource reading are expected to implement
+    the ``get_resource_reader(fullname)`` method and have it either return None
+    or an object compatible with this ABC.
+    """
 
     @abc.abstractmethod
     def open_resource(self, resource):
diff --git a/Misc/NEWS.d/next/Library/2017-12-15-15-34-12.bpo-32248.zmO8G2.rst b/Misc/NEWS.d/next/Library/2017-12-15-15-34-12.bpo-32248.zmO8G2.rst
new file mode 100644
index 00000000000..a41fde94b3d
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2017-12-15-15-34-12.bpo-32248.zmO8G2.rst
@@ -0,0 +1,13 @@
+Add :class:`importlib.abc.ResourceReader` as an ABC to provide a
+unified API for reading resources contained within packages. Loaders
+wishing to support resource reading are expected to implement the
+``get_resource_reader(fullname)`` method.
+
+Also add :mod:`importlib.resources` as the stdlib port of the
+``importlib_resources`` PyPI package. The modules provides a high-level
+API for end-users to read resources in a nicer fashion than having to
+directly interact with low-level details such as loaders.
+
+Thanks to this work, :class:`importlib.abc.ResourceLoader` has now
+been documented as deprecated due to its under-specified nature and
+lack of features as provided by :class:`importlib.abc.ResourceReader`.



More information about the Python-checkins mailing list