8000 Merge branch 'issue52' into 'master' · jaraco/cpython@59bf56e · GitHub
[go: up one dir, main page]

Skip to content

Commit 59bf56e

Browse files
committed
Merge branch 'issue52' into 'master'
Backport bpo-33254 - contents() returns an Iterable Closes python#52 See merge request python-devs/importlib_resources!57
2 parents 5ff6d39 + eb59f6e commit 59bf56e

File tree

11 files changed

+46
-39
lines changed

11 files changed

+46
-39
lines changed

MANIFEST.in

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
include *.py MANIFEST.in
2+
global-include *.txt *.rst *.ini *.cfg
3+
exclude .gitignore .tox
4+
prune build

importlib_resources/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import sys
44

5-
__version__ = '0.4'
5+
__version__ = '0.5'
66

77

88
# Use the Python 3.7 stdlib implementation if available.

importlib_resources/_py2.py

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ def is_resource(package, name):
216216

217217

218218
def contents(package):
219-
"""Return the list of entries in package.
219+
"""Return an iterable of entries in `package`.
220220
221221
Note that not all entries are resources. Specifically, directories are
222222
not considered resources. Use `is_resource()` on each entry returned here
@@ -225,10 +225,7 @@ def contents(package):
225225
package = _get_package(package)
226226
package_directory = Path(package.__file__).parent
227227
try:
228-
# Python 2 doesn't support `yield from`. We fall back to using
229-
# os.listdir() here to simplify the returning of just the name.
230-
for entry in os.listdir(str(package_directory)):
231-
yield entry
228+
return os.listdir(str(package_directory))
232229
except OSError as error:
233230
if error.errno not in (errno.ENOENT, errno.ENOTDIR):
234231
# We won't hit this in the Python 2 tests, so it'll appear
@@ -245,6 +242,7 @@ def contents(package):
245242
with ZipFile(archive_path) as zf:
246243
toc = zf.namelist()
247244
subdirs_seen = set() # type: Set
245+
subdirs_returned = []
248246
for filename in toc:
249247
path = Path(filename)
250248
# Strip off any path component parts that are in common with the
@@ -263,9 +261,10 @@ def contents(package):
263261
continue
264262
subparts = path.parts[len(relpath.parts):]
265263
if len(subparts) == 1:
266-
yield subparts[0]
264+
subdirs_returned.append(subparts[0])
267265
elif len(subparts) > 1: # pragma: nobranch
268266
subdir = subparts[0]
269267
if subdir not in subdirs_seen:
270268
subdirs_seen.add(subdir)
271-
yield subdir
269+
subdirs_returned.append(subdir)
270+
return subdirs_returned

importlib_resources/_py3.py

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
from io import BytesIO, TextIOWrapper
1111
from pathlib import Path
1212
from types import ModuleType
13-
from typing import Iterator, Optional, Set, Union # noqa: F4 6D40 01
13+
from typing import Iterable, Iterator, Optional, Set, Union # noqa: F401
1414
from typing import cast
1515
from typing.io import BinaryIO, TextIO
1616
from zipfile import ZipFile
@@ -258,8 +258,8 @@ def is_resource(package: Package, name: str) -> bool:
258258
raise AssertionError('Impossible situation')
259259

260260

261-
def contents(package: Package) -> Iterator[str]:
262-
"""Return the list of entries in `package`.
261+
def contents(package: Package) -> Iterable[str]:
262+
"""Return an iterable of entries in `package`.
263263
264264
Note that not all entries are resources. Specifically, directories are
265265
not considered resources. Use `is_resource()` on each entry returned here
@@ -268,16 +268,15 @@ def contents(package: Package) -> Iterator[str]:
268268
package = _get_package(package)
269269
reader = _get_resource_reader(package)
270270
if reader is not None:
271-
yield from reader.contents()
272-
return
271+
return reader.contents()
273272
# Is the package a namespace package? By definition, namespace packages
274273
# cannot have resources.
275274
if (package.__spec__.origin == 'namespace' and
276275
not package.__spec__.has_location):
277-
return []
276+
return ()
278277
package_directory = Path(package.__spec__.origin).parent
279278
try:
280-
yield from os.listdir(str(package_directory))
279+
return os.listdir(str(package_directory))
281280
except (NotADirectoryError, FileNotFoundError):
282281
# The package is probably in a zip file.
283282
archive_path = getattr(package.__spec__.loader, 'archive', None)
@@ -287,6 +286,7 @@ def contents(package: Package) -> Iterator[str]:
287286
with ZipFile(archive_path) as zf:
288287
toc = zf.namelist()
289288
subdirs_seen = set() # type: Set
289+
subdirs_returned = []
290290
for filename in toc:
291291
path = Path(filename)
292292
# Strip off any path component parts that are in common with the
@@ -305,9 +305,10 @@ def contents(package: Package) -> Iterator[str]:
305305
continue
306306
subparts = path.parts[len(relpath.parts):]
307307
if len(subparts) == 1:
308-
yield subparts[0]
308+
subdirs_returned.append(subparts[0])
309309
elif len(subparts) > 1: # pragma: nobranch
310310
subdir = subparts[0]
311311
if subdir not in subdirs_seen:
312312
subdirs_seen.add(subdir)
313-
yield subdir
313+
subdirs_returned.append(subdir)
314+
return subdirs_returned

