]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.8] bpo-42531: Teach importlib.resources.path to handle packages without __file__...
authorWilliam Schwartz <wkschwartz@gmail.com>
Sat, 16 Jan 2021 17:22:21 +0000 (11:22 -0600)
committerGitHub <noreply@github.com>
Sat, 16 Jan 2021 17:22:21 +0000 (09:22 -0800)
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
Lib/importlib/resources.py
Lib/test/test_importlib/test_path.py
Misc/NEWS.d/next/Library/2020-12-02-16-28-04.bpo-42531.2sLlFW.rst [new file with mode: 0644]

index fc3a1c9cabe636bb88be89c27225ebf66a8e5967..8d37d52cb8d37efd362c84cc3857a967dca05e1d 100644 (file)
@@ -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:
index 2d3dcda7ed2e7998381846a92ff62794e7c6dfb2..5c5a8e3d76e79e02ffcb13e866bab94fe072a631 100644 (file)
@@ -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 (file)
index 0000000..7927078
--- /dev/null
@@ -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