8000 [3.8] bpo-42531: Teach importlib.resources.path to handle packages wi… · python/cpython@f08c664 · GitHub
[go: up one dir, main page]

Skip to content

Commit f08c664

Browse files
authored
[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
1 parent 187f76d commit f08c664

File tree

3 files changed

+18
-3
lines changed

3 files changed

+18
-3
lines changed

Lib/importlib/resources.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -193,9 +193,11 @@ def path(package: Package, resource: Resource) -> Iterator[Path]:
193193
_check_location(package)
194194
# Fall-through for both the lack of resource_path() *and* if
195195
# resource_path() raises FileNotFoundError.
196-
package_directory = Path(package.__spec__.origin).parent
197-
file_path = package_directory / resource
198-
if file_path.exists():
196+
file_path = None
197+
if package.__spec__.origin is not None:
198+
package_directory = Path(package.__spec__.origin).parent
199+
file_path = package_directory / resource
200+
if file_path is not None and file_path.exists():
199201
yield file_path
200202
else:
201203
with open_binary(package, resource) as fp:

Lib/test/test_importlib/test_path.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import io
12
import unittest
23

34
from importlib import resources
@@ -27,6 +28,17 @@ class PathDiskTests(PathTests, unittest.TestCase):
2728
data = data01
2829

2930

31+
class PathMemoryTests(PathTests, unittest.TestCase):
32+
def setUp(self):
33+
file = io.BytesIO(b'Hello, UTF-8 world!\n')
34+
self.addCleanup(file.close)
35+
self.data = util.create_package(
36+
file=file, path=FileNotFoundError("package exists only in memory")
37+
)
38+
self.data.__spec__.origin = None
39+
self.data.__spec__.has_location = False
40+
41+
3042
class PathZipTests(PathTests, util.ZipSetup, unittest.TestCase):
3143
def test_remove_in_context_manager(self):
3244
# It is not an error if the file that was temporarily stashed on the
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
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`).

0 commit comments

Comments
 (0)
0