Skip to content

Commit c1823d9

Browse files
Revert "gh-121190: Emit a better error message from importlib.resources.files() when module spec is None" (#148460)"
This reverts commit 480edc1.
1 parent a45593a commit c1823d9

14 files changed

Lines changed: 202 additions & 197 deletions

File tree

Lib/importlib/resources/_common.py

Lines changed: 6 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@
77
import pathlib
88
import tempfile
99
import types
10-
from typing import Optional, cast
10+
from typing import cast, Optional, Union
1111

1212
from .abc import ResourceReader, Traversable
1313

14-
Package = types.ModuleType | str
14+
Package = Union[types.ModuleType, str]
1515
Anchor = Package
1616

1717

@@ -32,7 +32,7 @@ def get_resource_reader(package: types.ModuleType) -> Optional[ResourceReader]:
3232
# zipimport.zipimporter does not support weak references, resulting in a
3333
# TypeError. That seems terrible.
3434
spec = package.__spec__
35-
reader = getattr(spec.loader, 'get_resource_reader', None) # type: ignore[union-attr]
35+
reader = getattr(spec.loader, "get_resource_reader", None) # type: ignore[union-attr]
3636
if reader is None:
3737
return None
3838
return reader(spec.name) # type: ignore[union-attr]
@@ -50,7 +50,7 @@ def _(cand: str) -> types.ModuleType:
5050

5151
@resolve.register
5252
def _(cand: None) -> types.ModuleType:
53-
return resolve(_infer_caller().f_globals['__name__'])
53+
return resolve(_infer_caller().f_globals["__name__"])
5454

5555

5656
def _infer_caller():
@@ -62,7 +62,7 @@ def is_this_file(frame_info):
6262
return frame_info.filename == stack[0].filename
6363

6464
def is_wrapper(frame_info):
65-
return frame_info.function == 'wrapper'
65+
return frame_info.function == "wrapper"
6666

6767
stack = inspect.stack()
6868
not_this_file = itertools.filterfalse(is_this_file, stack)
@@ -71,19 +71,6 @@ def is_wrapper(frame_info):
7171
return next(callers).frame
7272

7373

74-
def _assert_spec(package: types.ModuleType) -> None:
75-
"""
76-
Provide a nicer error message when package is ``__main__``
77-
and its ``__spec__`` is ``None``
78-
(https://docs.python.org/3/reference/import.html#main-spec).
79-
"""
80-
if package.__spec__ is None:
81-
raise TypeError(
82-
f"Cannot access resources for '{package.__name__}' "
83-
"as it does not appear to correspond to an importable module (its __spec__ is None)."
84-
)
85-
86-
8774
def from_package(package: types.ModuleType):
8875
"""
8976
Return a Traversable object for the given package.
@@ -92,7 +79,6 @@ def from_package(package: types.ModuleType):
9279
# deferred for performance (python/cpython#109829)
9380
from ._adapters import wrap_spec
9481

95-
_assert_spec(package)
9682
spec = wrap_spec(package)
9783
reader = spec.loader.get_resource_reader(spec.name)
9884
return reader.files()
@@ -101,7 +87,7 @@ def from_package(package: types.ModuleType):
10187
@contextlib.contextmanager
10288
def _tempfile(
10389
reader,
104-
suffix='',
90+
suffix="",
10591
# gh-93353: Keep a reference to call os.remove() in late Python
10692
# finalization.
10793
*,

Lib/importlib/resources/abc.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,23 @@
22
import itertools
33
import os
44
import pathlib
5-
from collections.abc import Iterable, Iterator
65
from typing import (
76
Any,
87
BinaryIO,
8+
Iterable,
9+
Iterator,
910
Literal,
1011
NoReturn,
1112
Optional,
1213
Protocol,
1314
Text,
1415
TextIO,
16+
Union,
1517
overload,
1618
runtime_checkable,
1719
)
1820

19-
StrPath = str | os.PathLike[str]
21+
StrPath = Union[str, os.PathLike[str]]
2022

2123
__all__ = ["ResourceReader", "Traversable", "TraversableResources"]
2224

@@ -149,7 +151,9 @@ def open(self, mode: Literal['r'] = 'r', *args: Any, **kwargs: Any) -> TextIO: .
149151
def open(self, mode: Literal['rb'], *args: Any, **kwargs: Any) -> BinaryIO: ...
150152

151153
@abc.abstractmethod
152-
def open(self, mode: str = 'r', *args: Any, **kwargs: Any) -> TextIO | BinaryIO:
154+
def open(
155+
self, mode: str = 'r', *args: Any, **kwargs: Any
156+
) -> Union[TextIO, BinaryIO]:
153157
"""
154158
mode may be 'r' or 'rb' to open as text or binary. Return a handle
155159
suitable for reading (same as pathlib.Path.open).

Lib/importlib/resources/simple.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import abc
66
import io
77
import itertools
8-
from typing import BinaryIO
8+
from typing import BinaryIO, List
99

1010
from .abc import Traversable, TraversableResources
1111

@@ -24,14 +24,14 @@ def package(self) -> str:
2424
"""
2525

2626
@abc.abstractmethod
27-
def children(self) -> list['SimpleReader']:
27+
def children(self) -> List['SimpleReader']:
2828
"""
2929
Obtain an iterable of SimpleReader for available
3030
child containers (e.g. directories).
3131
"""
3232

3333
@abc.abstractmethod
34-
def resources(self) -> list[str]:
34+
def resources(self) -> List[str]:
3535
"""
3636
Obtain available named resources for this virtual package.
3737
"""

Lib/test/test_importlib/resources/_path.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import functools
22
import pathlib
3-
from typing import Protocol, Union, runtime_checkable
3+
from typing import Dict, Protocol, Union, runtime_checkable
44

55
####
66
# from jaraco.path 3.7.1
@@ -12,7 +12,7 @@ class Symlink(str):
1212
"""
1313

1414

15-
FilesSpec = dict[str, Union[str, bytes, Symlink, 'FilesSpec']]
15+
FilesSpec = Dict[str, Union[str, bytes, Symlink, 'FilesSpec']]
1616

1717

1818
@runtime_checkable
@@ -28,13 +28,13 @@ def write_bytes(self, content): ... # pragma: no cover
2828
def symlink_to(self, target): ... # pragma: no cover
2929

3030

31-
def _ensure_tree_maker(obj: str | TreeMaker) -> TreeMaker:
31+
def _ensure_tree_maker(obj: Union[str, TreeMaker]) -> TreeMaker:
3232
return obj if isinstance(obj, TreeMaker) else pathlib.Path(obj) # type: ignore[return-value]
3333

3434

3535
def build(
3636
spec: FilesSpec,
37-
prefix: str | TreeMaker = pathlib.Path(), # type: ignore[assignment]
37+
prefix: Union[str, TreeMaker] = pathlib.Path(), # type: ignore[assignment]
3838
):
3939
"""
4040
Build a set of files/directories, as described by the spec.
@@ -66,7 +66,7 @@ def build(
6666

6767

6868
@functools.singledispatch
69-
def create(content: str | bytes | FilesSpec, path):
69+
def create(content: Union[str, bytes, FilesSpec], path):
7070
path.mkdir(exist_ok=True)
7171
build(content, prefix=path) # type: ignore[arg-type]
7272

Lib/test/test_importlib/resources/test_compatibilty_files.py

Lines changed: 27 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -24,46 +24,51 @@ def files(self):
2424
return resources.files(self.package)
2525

2626
def test_spec_path_iter(self):
27-
assert sorted(path.name for path in self.files.iterdir()) == ['a', 'b', 'c']
27+
self.assertEqual(
28+
sorted(path.name for path in self.files.iterdir()),
29+
['a', 'b', 'c'],
30+
)
2831

2932
def test_child_path_iter(self):
30-
assert list((self.files / 'a').iterdir()) == []
33+
self.assertEqual(list((self.files / 'a').iterdir()), [])
3134

3235
def test_orphan_path_iter(self):
33-
assert list((self.files / 'a' / 'a').iterdir()) == []
34-
assert list((self.files / 'a' / 'a' / 'a').iterdir()) == []
36+
self.assertEqual(list((self.files / 'a' / 'a').iterdir()), [])
37+
self.assertEqual(list((self.files / 'a' / 'a' / 'a').iterdir()), [])
3538

3639
def test_spec_path_is(self):
37-
assert not self.files.is_file()
38-
assert not self.files.is_dir()
40+
self.assertFalse(self.files.is_file())
41+
self.assertFalse(self.files.is_dir())
3942

4043
def test_child_path_is(self):
41-
assert (self.files / 'a').is_file()
42-
assert not (self.files / 'a').is_dir()
44+
self.assertTrue((self.files / 'a').is_file())
45+
self.assertFalse((self.files / 'a').is_dir())
4346

4447
def test_orphan_path_is(self):
45-
assert not (self.files / 'a' / 'a').is_file()
46-
assert not (self.files / 'a' / 'a').is_dir()
47-
assert not (self.files / 'a' / 'a' / 'a').is_file()
48-
assert not (self.files / 'a' / 'a' / 'a').is_dir()
48+
self.assertFalse((self.files / 'a' / 'a').is_file())
49+
self.assertFalse((self.files / 'a' / 'a').is_dir())
50+
self.assertFalse((self.files / 'a' / 'a' / 'a').is_file())
51+
self.assertFalse((self.files / 'a' / 'a' / 'a').is_dir())
4952

5053
def test_spec_path_name(self):
51-
assert self.files.name == 'testingpackage'
54+
self.assertEqual(self.files.name, 'testingpackage')
5255

5356
def test_child_path_name(self):
54-
assert (self.files / 'a').name == 'a'
57+
self.assertEqual((self.files / 'a').name, 'a')
5558

5659
def test_orphan_path_name(self):
57-
assert (self.files / 'a' / 'b').name == 'b'
58-
assert (self.files / 'a' / 'b' / 'c').name == 'c'
60+
self.assertEqual((self.files / 'a' / 'b').name, 'b')
61+
self.assertEqual((self.files / 'a' / 'b' / 'c').name, 'c')
5962

6063
def test_spec_path_open(self):
61-
assert self.files.read_bytes() == b'Hello, world!'
62-
assert self.files.read_text(encoding='utf-8') == 'Hello, world!'
64+
self.assertEqual(self.files.read_bytes(), b'Hello, world!')
65+
self.assertEqual(self.files.read_text(encoding='utf-8'), 'Hello, world!')
6366

6467
def test_child_path_open(self):
65-
assert (self.files / 'a').read_bytes() == b'Hello, world!'
66-
assert (self.files / 'a').read_text(encoding='utf-8') == 'Hello, world!'
68+
self.assertEqual((self.files / 'a').read_bytes(), b'Hello, world!')
69+
self.assertEqual(
70+
(self.files / 'a').read_text(encoding='utf-8'), 'Hello, world!'
71+
)
6772

6873
def test_orphan_path_open(self):
6974
with self.assertRaises(FileNotFoundError):
@@ -81,7 +86,7 @@ def test_orphan_path_invalid(self):
8186

8287
def test_wrap_spec(self):
8388
spec = wrap_spec(self.package)
84-
assert isinstance(spec.loader.get_resource_reader(None), CompatibilityFiles)
89+
self.assertIsInstance(spec.loader.get_resource_reader(None), CompatibilityFiles)
8590

8691

8792
class CompatibilityFilesNoReaderTests(unittest.TestCase):
@@ -94,4 +99,4 @@ def files(self):
9499
return resources.files(self.package)
95100

96101
def test_spec_path_joinpath(self):
97-
assert isinstance(self.files / 'a', CompatibilityFiles.OrphanPath)
102+
self.assertIsInstance(self.files / 'a', CompatibilityFiles.OrphanPath)

Lib/test/test_importlib/resources/test_files.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ def test_traversable(self):
3737
def test_joinpath_with_multiple_args(self):
3838
files = resources.files(self.data)
3939
binfile = files.joinpath('subdirectory', 'binary.file')
40-
assert binfile.is_file()
40+
self.assertTrue(binfile.is_file())
4141

4242

4343
class OpenDiskTests(FilesTests, util.DiskSetup, unittest.TestCase):

0 commit comments

Comments
 (0)