Skip to content

Commit 47b3f09

Browse files
committed
A better error message from importlib.resources.files() when module spec is None from python/cpython#138531
1 parent 89fcc4b commit 47b3f09

3 files changed

Lines changed: 22 additions & 3 deletions

File tree

importlib_resources/_adapters.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -160,9 +160,9 @@ def files(self):
160160
return CompatibilityFiles.SpecPath(self.spec, self._reader)
161161

162162

163-
def wrap_spec(package):
163+
def wrap_spec(spec):
164164
"""
165165
Construct a package spec with traversable compatibility
166166
on the spec/loader/reader.
167167
"""
168-
return SpecLoaderAdapter(package.__spec__, TraversableResourcesLoader)
168+
return SpecLoaderAdapter(spec, TraversableResourcesLoader)

importlib_resources/_common.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,13 @@ def from_package(package: types.ModuleType):
113113
# deferred for performance (python/cpython#109829)
114114
from .future.adapters import wrap_spec
115115

116-
spec = wrap_spec(package)
116+
if package.__spec__ is None:
117+
raise TypeError(
118+
f"Cannot access resources for '{package.__name__ or package!r}' "
119+
"as it does not appear to correspond to an importable module (its __spec__ is None)."
120+
)
121+
122+
spec = wrap_spec(package.__spec__)
117123
reader = spec.loader.get_resource_reader(spec.name)
118124
return reader.files()
119125

importlib_resources/tests/test_resource.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import types
12
import unittest
23
from importlib import import_module
34

@@ -234,5 +235,17 @@ class ResourceFromNamespaceZipTests(
234235
MODULE = 'namespacedata01'
235236

236237

238+
class ResourceFromMainModuleWithNoneSpecTests(unittest.TestCase):
239+
# `__main__.__spec__` can be `None` depending on how it is populated.
240+
# https://docs.python.org/3/reference/import.html#main-spec
241+
def test_main_module_with_none_spec(self):
242+
mainmodule = types.ModuleType("__main__")
243+
244+
self.assertIsNone(mainmodule.__spec__)
245+
246+
with self.assertRaises(TypeError, msg="Cannot access resources for '__main__' as it does not appear to correspond to an importable module (its __spec__ is None)."):
247+
resources.files(mainmodule)
248+
249+
237250
if __name__ == '__main__':
238251
unittest.main()

0 commit comments

Comments
 (0)