[Python-checkins] bpo-33254: do not return an empty list when asking for the contents of a namespace package (GH-6467)

Miss Islington (bot) webhook-mailer at python.org
Mon Apr 30 15:30:34 EDT 2018


https://github.com/python/cpython/commit/2e5fa38c5aaf7630c55ce6dfb8f79df6b3b86076
commit: 2e5fa38c5aaf7630c55ce6dfb8f79df6b3b86076
branch: 3.7
author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com>
committer: GitHub <noreply at github.com>
date: 2018年04月30日T12:30:26-07:00
summary:
bpo-33254: do not return an empty list when asking for the contents of a namespace package (GH-6467)
(cherry picked from commit 3ab9365dca8438f89b2060cd3eebe00606133dc4)
Co-authored-by: Brett Cannon <brettcannon at users.noreply.github.com>
files:
A Misc/NEWS.d/next/Library/2018-04-13-15-14-47.bpo-33254.DS4KFK.rst
M Doc/library/importlib.rst
M Lib/importlib/abc.py
M Lib/importlib/resources.py
M Lib/test/test_importlib/test_resource.py
diff --git a/Doc/library/importlib.rst b/Doc/library/importlib.rst
index 130aabf119a6..e33abae7aaca 100644
--- a/Doc/library/importlib.rst
+++ b/Doc/library/importlib.rst
@@ -530,7 +530,7 @@ ABC hierarchy::
 
 .. abstractmethod:: contents()
 
- Returns an :term:`iterator` of strings over the contents of
+ Returns an :term:`iterable` of strings over the contents of
 the package. Do note that it is not required that all names
 returned by the iterator be actual resources, e.g. it is
 acceptable to return names for which :meth:`is_resource` would
@@ -544,7 +544,7 @@ ABC hierarchy::
 the file system then those subdirectory names can be used
 directly.
 
- The abstract method returns an iterator of no items.
+ The abstract method returns an iterable of no items.
 
 
 .. class:: ResourceLoader
@@ -926,9 +926,9 @@ The following functions are available.
 
 .. function:: contents(package)
 
- Return an iterator over the named items within the package. The iterator
+ Return an iterable over the named items within the package. The iterable
 returns :class:`str` resources (e.g. files) and non-resources
- (e.g. directories). The iterator does not recurse into subdirectories.
+ (e.g. directories). The iterable does not recurse into subdirectories.
 
 *package* is either a name or a module object which conforms to the
 ``Package`` requirements.
diff --git a/Lib/importlib/abc.py b/Lib/importlib/abc.py
index d2f45093a455..dbdd5bf64192 100644
--- a/Lib/importlib/abc.py
+++ b/Lib/importlib/abc.py
@@ -381,8 +381,8 @@ def is_resource(self, name):
 
 @abc.abstractmethod
 def contents(self):
- """Return an iterator of strings over the contents of the package."""
- return iter([])
+ """Return an iterable of strings over the contents of the package."""
+ return []
 
 
 _register(ResourceReader, machinery.SourceFileLoader)
diff --git a/Lib/importlib/resources.py b/Lib/importlib/resources.py
index e5654273c06a..4d70186c1a43 100644
--- a/Lib/importlib/resources.py
+++ b/Lib/importlib/resources.py
@@ -9,7 +9,7 @@
 from io import BytesIO, TextIOWrapper
 from pathlib import Path
 from types import ModuleType
-from typing import Iterator, Optional, Set, Union # noqa: F401
+from typing import Iterable, Iterator, Optional, Set, Union # noqa: F401
 from typing import cast
 from typing.io import BinaryIO, TextIO
 from zipimport import ZipImportError
@@ -44,8 +44,7 @@ def _normalize_path(path) -> str:
 
 If the resulting string contains path separators, an exception is raised.
 """
- str_path = str(path)
- parent, file_name = os.path.split(str_path)
+ parent, file_name = os.path.split(path)
 if parent:
 raise ValueError('{!r} must be only a file name'.format(path))
 else:
@@ -228,8 +227,8 @@ def is_resource(package: Package, name: str) -> bool:
 return path.is_file()
 
 
-def contents(package: Package) -> Iterator[str]:
- """Return the list of entries in 'package'.
+def contents(package: Package) -> Iterable[str]:
+ """Return an iterable of entries in 'package'.
 
 Note that not all entries are resources. Specifically, directories are
 not considered resources. Use `is_resource()` on each entry returned here
@@ -238,15 +237,15 @@ def contents(package: Package) -> Iterator[str]:
 package = _get_package(package)
 reader = _get_resource_reader(package)
 if reader is not None:
- yield from reader.contents()
- return
+ return reader.contents()
 # Is the package a namespace package? By definition, namespace packages
 # cannot have resources. We could use _check_location() and catch the
 # exception, but that's extra work, so just inline the check.
- if package.__spec__.origin is None or not package.__spec__.has_location:
- return []
- package_directory = Path(package.__spec__.origin).parent
- yield from os.listdir(str(package_directory))
+ elif package.__spec__.origin is None or not package.__spec__.has_location:
+ return ()
+ else:
+ package_directory = Path(package.__spec__.origin).parent
+ return os.listdir(package_directory)
 
 
 # Private implementation of ResourceReader and get_resource_reader() for
diff --git a/Lib/test/test_importlib/test_resource.py b/Lib/test/test_importlib/test_resource.py
index d717e1dd04da..b07686032e04 100644
--- a/Lib/test/test_importlib/test_resource.py
+++ b/Lib/test/test_importlib/test_resource.py
@@ -131,10 +131,9 @@ def test_submodule_contents_by_name(self):
 
 
 class NamespaceTest(unittest.TestCase):
- def test_namespaces_cant_have_resources(self):
- contents = set(resources.contents(
- 'test.test_importlib.data03.namespace'))
- self.assertEqual(len(contents), 0)
+ def test_namespaces_cannot_have_resources(self):
+ contents = resources.contents('test.test_importlib.data03.namespace')
+ self.assertFalse(list(contents))
 # Even though there is a file in the namespace directory, it is not
 # considered a resource, since namespace packages can't have them.
 self.assertFalse(resources.is_resource(
diff --git a/Misc/NEWS.d/next/Library/2018-04-13-15-14-47.bpo-33254.DS4KFK.rst b/Misc/NEWS.d/next/Library/2018-04-13-15-14-47.bpo-33254.DS4KFK.rst
new file mode 100644
index 000000000000..c77a902524b8
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2018-04-13-15-14-47.bpo-33254.DS4KFK.rst
@@ -0,0 +1,3 @@
+Have :func:`importlib.resources.contents` and
+:meth:`importlib.abc.ResourceReader.contents` return an :term:`iterable` instead
+of an :term:`iterator`.


More information about the Python-checkins mailing list

AltStyle によって変換されたページ (->オリジナル) /