Skip to content

Commit 54debaf

Browse files
committed
trees.from_package now supports TraversableResources loaders. Closes #77.
1 parent cc74d38 commit 54debaf

File tree

3 files changed

+31
-28
lines changed

3 files changed

+31
-28
lines changed

importlib_resources/docs/index.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ problems of ``pkg_resources``.
99

1010
In our terminology, a *resource* is a file tree that is located within an
1111
importable `Python package`_. Resources can live on the file system or in a
12-
zip file, with limited support for loader_ supporting the appropriate API for
13-
reading resources.
12+
zip file, with support for other loader_ classes that implement the appropriate
13+
API for reading resources.
1414

1515
``importlib_resources`` is a backport of Python 3.9's standard library
1616
`importlib.resources`_ module for Python 2.7, and 3.5 through 3.8. Users of

importlib_resources/docs/using.rst

Lines changed: 10 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -55,29 +55,6 @@ the ``data.one`` package, and
5555
``data`` package.
5656

5757

58-
Caveats
59-
=======
60-
61-
Subdirectory Access
62-
-------------------
63-
64-
Prior to importlib_resources 1.1 and the ``files()`` API, resources that were
65-
not direct descendents of a package's folder were inaccessible through the
66-
API, so in the example above ``resources1/resource1.1`` is not a resource of
67-
the ``data.one`` package and ``two/resource2.txt`` is not a resource of the
68-
``data`` package. Therefore, if subdirectory access is required, use the
69-
``files()`` API.
70-
71-
Resource Reader Support
72-
-----------------------
73-
74-
Due to the limitations on resource readers to access files beyond direct
75-
descendents of a package, the ``files()`` API does not rely
76-
on the importlib ResourceReader interface and thus only supports resources
77-
exposed by the built-in path and zipfile loaders. If support for arbitrary
78-
resource readers is required, the other API functions still support loading
79-
those resources.
80-
8158
Example
8259
=======
8360

@@ -187,6 +164,16 @@ manager.
187164
Both relative and absolute paths work for Python 3.7 and newer.
188165

189166

167+
Extending
168+
=========
169+
170+
Starting with Python 3.9 and ``importlib_resources`` 1.2, this package
171+
provides an interface for non-standard loaders, such as those used by
172+
executable bundlers, to supply resources. These loaders should subclass
173+
from the ``TraversableResources`` abstract class and implement the
174+
``files()`` method to return a ``Traversable`` object.
175+
176+
190177
.. rubric:: Footnotes
191178

192179
.. [#fn1] We're ignoring `PEP 420

importlib_resources/trees.py

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,24 @@ def __truediv__(self, child):
6161

6262

6363
def from_package(package):
64-
"""Return a Traversable object for the given package"""
64+
"""
65+
Return a Traversable object for the given package.
66+
67+
"""
6568
spec = package_spec(package)
69+
return from_traversable_resources(spec) or fallback_resources(spec)
70+
71+
72+
def from_traversable_resources(spec):
73+
"""
74+
If the spec.loader implements TraversableResources,
75+
directly or implicitly, it will have a ``files()`` method.
76+
"""
77+
with contextlib.suppress(AttributeError):
78+
return spec.loader.files()
79+
80+
81+
def fallback_resources(spec):
6682
package_directory = Path(spec.origin).parent
6783
try:
6884
archive_path = spec.loader.archive
@@ -94,7 +110,7 @@ def _tempfile(reader):
94110
@contextlib.contextmanager
95111
def as_file(path):
96112
"""
97-
Given a path-like object, return that object as a
113+
Given a Traversable object, return that object as a
98114
path on the local file system in a context manager.
99115
"""
100116
with _tempfile(path.read_bytes) as local:
@@ -105,6 +121,6 @@ def as_file(path):
105121
@contextlib.contextmanager
106122
def _(path):
107123
"""
108-
Degenerate behavior for pathlib.Path objects
124+
Degenerate behavior for pathlib.Path objects.
109125
"""
110126
yield path

0 commit comments

Comments
 (0)