[Python-checkins] [3.8] bpo-42531: Teach importlib.resources.path to handle packages without __file__ (GH-23611)
miss-islington
webhook-mailer at python.org
Sat Jan 16 12:22:30 EST 2021
https://github.com/python/cpython/commit/f08c66467d56c71f75c6659ede9177449fe9d2e6
commit: f08c66467d56c71f75c6659ede9177449fe9d2e6
branch: 3.8
author: William Schwartz <wkschwartz at gmail.com>
committer: miss-islington <31488909+miss-islington at users.noreply.github.com>
date: 2021-01-16T09:22:21-08:00
summary:
[3.8] bpo-42531: Teach importlib.resources.path to handle packages without __file__ (GH-23611)
Fixes [bpo-42531]() for Python 3.8.
The issue also applies to 3.7. If this PR looks like it'll be accepted, I can cherry-pick it to the 3.7 branch and submit a follow-up PR.
Automerge-Triggered-By: GH:jaraco
files:
A Misc/NEWS.d/next/Library/2020-12-02-16-28-04.bpo-42531.2sLlFW.rst
M Lib/importlib/resources.py
M Lib/test/test_importlib/test_path.py
diff --git a/Lib/importlib/resources.py b/Lib/importlib/resources.py
index fc3a1c9cabe63..8d37d52cb8d37 100644
--- a/Lib/importlib/resources.py
+++ b/Lib/importlib/resources.py
@@ -193,9 +193,11 @@ def path(package: Package, resource: Resource) -> Iterator[Path]:
_check_location(package)
# Fall-through for both the lack of resource_path() *and* if
# resource_path() raises FileNotFoundError.
- package_directory = Path(package.__spec__.origin).parent
- file_path = package_directory / resource
- if file_path.exists():
+ file_path = None
+ if package.__spec__.origin is not None:
+ package_directory = Path(package.__spec__.origin).parent
+ file_path = package_directory / resource
+ if file_path is not None and file_path.exists():
yield file_path
else:
with open_binary(package, resource) as fp:
diff --git a/Lib/test/test_importlib/test_path.py b/Lib/test/test_importlib/test_path.py
index 2d3dcda7ed2e7..5c5a8e3d76e79 100644
--- a/Lib/test/test_importlib/test_path.py
+++ b/Lib/test/test_importlib/test_path.py
@@ -1,3 +1,4 @@
+import io
import unittest
from importlib import resources
@@ -27,6 +28,17 @@ class PathDiskTests(PathTests, unittest.TestCase):
data = data01
+class PathMemoryTests(PathTests, unittest.TestCase):
+ def setUp(self):
+ file = io.BytesIO(b'Hello, UTF-8 world!\n')
+ self.addCleanup(file.close)
+ self.data = util.create_package(
+ file=file, path=FileNotFoundError("package exists only in memory")
+ )
+ self.data.__spec__.origin = None
+ self.data.__spec__.has_location = False
+
+
class PathZipTests(PathTests, util.ZipSetup, unittest.TestCase):
def test_remove_in_context_manager(self):
# It is not an error if the file that was temporarily stashed on the
diff --git a/Misc/NEWS.d/next/Library/2020-12-02-16-28-04.bpo-42531.2sLlFW.rst b/Misc/NEWS.d/next/Library/2020-12-02-16-28-04.bpo-42531.2sLlFW.rst
new file mode 100644
index 0000000000000..7927078acda43
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2020-12-02-16-28-04.bpo-42531.2sLlFW.rst
@@ -0,0 +1 @@
+:func:`importlib.resources.path` now works for :term:`package`\ s missing the optional :attr:`__file__` attribute (more specifically, packages whose :attr:`__spec__`\ ``.``\ :attr:`~importlib.machinery.ModuleSpec.origin` :keyword:`is` :data:`None`).
\ No newline at end of file
More information about the Python-checkins
mailing list