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

This commit is contained in:
Brett Cannon 2018-01-12 15:08:59 -08:00 committed by GitHub
parent 5b76bdba07
commit bca42186b6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 57 additions and 13 deletions

View File

@ -233,7 +233,6 @@ ABC hierarchy::
| +-- MetaPathFinder | +-- MetaPathFinder
| +-- PathEntryFinder | +-- PathEntryFinder
+-- Loader +-- Loader
+-- ResourceReader
+-- ResourceLoader --------+ +-- ResourceLoader --------+
+-- InspectLoader | +-- InspectLoader |
+-- ExecutionLoader --+ +-- ExecutionLoader --+
@ -370,6 +369,13 @@ ABC hierarchy::
An abstract base class for a :term:`loader`. An abstract base class for a :term:`loader`.
See :pep:`302` for the exact definition for a 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) .. method:: create_module(spec)
A method that returns the module object to use when A method that returns the module object to use when
@ -471,8 +477,7 @@ ABC hierarchy::
.. class:: ResourceReader .. class:: ResourceReader
An :term:`abstract base class` for :term:`package` An :term:`abstract base class` to provide the ability to read
:term:`loaders <loader>` to provide the ability to read
*resources*. *resources*.
From the perspective of this ABC, a *resource* is a binary 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 expected to be a :term:`path-like object` which represents
conceptually just a file name. This means that no subdirectory conceptually just a file name. This means that no subdirectory
paths should be included in the *resource* argument. This is paths should be included in the *resource* argument. This is
because the location of the package that the loader is for acts because the location of the package the reader is for, acts as the
as the "directory". Hence the metaphor for directories and file "directory". Hence the metaphor for directories and file
names is packages and resources, respectively. This is also why names is packages and resources, respectively. This is also why
instances of this class are expected to directly correlate to instances of this class are expected to directly correlate to
a specific package (instead of potentially representing multiple a specific package (instead of potentially representing multiple
packages or a module). 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 .. versionadded:: 3.7
.. abstractmethod:: open_resource(resource) .. abstractmethod:: open_resource(resource)
@ -529,9 +541,10 @@ ABC hierarchy::
are known a priori and the non-resource names would be useful. are known a priori and the non-resource names would be useful.
For instance, returning subdirectory names is allowed so that For instance, returning subdirectory names is allowed so that
when it is known that the package and resources are stored on 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 .. class:: ResourceLoader
@ -540,6 +553,10 @@ ABC hierarchy::
:pep:`302` protocol for loading arbitrary resources from the storage :pep:`302` protocol for loading arbitrary resources from the storage
back-end. back-end.
.. deprecated:: 3.7
This ABC is deprecated in favour of supporting resource loading
through :class:`importlib.abc.ResourceReader`.
.. abstractmethod:: get_data(path) .. abstractmethod:: get_data(path)
An abstract method to return the bytes for the data located at *path*. An abstract method to return the bytes for the data located at *path*.

View File

@ -328,8 +328,8 @@ importlib.resources
This module provides several new APIs and one new ABC for access to, opening, 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 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 inside of packages, but they needn't be actual files on the physical file
system. Module loaders can implement the system. Module loaders can provide :class:`importlib.abc.ResourceReader`
:class:`importlib.abc.ResourceReader` ABC to support this new module's API. implementations to support this new module's API.
Improved Modules 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. 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`.) (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 locale
------ ------
@ -761,6 +767,9 @@ Deprecated
- The :mod:`macpath` is now deprecated and will be removed in Python 3.8. - 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 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. been used. If the specified version is not available py.exe will error exit.
(Contributed by Steve Barnes in :issue:`30291`.) (Contributed by Steve Barnes in :issue:`30291`.)
- The launcher can be run as "py -0" to produce a list of the installed pythons, - 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. *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 If py is run with a version specifier that cannot be matched it will also print
the *short form* list of available specifiers. the *short form* list of available specifiers.
(Contributed by Steve Barnes in :issue:`30362`.) (Contributed by Steve Barnes in :issue:`30362`.)

View File

@ -342,9 +342,14 @@ class SourceLoader(_bootstrap_external.SourceLoader, ResourceLoader, ExecutionLo
_register(SourceLoader, machinery.SourceFileLoader) _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 @abc.abstractmethod
def open_resource(self, resource): def open_resource(self, resource):

View File

@ -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`.