importlib_resources/abc.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,5 +54,5 @@ def is_resource(self, path):
5454
@abstractmethod
5555
def contents(self):
5656
# type: () -> Iterable[str]
57-
"""Return an iterable over the string contents of the package."""
57+
"""Return an iterable of entries in `package`."""
5858
raise FileNotFoundError

importlib_resources/docs/changelog.rst

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

5+
0.5 (2018-XX-XX)
6+
================
7+
* Resynchronize with Python 3.7; changes the return type of ``contents()`` to
8+
be an ``Iterable``. Closes #52
9+
10+
0.4 (2018-03-27)
11+
================
12+
* Correctly find resources in subpackages inside a zip file. Closes #51
13+
514
0.3 (2018-02-17)
615
================
7-
* The API, implementation, and documenttion is synchronized with the Python
16+
* The API, implementation, and documentation is synchronized with the Python
817
3.7 standard library. Closes #47
918
* When run under Python 3.7 this API shadows the stdlib versions. Closes #50
1019

11-
1220
0.2 (2017-12-13)
1321
================
1422
* **Backward incompatible change**. Split the ``open()`` and ``read()`` calls
@@ -18,7 +26,6 @@
1826
Closes #44
1927
* Correctly prevent namespace packages from containing resources. Closes #20
2028

21-
2229
0.1 (2017-12-05)
2330
================
2431
* Initial release.

importlib_resources/tests/test_resource.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -138,10 +138,10 @@ def test_unrelated_contents(self):
138138

139139
@unittest.skipIf(sys.version_info < (3,), 'No namespace packages in Python 2')
140140
class NamespaceTest(unittest.TestCase):
141-
def test_namespaces_cant_have_resources(self):
142-
contents = set(resources.contents(
143-
'importlib_resources.tests.data03.namespace'))
144-
self.assertEqual(len(contents), 0)
141+
def test_namespaces_cannot_have_resources(self):
142+
contents = resources.contents(
143+
'importlib_resources.tests.data03.namespace')
144+
self.assertFalse(list(contents))
145145
# Even though there is a file in the namespace directory, it is not
146146
# considered a resource, since namespace packages can't have them.
147147
self.assertFalse(resources.is_resource(

pyproject.toml renamed to pyproject.toml.aside

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,11 @@
66
# If you modify this file, you MUST run ./update-setup.py
77

88
[build-system]
9-
requires = ["flit"]
9+
requires = [
10+
"flit",
11+
"setuptools",
12+
"wheel",
13+
]
1014
build-backend = "flit.buildapi"
1115

1216
[tool.flit.metadata]

setup.py

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,3 @@
1-
#!/usr/bin/env python
2-
# setup.py generated by flit for tools that don't yet use PEP 517
3-
4-
# Do not modify this file by hand! Run ./update-setup.py instead.
5-
61
from distutils.core import setup
72

83
packages = \
@@ -28,7 +23,7 @@
2823
{":python_version < '3'": ['pathlib2'], ":python_version < '3.5'": ['typing']}
2924

3025
setup(name='importlib_resources',
31-
version='0.4',
26+
version='0.5',
3227
description='Read resources contained within a package.',
3328
author='Barry Warsaw',
3429
author_email='barry@python.org',

tox.ini

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[tox]
2-
# We deliberately don't test any versions >= 3.7, since this package just
3-
# shadows the stdlib version, so there's really nothing to test here.
4-
envlist = {py27,py34,py35,py36}-{nocov,cov,diffcov},qa,docs
2+
# Don't cover Python 3.7 since this is just a shim for that version. Do at
3+
# least make sure we don't regress!
4+
envlist = {py27,py34,py35,py36}-{nocov,cov,diffcov},py37-nocov,qa,docs
55
skip_missing_interpreters = True
66

77

0 commit comments

1241
Comments
 (0)
0