New submission from William Schwartz <wkschwa...@gmail.com>:

Suppose pkg is a package, it contains a resource r, pkg.__spec__.origin is 
None, and p = importlib.resources.path(pkg, r). Then p.__enter__() raises a 
TypeError in Python 3.7 and 3.8. (The problem has been fixed in 3.9). The error 
can be demonstrated by running the attached path-test.py. The tracebacks in 3.7 
and 3.8 are nearly identical, so I'll just show the 3.8 traceback.

3.8.6 (default, Nov 20 2020, 18:29:40) 
[Clang 12.0.0 (clang-1200.0.32.27)]
Traceback (most recent call last):
  File "path-test.py", line 19, in <module>
    p.__enter__()  # Kaboom
  File 
"/usr/local/Cellar/python@3.8/3.8.6_2/Frameworks/Python.framework/Versions/3.8/lib/python3.8/contextlib.py",
 line 113, in __enter__
    return next(self.gen)
  File 
"/usr/local/Cellar/python@3.8/3.8.6_2/Frameworks/Python.framework/Versions/3.8/lib/python3.8/importlib/resources.py",
 line 196, in path
    package_directory = Path(package.__spec__.origin).parent
  File 
"/usr/local/Cellar/python@3.8/3.8.6_2/Frameworks/Python.framework/Versions/3.8/lib/python3.8/pathlib.py",
 line 1041, in __new__
    self = cls._from_parts(args, init=False)
  File 
"/usr/local/Cellar/python@3.8/3.8.6_2/Frameworks/Python.framework/Versions/3.8/lib/python3.8/pathlib.py",
 line 682, in _from_parts
    drv, root, parts = self._parse_args(args)
  File 
"/usr/local/Cellar/python@3.8/3.8.6_2/Frameworks/Python.framework/Versions/3.8/lib/python3.8/pathlib.py",
 line 666, in _parse_args
    a = os.fspath(a)
TypeError: expected str, bytes or os.PathLike object, not NoneType

The fix is super simple, as shown below. I'll submit this as a PR as well.

diff --git a/Lib/importlib/resources.py b/Lib/importlib/resources.py
index fc3a1c9cab..8d37d52cb8 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:

----------
components: Library (Lib)
files: path-test.py
messages: 382297
nosy: William.Schwartz, brett.cannon
priority: normal
severity: normal
status: open
title: importlib.resources.path() raises TypeError for packages without __file__
type: behavior
versions: Python 3.7, Python 3.8
Added file: https://bugs.python.org/file49643/path-test.py

_______________________________________
Python tracker <rep...@bugs.python.org>
<https://bugs.python.org/issue42531>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to