Skip to content

Commit 5d53bf9

Browse files
committed
Merge branch 'abcdocs' into 'master'
Document the ABC Closes python#36 See merge request python-devs/importlib_resources!40
2 parents c2f59e3 + a81e25b commit 5d53bf9

File tree

3 files changed

+110
-6
lines changed

3 files changed

+110
-6
lines changed

importlib_resources/abc.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,11 @@ class ResourceReader(ABC):
1616
"""Abstract base class for loaders to provide resource reading support."""
1717

1818
@abstractmethod
19-
def open_resource(self, path):
19+
def open_resource(self, resource):
2020
# type: (Text) -> BinaryIO
2121
"""Return an opened, file-like object for binary reading.
2222
23-
The 'path' argument is expected to represent only a file name.
23+
The 'resource' argument is expected to represent only a file name.
2424
If the resource cannot be found, FileNotFoundError is raised.
2525
"""
2626
# This deliberately raises FileNotFoundError instead of
@@ -29,11 +29,11 @@ def open_resource(self, path):
2929
raise FileNotFoundError
3030

3131
@abstractmethod
32-
def resource_path(self, path):
32+
def resource_path(self, resource):
3333
# type: (Text) -> Text
3434
"""Return the file system path to the specified resource.
3535
36-
The 'path' argument is expected to represent only a file name.
36+
The 'resource' argument is expected to represent only a file name.
3737
If the resource does not exist on the file system, raise
3838
FileNotFoundError.
3939
"""
@@ -45,7 +45,7 @@ def resource_path(self, path):
4545
@abstractmethod
4646
def is_resource(self, path):
4747
# type: (Text) -> bool
48-
"""Return True if the named path is a resource.
48+
"""Return True if the named 'path' is a resource.
4949
5050
Files are resources, directories are not.
5151
"""
@@ -54,5 +54,5 @@ def is_resource(self, path):
5454
@abstractmethod
5555
def contents(self):
5656
# type: () -> Iterator[str]
57-
"""Return an iterator over the string contents of the resource."""
57+
"""Return an iterator over the string contents of the package."""
5858
raise FileNotFoundError

importlib_resources/docs/abc.rst

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
========================
2+
The ResourceReader ABC
3+
========================
4+
5+
``importlib_resources`` relies heavily on a package's module loader_ for
6+
accessing that package's resources, with fallbacks for common cases when the
7+
loader doesn't provide this information (e.g. for zip files in versions of
8+
Python before 3.7). These fallbacks are not perfect, and there will be cases
9+
where custom loaders are implemented which subvert the usefulness of these
10+
fallback.
11+
12+
For this reason, a new `abstract base class`_ is introduced for loaders that
13+
want to participate in resource introspection and access. Loaders can
14+
implement the ``ResourceReader`` ABC to provide support for resources where
15+
the fallbacks don't work, or for providing more efficient access to
16+
resources.
17+
18+
``importlib_resources`` will first [#fn1]_ introspect the package's loader to
19+
see if it supports the ``ResourceReader`` interface. If it does, it will use
20+
that for all resource access.
21+
22+
23+
ResourceReader API
24+
==================
25+
26+
The ``ResourceReader`` ABC decorates its methods with ``@abstractmethod`` to
27+
indicate that they must all be overridden by the loader that implements this
28+
interface. However, the default implementation of each of these methods is to
29+
raise :py:exc:`FileNotFoundError` rather than :py:exc:`NotImplementedError`.
30+
This is so that if the ABC method is accidentally called,
31+
``importlib_resources`` should still be able to try its fallbacks.
32+
33+
34+
.. py:class:: ResourceReader
35+
36+
The abstract base class for loaders to implement if they provide resource
37+
reading and access support. Loaders should implement all of these methods.
38+
39+
.. py:method:: open_resource(resource)
40+
41+
Open the named **resource** for binary reading. The argument must be
42+
filename-like, i.e. it cannot have any path separators in the string.
43+
If the resource cannot be found, :py:exc:`FileNotFoundError` should be
44+
raised.
45+
46+
:param resource: The resource within the package to open.
47+
:type resource: importlib_resources.Resource
48+
:return: A stream open for binary reading. Text decoding is handled at
49+
a higher level.
50+
:rtype: typing.BinaryIO
51+
:raises FileNotFoundError: when the named resource is not found within
52+
the package.
53+
54+
.. py:method:: resource_path(resource)
55+
56+
Return the path to the named **resource** as found on the file
57+
system.
58+
59+
If the resource is not natively accessible on the file system
60+
(e.g. can't be accessed through :py:class:`pathlib.Path`), then
61+
:py:exc:`FileNotFoundError` should be raised. In this case,
62+
:py:meth:`importlib_resources.path()` will read the contents of the
63+
resource, create a temporary file, and return a context manager that
64+
will manage the lifetime of the temporary file.
65+
66+
:param resource: The resource within the package to open.
67+
:type resource: importlib_resources.Resource
68+
:return: The path to the named resource, relative to the package.
69+
:rtype: str
70+
:raises FileNotFoundError: when the named resource is not found within
71+
the package, or the resources is not directly
72+
accessible on the file system.
73+
74+
.. py:method:: is_resource(name)
75+
76+
Return a boolean indicating whether **name** is a resource within the
77+
package. *Remember that directories are not resources!*
78+
79+
:param name: A filename-like string (i.e. no path separators) to check
80+
whether it is a resource within the package.
81+
:type resource: str
82+
:return: Flag indicating whether **name** is a resource or not.
83+
:rtype: bool
84+
:raises FileNotFoundError: when the named resource is not found within
85+
the package.
86+
87+
.. py:method:: contents()
88+
89+
Return a sequence of all the contents of the package. This is like
90+
doing a directory listing. This returns resources (e.g. file names) and
91+
non-resource (e.g. subdirectories) alike. Thus, entries in this
92+
sequence may or may not be resources.
93+
94+
:return: A sequence of string names.
95+
:rtype: Iterator[str]
96+
97+
.. rubric:: Footnotes
98+
99+
.. [#fn1] In Python 3 only. ``importlib_resources`` does not support the
100+
``ResourceReader`` ABC for Python 2.
101+
102+
.. _loader: https://docs.python.org/3/reference/import.html#finders-and-loaders
103+
.. _`abstract base class`: https://docs.python.org/3/library/abc.html

importlib_resources/docs/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ This documentation includes a general :ref:`usage <using>` guide and a
2929
using.rst
3030
migration.rst
3131
api.rst
32+
abc.rst
3233

3334

3435
Indices and tables

0 commit comments

Comments
 (0)