Skip to content

Commit 19b0cdd

Browse files
committed
Sync with stdlib changes in GH#4911
1 parent 3f32685 commit 19b0cdd

File tree

13 files changed

+72
-330
lines changed

13 files changed

+72
-330
lines changed

.gitlab-ci.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,18 @@ qa:
1010

1111
tests:
1212
script:
13-
- tox -e py27-nocov,py34-nocov,py35-nocov,py36-nocov,py37-nocov
13+
- tox -e py27-nocov,py34-nocov,py35-nocov,py36-nocov
1414

1515
coverage:
1616
script:
17-
- tox -e py27-cov,py34-cov,py35-cov,py36-cov,py37-cov
17+
- tox -e py27-cov,py34-cov,py35-cov,py36-cov
1818
artifacts:
1919
paths:
2020
- coverage.xml
2121

2222
diffcov:
2323
script:
24-
- tox -e py27-diffcov,py34-diffcov,py35-diffcov,py36-diffcov,py37-diffcov
24+
- tox -e py27-diffcov,py34-diffcov,py35-diffcov,py36-diffcov
2525

2626
docs:
2727
script:

.travis.yml

Lines changed: 0 additions & 25 deletions
This file was deleted.

README.rst

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,19 @@
11
=========================
2-
``importlib.resources``
2+
``importlib_resources``
33
=========================
44

5-
This repository is to house the design and implementation of a planned
6-
``importlib.resources`` module for Python's stdlib -- aiming for Python 3.7 --
7-
along with a backport to target Python 2.7, and 3.4 - 3.6.
5+
``importlib_resources`` is a backport of Python 3.7's standard library
6+
`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
9+
should use the standard library module, since for these versions,
10+
``importlib_resources`` just delegates to that module.
811

912
The key goal of this module is to replace parts of `pkg_resources
1013
<https://setuptools.readthedocs.io/en/latest/pkg_resources.html>`_ with a
11-
solution in Python's stdlib that relies on well-defined APIs. This should not
12-
only make reading resources included in packages easier, but have the
13-
semantics be stable and consistent.
14+
solution in Python's stdlib that relies on well-defined APIs. This makes
15+
reading resources included in packages easier, with more stable and consistent
16+
semantics.
1417

1518

1619
Project details

coverage.ini

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ exclude_lines =
1818
pragma: nocover
1919
raise NotImplementedError
2020
raise AssertionError
21-
pragma: FIXME
2221
assert\s
2322

2423
[paths]

importlib_resources/__init__.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,15 @@
22

33
import sys
44

5-
__version__ = '0.2'
5+
__version__ = '0.3'
66

77

8-
if sys.version_info >= (3,):
8+
# Use the Python 3.7 stdlib implementation if available.
9+
if sys.version_info >= (3, 7):
10+
from importlib.resources import (
11+
Package, Resource, contents, is_resource, open_binary, open_text, path,
12+
read_binary, read_text)
13+
elif sys.version_info >= (3,):
914
from importlib_resources._py3 import (
1015
Package, Resource, contents, is_resource, open_binary, open_text, path,
1116
read_binary, read_text)

importlib_resources/_py2.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,10 @@
1111

1212

1313
def _get_package(package):
14-
# `package` will be a string or a module. Always return a module which is
15-
# a package, otherwise raise an exception.
14+
"""Normalize a path by ensuring it is a string.
15+
16+
If the resulting string contains path separators, an exception is raised.
17+
"""
1618
if isinstance(package, basestring): # noqa: F821
1719
module = import_module(package)
1820
else:
@@ -23,8 +25,10 @@ def _get_package(package):
2325

2426

2527
def _normalize_path(path):
26-
# Ensure that the incoming `path`, which may be a string or a Path object,
27-
# is a bare file name with no hierarchy.
28+
"""Normalize a path by ensuring it is a string.
29+
30+
If the resulting string contains path separators, an exception is raised.
31+
"""
2832
str_path = str(path)
2933
parent, file_name = os.path.split(str_path)
3034
if parent:

importlib_resources/_py3.py

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@
2424

2525

