Skip to content

Commit bca4218

Browse files
authored
bpo-32248: Introduce the concept of Loader.get_resource_reader() (GH-5108)
1 parent 5b76bdb commit bca4218

File tree

4 files changed

+57
-13
lines changed

4 files changed

+57
-13
lines changed

Doc/library/importlib.rst

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,6 @@ ABC hierarchy::
233233
| +-- MetaPathFinder
234234
| +-- PathEntryFinder
235235
+-- Loader
236-
+-- ResourceReader
237236
+-- ResourceLoader --------+
238237
+-- InspectLoader |
239238
+-- ExecutionLoader --+
@@ -370,6 +369,13 @@ ABC hierarchy::
370369
An abstract base class for a :term:`loader`.
371370
See :pep:`302` for the exact definition for a loader.
372371

372+
For loaders that wish to support resource reading, they should
373+
implement a ``get_resource_reader(fullname)`` method as specified
374+
by :class:`importlib.abc.ResourceReader`.
375+
376+
.. versionchanged:: 3.7
377+
Introduced the optional ``get_resource_reader()`` method.
378+
373379
.. method:: create_module(spec)
374380

375381
A method that returns the module object to use when
@@ -471,8 +477,7 @@ ABC hierarchy::
471477

472478
.. class:: ResourceReader
473479

474-
An :term:`abstract base class` for :term:`package`
475-
:term:`loaders <loader>` to provide the ability to read
480+
An :term:`abstract base class` to provide the ability to read
476481
*resources*.
477482

478483
From the perspective of this ABC, a *resource* is a binary
@@ -487,13 +492,20 @@ ABC hierarchy::
487492
expected to be a :term:`path-like object` which represents
488493
conceptually just a file name. This means that no subdirectory
489494
paths should be included in the *resource* argument. This is
490-
because the location of the package that the loader is for acts
491-
as the "directory". Hence the metaphor for directories and file
495+
because the location of the package the reader is for, acts as the
496+
"directory". Hence the metaphor for directories and file
492497
names is packages and resources, respectively. This is also why
493498
instances of this class are expected to directly correlate to
494499
a specific package (instead of potentially representing multiple
495500
packages or a module).
496501

502+
Loaders that wish to support resource reading are expected to
503+
provide a method called ``get_resource_loader(fullname)`` which
504+
returns an object implementing this ABC's interface. If the module
505+
specified by fullname is not a package, this method should return
506+
:const:`None`. An object compatible with this ABC should only be
507+
returned when the specified module is a package.
508+
497509
.. versionadded:: 3.7
498510

499511
.. abstractmethod:: open_resource(resource)
@@ -529,9 +541,10 @@ ABC hierarchy::
529541
are known a priori and the non-resource names would be useful.
530542
For instance, returning subdirectory names is allowed so that
531543
when it is known that the package and resources are stored on
532-
the file system then those subdirectory names can be used.
544+
the file system then those subdirectory names can be used
545+
directly.
533546

534-
The abstract method returns an empty iterator.
547+
The abstract method returns an iterator of no items.
535548

536549

537550
.. class:: ResourceLoader
@@ -540,6 +553,10 @@ ABC hierarchy::
540553
:pep:`302` protocol for loading arbitrary resources from the storage
541554
back-end.
542555

556+
.. deprecated:: 3.7
557+
This ABC is deprecated in favour of supporting resource loading
558+
through :class:`importlib.abc.ResourceReader`.
559+
543560
.. abstractmethod:: get_data(path)
544561

545562
An abstract method to return the bytes for the data located at *path*.

Doc/whatsnew/3.7.rst

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -328,8 +328,8 @@ importlib.resources
328328
This module provides several new APIs and one new ABC for access to, opening,
329329
and reading *resources* inside packages. Resources are roughly akin to files
330330
inside of packages, but they needn't be actual files on the physical file
331-
system. Module loaders can implement the
332-
:class:`importlib.abc.ResourceReader` ABC to support this new module's API.
331+
system. Module loaders can provide :class:`importlib.abc.ResourceReader`
332+
implementations to support this new module's API.
333333

334334

335335
Improved Modules
@@ -429,6 +429,12 @@ and the ``--directory`` to the command line of the module :mod:`~http.server`.
429429
With this parameter, the server serves the specified directory, by default it uses the current working directory.
430430
(Contributed by Stéphane Wirtel and Julien Palard in :issue:`28707`.)
431431

432+
importlib
433+
---------
434+
435+
The :class:`importlib.abc.ResourceReader` ABC was introduced to
436+
support the loading of resource from packages.
437+
432438
locale
433439
------
434440

@@ -761,6 +767,9 @@ Deprecated
761767

762768
- The :mod:`macpath` is now deprecated and will be removed in Python 3.8.
763769

770+
- The :class:`importlib.abc.ResourceLoader` ABC has been deprecated in
771+
favour of :class:`importlib.abc.ResourceReader`.
772+
764773

765774
Changes in the C API
766775
--------------------
@@ -785,8 +794,8 @@ Windows Only
785794
been used. If the specified version is not available py.exe will error exit.
786795
(Contributed by Steve Barnes in :issue:`30291`.)
787796

788-
- The launcher can be run as "py -0" to produce a list of the installed pythons,
789-
*with default marked with an asterix*. Running "py -0p" will include the paths.
797+
- The launcher can be run as ``py -0`` to produce a list of the installed pythons,
798+
*with default marked with an asterisk*. Running ``py -0p`` will include the paths.
790799
If py is run with a version specifier that cannot be matched it will also print
791800
the *short form* list of available specifiers.
792801
(Contributed by Steve Barnes in :issue:`30362`.)

Lib/importlib/abc.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -342,9 +342,14 @@ def set_data(self, path, data):
342342
_register(SourceLoader, machinery.SourceFileLoader)
343343

344344

345-
class ResourceReader(Loader):
345+
class ResourceReader:
346346

347-
"""Abstract base class for loaders to provide resource reading support."""
347+
"""Abstract base class to provide resource-reading support.
348+
349+
Loaders that support resource reading are expected to implement
350+
the ``get_resource_reader(fullname)`` method and have it either return None
351+
or an object compatible with this ABC.
352+
"""
348353

349354
@abc.abstractmethod
350355
def open_resource(self, resource):
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
Add :class:`importlib.abc.ResourceReader` as an ABC to provide a
2+
unified API for reading resources contained within packages. Loaders
3+
wishing to support resource reading are expected to implement the
4+
``get_resource_reader(fullname)`` method.
5+
6+
Also add :mod:`importlib.resources` as the stdlib port of the
7+
``importlib_resources`` PyPI package. The modules provides a high-level
8+
API for end-users to read resources in a nicer fashion than having to
9+
directly interact with low-level details such as loaders.
10+
11+
Thanks to this work, :class:`importlib.abc.ResourceLoader` has now
12+
been documented as deprecated due to its under-specified nature and
13+
lack of features as provided by :class:`importlib.abc.ResourceReader`.

0 commit comments

Comments
 (0)