Fix bpo-42531: Teach importlib.resources.path to handle packages without __file__

This commit is contained in:
William Schwartz 2020-12-02 00:28:03 -06:00
parent d9d63f13cf
commit f1d2ac8590
2 changed files with 17 additions and 3 deletions

View 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:

View File

@ -1,3 +1,4 @@
from test.support import swap_attr
import unittest
from importlib import resources
@ -26,6 +27,17 @@ class PathTests:
class PathDiskTests(PathTests, unittest.TestCase):
data = data01
def test_package_spec_origin_is_None(self):
import pydoc_data
spec = pydoc_data.__spec__
# Emulate importing from non-file source by setting spec.origin = None.
# Barge past path's sanity checks by ensuring spec.loader.is_resource
# returns False.
with swap_attr(spec, "origin", None), \
swap_attr(spec.loader, "is_resource", lambda *args: False), \
resources.path(pydoc_data, '_pydoc.css') as p:
pass
class PathZipTests(PathTests, util.ZipSetup, unittest.TestCase):
def test_remove_in_context_manager(self):