2626
def _get_package(package) -> ModuleType:
27+
"""Take a package name or module object and return the module.
28+
29+
If a name, the module is imported. If the passed or imported module
30+
object is not a package, raise an exception.
31+
"""
2732
if hasattr(package, '__spec__'):
2833
if package.__spec__.submodule_search_locations is None:
2934
raise TypeError('{!r} is not a package'.format(
@@ -39,6 +44,10 @@ def _get_package(package) -> ModuleType:
3944

4045

4146
def _normalize_path(path) -> str:
47+
"""Normalize a path by ensuring it is a string.
48+
49+
If the resulting string contains path separators, an exception is raised.
50+
"""
4251
str_path = str(path)
4352
parent, file_name = os.path.split(str_path)
4453
if parent:
@@ -54,9 +63,11 @@ def _get_resource_reader(
5463
# hook wants to create a weak reference to the object, but
5564
# zipimport.zipimporter does not support weak references, resulting in a
5665
# TypeError. That seems terrible.
57-
if hasattr(package.__spec__.loader, 'open_resource'):
58-
return cast(resources_abc.ResourceReader, package.__spec__.loader)
59-
return None
66+
spec = package.__spec__
67+
reader = getattr(spec.loader, 'get_resource_reader', None)
68+
if reader is None:
69+
return None
70+
return cast(resources_abc.ResourceReader, reader(spec.name))
6071

6172

6273
def open_binary(package: Package, resource: Resource) -> BinaryIO:
@@ -73,14 +84,14 @@ def open_binary(package: Package, resource: Resource) -> BinaryIO:
7384
full_path = os.path.join(package_path, resource)
7485
try:
7586
return builtins_open(full_path, mode='rb')
76-
except IOError:
87+
except OSError:
7788
# Just assume the loader is a resource loader; all the relevant
7889
# importlib.machinery loaders are and an AttributeError for
7990
# get_data() will make it clear what is needed from the loader.
8091
loader = cast(ResourceLoader, package.__spec__.loader)
8192
data = None
8293
if hasattr(package.__spec__.loader, 'get_data'):
83-
with suppress(IOError):
94+
with suppress(OSError):
8495
data = loader.get_data(full_path)
8596
if data is None:
8697
package_name = package.__spec__.name
@@ -109,14 +120,14 @@ def open_text(package: Package,
109120
try:
110121
return builtins_open(
111122
full_path, mode='r', encoding=encoding, errors=errors)
112-
except IOError:
123+
except OSError:
113124
# Just assume the loader is a resource loader; all the relevant
114125
# importlib.machinery loaders are and an AttributeError for
115126
# get_data() will make it clear what is needed from the loader.
116127
loader = cast(ResourceLoader, package.__spec__.loader)
117128
data = None
118129
if hasattr(package.__spec__.loader, 'get_data'):
119-
with suppress(IOError):
130+
with suppress(OSError):
120131
data = loader.get_data(full_path)
121132
if data is None:
122133
package_name = package.__spec__.name
@@ -173,7 +184,7 @@ def path(package: Package, resource: Resource) -> Iterator[Path]:
173184
# resource_path() raises FileNotFoundError.
174185
package_directory = Path(package.__spec__.origin).parent
175186
file_path = package_directory / resource
176-
if file_path.exists(): # pragma: FIXME
187+
if file_path.exists():
177188
yield file_path
178189
else:
179190
with open_binary(package, resource) as fp:
@@ -213,10 +224,10 @@ def is_resource(package: Package, name: str) -> bool:
213224
# contents doesn't necessarily mean it's a resource. Directories are not
214225
# resources, so let's try to find out if it's a directory or not.
215226
path = Path(package.__spec__.origin).parent / name
216-
if path.is_file(): # pragma: FIXME
227+
if path.is_file():
217228
return True
218229
if path.is_dir():
219-
return False # pragma: FIXME
230+
return False
220231
# If it's not a file and it's not a directory, what is it? Well, this
221232
# means the file doesn't exist on the file system, so it probably lives
222233
# inside a zip file. We have to crack open the zip, look at its table of

importlib_resources/docs/abc.rst

Lines changed: 0 additions & 101 deletions
This file was deleted.

0 commit comments

Comments
 (0)