Skip to content

Commit cf11d50

Browse files
committed
Merge branch 'master' into feature/extensible-traversable
2 parents 6290675 + bd53527 commit cf11d50

File tree

8 files changed

+86
-66
lines changed

8 files changed

+86
-66
lines changed

README.rst

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22
``importlib_resources``
33
=========================
44

5-
``importlib_resources`` is a backport of Python 3.7's standard library
5+
``importlib_resources`` is a backport of Python standard library
66
`importlib.resources
7-
<https://docs.python.org/3.7/library/importlib.html#module-importlib.resources>`_
8-
module for Python 2.7, and 3.4 through 3.6. Users of Python 3.7 and beyond
7+
<https://docs.python.org/3.9/library/importlib.html#module-importlib.resources>`_
8+
module for Python 2.7, and 3.4 through 3.8. Users of Python 3.9 and beyond
99
should use the standard library module, since for these versions,
1010
``importlib_resources`` just delegates to that module.
1111

importlib_resources/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,14 @@
33
import sys
44

55
from ._compat import metadata
6+
from .trees import as_file
67

78

89
__all__ = [
910
'Package',
1011
'Resource',
1112
'ResourceReader',
13+
'as_file',
1214
'contents',
1315
'files',
1416
'is_resource',

importlib_resources/_py3.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,11 @@
1010
from pathlib import Path
1111
from types import ModuleType
1212
from typing import Iterable, Iterator, Optional, Set, Union # noqa: F401
13-
from typing import ContextManager
1413
from typing import cast
1514
from typing.io import BinaryIO, TextIO
1615

16+
if False: # TYPE_CHECKING
17+
from typing import ContextManager
1718

1819
Package = Union[ModuleType, str]
1920
if sys.version_info >= (3, 6):
@@ -131,7 +132,7 @@ def read_text(package: Package,
131132
return fp.read()
132133

133134

134-
def files(package: Package) -> trees.Traversable:
135+
def files(package: Package) -> resources_abc.Traversable:
135136
"""
136137
Get a Traversable resource from a package
137138
"""
@@ -140,7 +141,7 @@ def files(package: Package) -> trees.Traversable:
140141

141142
def path(
142143
package: Package, resource: Resource,
143-
) -> ContextManager[Path]:
144+
) -> 'ContextManager[Path]':
144145
"""A context manager providing a file path object to the resource.
145146
146147
If the resource does not already exist on its own on the file system,

importlib_resources/abc.py

Lines changed: 66 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
from __future__ import absolute_import
22

3+
import abc
4+
35
from ._compat import ABC, FileNotFoundError
4-
from abc import abstractmethod
56

67
# We use mypy's comment syntax here since this file must be compatible with
78
# both Python 2 and 3.
@@ -15,7 +16,7 @@
1516
class ResourceReader(ABC):
1617
"""Abstract base class for loaders to provide resource reading support."""
1718

18-
@abstractmethod
19+
@abc.abstractmethod
1920
def open_resource(self, resource):
2021
# type: (Text) -> BinaryIO
2122
"""Return an opened, file-like object for binary reading.
@@ -28,7 +29,7 @@ def open_resource(self, resource):
2829
# it'll still do the right thing.
2930
raise FileNotFoundError
3031

31-
@abstractmethod
32+
@abc.abstractmethod
3233
def resource_path(self, resource):
3334
# type: (Text) -> Text
3435
"""Return the file system path to the specified resource.
@@ -42,7 +43,7 @@ def resource_path(self, resource):
4243
# it'll still do the right thing.
4344
raise FileNotFoundError
4445

45-
@abstractmethod
46+
@abc.abstractmethod
4647
def is_resource(self, path):
4748
# type: (Text) -> bool
4849
"""Return True if the named 'path' is a resource.
@@ -51,15 +52,74 @@ def is_resource(self, path):
5152
"""
5253
raise FileNotFoundError
5354

54-
@abstractmethod
55+
@abc.abstractmethod
5556
def contents(self):
5657
# type: () -> Iterable[str]
5758
"""Return an iterable of entries in `package`."""
5859
raise FileNotFoundError
5960

6061

62+
class Traversable(ABC):
63+
"""
64+
An object with a subset of pathlib.Path methods suitable for
65+
traversing directories and opening files.
66+
"""
67+
68+
@abc.abstractmethod
69+
def iterdir(self):
70+
"""
71+
Yield Traversable objects in self
72+
"""
73+
74+
@abc.abstractmethod
75+
def read_bytes(self):
76+
"""
77+
Read contents of self as bytes
78+
"""
79+
80+
@abc.abstractmethod
81+
def read_text(self, encoding=None):
82+
"""
83+
Read contents of self as bytes
84+
"""
85+
86+
@abc.abstractmethod
87+
def is_dir(self):
88+
"""
89+
Return True if self is a dir
90+
"""
91+
92+
@abc.abstractmethod
93+
def is_file(self):
94+
"""
95+
Return True if self is a file
96+
"""
97+
98+
@abc.abstractmethod
99+
def joinpath(self, child):
100+
"""
101+
Return Traversable child in self
102+
"""
103+
104+
@abc.abstractmethod
105+
def __truediv__(self, child):
106+
"""
107+
Return Traversable child in self
108+
"""
109+
110+
@abc.abstractmethod
111+
def open(self, mode='r', *args, **kwargs):
112+
"""
113+
mode may be 'r' or 'rb' to open as text or binary. Return a handle
114+
suitable for reading (same as pathlib.Path.open).
115+
116+
When opening as text, accepts encoding parameters such as those
117+
accepted by io.TextIOWrapper.
118+
"""
119+
120+
61121
class TraversableResources(ResourceReader):
62-
@abstractmethod
122+
@abc.abstractmethod
63123
def files(self):
64124
"""Return a Traversable object for the loaded package."""
65125

importlib_resources/docs/changelog.rst

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
importlib_resources NEWS
33
==========================
44

5-
v1.2.0
5+
v1.3.0
66
======
77
* Add extensibility support for non-standard loaders to supply
88
``Traversable`` resources. Introduces a new abstract base
@@ -12,6 +12,13 @@ v1.2.0
1212
``TraversableResources.files`` method will be capable of
1313
supplying resources with subdirectory support. Closes #77.
1414

15+
v1.2.0
16+
======
17+
* Traversable now requires an ``open`` method. Closes #81.
18+
* Fixed error on ``Python 3.5.{0,3}``. Closes #83.
19+
* Updated packaging to resolve version from package metadata.
20+
Closes #82.
21+
1522
v1.1.0
1623
======
1724
* Add support for retrieving resources from subdirectories of packages

importlib_resources/docs/using.rst

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,8 +132,7 @@ to this temporary file as a :py:class:`pathlib.Path` object. In order to
132132
properly clean up this temporary file, what's actually returned is a context
133133
manager that you can use in a ``with``-statement::
134134

135-
from importlib_resources import files
136-
from importlib_resources.trees import as_file
135+
from importlib_resources import files, as_file
137136

138137
source = files(email.tests.data).joinpath('message.eml')
139138
with as_file(source) as eml:

importlib_resources/trees.py

Lines changed: 1 addition & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,65 +1,15 @@
11
from __future__ import absolute_import
22

33
import os
4-
import abc
54
import tempfile
65
import contextlib
76

87
from ._compat import (
9-
ABC, Path, package_spec, FileNotFoundError, ZipPath,
8+
Path, package_spec, FileNotFoundError, ZipPath,
109
singledispatch,
1110
)
1211

1312

14-
class Traversable(ABC):
15-
"""
16-
An object with a subset of pathlib.Path methods suitable for
17-
traversing directories and opening files.
18-
"""
19-
20-
@abc.abstractmethod
21-
def iterdir(self):
22-
"""
23-
Yield Traversable objects in self
24-
"""
25-
26-
@abc.abstractmethod
27-
def read_bytes(self):
28-
"""
29-
Read contents of self as bytes
30-
"""
31-
32-
@abc.abstractmethod
33-
def read_text(self, encoding=None):
34-
"""
35-
Read contents of self as bytes
36-
"""
37-
38-
@abc.abstractmethod
39-
def is_dir(self):
40-
"""
41-
Return True if self is a dir
42-
"""
43-
44-
@abc.abstractmethod
45-
def is_file(self):
46-
"""
47-
Return True if self is a file
48-
"""
49-
50-
@abc.abstractmethod
51-
def joinpath(self, child):
52-
"""
53-
Return Traversable child in self
54-
"""
55-
56-
@abc.abstractmethod
57-
def __truediv__(self, child):
58-
"""
59-
Return Traversable child in self
60-
"""
61-
62-
6313
def from_package(package):
6414
"""
6515
Return a Traversable object for the given package.

tox.ini

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ commands =
4040
deps =
4141
mypy
4242
flake8
43+
flake8-typing-imports
4344

4445

4546
[testenv:docs]

0 commit comments

Comments
 (0)