Skip to content

Commit daa2578

Browse files
authored
gh-127012: Traversable.read_text now allows/solicits an errors parameter. (#148401)
Applies changes from importlib_resources 6.5.2.
1 parent 20994b1 commit daa2578

File tree

19 files changed

+254
-86
lines changed

19 files changed

+254
-86
lines changed

Lib/importlib/resources/__init__.py

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,11 @@
88
"""
99

1010
from ._common import (
11+
Anchor,
12+
Package,
1113
as_file,
1214
files,
13-
Package,
14-
Anchor,
1515
)
16-
1716
from ._functional import (
1817
contents,
1918
is_resource,
@@ -23,10 +22,8 @@
2322
read_binary,
2423
read_text,
2524
)
26-
2725
from .abc import ResourceReader
2826

29-
3027
__all__ = [
3128
'Package',
3229
'Anchor',

Lib/importlib/resources/_common.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
1-
import os
2-
import pathlib
3-
import tempfile
4-
import functools
51
import contextlib
6-
import types
2+
import functools
73
import importlib
84
import inspect
95
import itertools
6+
import os
7+
import pathlib
8+
import tempfile
9+
import types
10+
from typing import cast, Optional, Union
1011

11-
from typing import Union, Optional, cast
1212
from .abc import ResourceReader, Traversable
1313

1414
Package = Union[types.ModuleType, str]
@@ -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)
@@ -87,7 +87,7 @@ def from_package(package: types.ModuleType):
8787
@contextlib.contextmanager
8888
def _tempfile(
8989
reader,
90-
suffix='',
90+
suffix="",
9191
# gh-93353: Keep a reference to call os.remove() in late Python
9292
# finalization.
9393
*,

Lib/importlib/resources/_functional.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22

33
import warnings
44

5-
from ._common import files, as_file
6-
5+
from ._common import as_file, files
6+
from .abc import TraversalError
77

88
_MISSING = object()
99

@@ -42,7 +42,10 @@ def is_resource(anchor, *path_names):
4242
4343
Otherwise returns ``False``.
4444
"""
45-
return _get_resource(anchor, path_names).is_file()
45+
try:
46+
return _get_resource(anchor, path_names).is_file()
47+
except TraversalError:
48+
return False
4649

4750

4851
def contents(anchor, *path_names):

Lib/importlib/resources/abc.py

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,22 @@
11
import abc
2-
import io
32
import itertools
43
import os
54
import pathlib
6-
from typing import Any, BinaryIO, Iterable, Iterator, NoReturn, Text, Optional
7-
from typing import runtime_checkable, Protocol
8-
from typing import Union
9-
5+
from typing import (
6+
Any,
7+
BinaryIO,
8+
Iterable,
9+
Iterator,
10+
Literal,
11+
NoReturn,
12+
Optional,
13+
Protocol,
14+
Text,
15+
TextIO,
16+
Union,
17+
overload,
18+
runtime_checkable,
19+
)
1020

1121
StrPath = Union[str, os.PathLike[str]]
1222

@@ -82,11 +92,13 @@ def read_bytes(self) -> bytes:
8292
with self.open('rb') as strm:
8393
return strm.read()
8494

85-
def read_text(self, encoding: Optional[str] = None) -> str:
95+
def read_text(
96+
self, encoding: Optional[str] = None, errors: Optional[str] = None
97+
) -> str:
8698
"""
8799
Read contents of self as text
88100
"""
89-
with self.open(encoding=encoding) as strm:
101+
with self.open(encoding=encoding, errors=errors) as strm:
90102
return strm.read()
91103

92104
@abc.abstractmethod
@@ -132,8 +144,16 @@ def __truediv__(self, child: StrPath) -> "Traversable":
132144
"""
133145
return self.joinpath(child)
134146

147+
@overload
148+
def open(self, mode: Literal['r'] = 'r', *args: Any, **kwargs: Any) -> TextIO: ...
149+
150+
@overload
151+
def open(self, mode: Literal['rb'], *args: Any, **kwargs: Any) -> BinaryIO: ...
152+
135153
@abc.abstractmethod
136-
def open(self, mode='r', *args, **kwargs):
154+
def open(
155+
self, mode: str = 'r', *args: Any, **kwargs: Any
156+
) -> Union[TextIO, BinaryIO]:
137157
"""
138158
mode may be 'r' or 'rb' to open as text or binary. Return a handle
139159
suitable for reading (same as pathlib.Path.open).
@@ -160,7 +180,7 @@ class TraversableResources(ResourceReader):
160180
def files(self) -> "Traversable":
161181
"""Return a Traversable object for the loaded package."""
162182

163-
def open_resource(self, resource: StrPath) -> io.BufferedReader:
183+
def open_resource(self, resource: StrPath) -> BinaryIO:
164184
return self.files().joinpath(resource).open('rb')
165185

166186
def resource_path(self, resource: Any) -> NoReturn:

Lib/importlib/resources/readers.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,14 @@
33
import collections
44
import contextlib
55
import itertools
6-
import pathlib
76
import operator
7+
import pathlib
88
import re
99
import warnings
1010
import zipfile
1111
from collections.abc import Iterator
1212

1313
from . import abc
14-
1514
from ._itertools import only
1615

1716

Lib/test/test_importlib/resources/_path.py

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
1-
import pathlib
21
import functools
3-
4-
from typing import Dict, Union
5-
from typing import runtime_checkable
6-
from typing import Protocol
7-
2+
import pathlib
3+
from typing import Dict, Protocol, Union, runtime_checkable
84

95
####
106
# from jaraco.path 3.7.1

Lib/test/test_importlib/resources/test_compatibilty_files.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
1+
import importlib.resources as resources
12
import io
23
import unittest
3-
4-
from importlib import resources
5-
64
from importlib.resources._adapters import (
75
CompatibilityFiles,
86
wrap_spec,

Lib/test/test_importlib/resources/test_contents.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1+
import importlib.resources as resources
12
import unittest
2-
from importlib import resources
33

44
from . import util
55

Lib/test/test_importlib/resources/test_custom.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
import unittest
21
import contextlib
2+
import importlib.resources as resources
33
import pathlib
4+
import unittest
5+
from importlib.resources import abc
6+
from importlib.resources.abc import ResourceReader, TraversableResources
47

58
from test.support import os_helper
69

7-
from importlib import resources
8-
from importlib.resources import abc
9-
from importlib.resources.abc import TraversableResources, ResourceReader
1010
from . import util
1111

1212

Lib/test/test_importlib/resources/test_files.py

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
1+
import contextlib
2+
import importlib
3+
import importlib.resources as resources
14
import pathlib
25
import py_compile
36
import textwrap
47
import unittest
58
import warnings
6-
import importlib
7-
import contextlib
8-
9-
from importlib import resources
109
from importlib.resources.abc import Traversable
10+
11+
from test.support import import_helper, os_helper
12+
1113
from . import util
12-
from test.support import os_helper, import_helper
1314

1415

1516
@contextlib.contextmanager
@@ -62,7 +63,7 @@ def test_non_paths_in_dunder_path(self):
6263
to cause the ``PathEntryFinder`` to be called when searching
6364
for packages. In that case, resources should still be loadable.
6465
"""
65-
import namespacedata01
66+
import namespacedata01 # type: ignore[import-not-found]
6667

6768
namespacedata01.__path__.append(
6869
'__editable__.sample_namespace-1.0.finder.__path_hook__'
@@ -153,7 +154,9 @@ def _compile_importlib(self):
153154
sources = pathlib.Path(resources.__file__).parent
154155

155156
for source_path in sources.glob('**/*.py'):
156-
c_path = c_resources.joinpath(source_path.relative_to(sources)).with_suffix('.pyc')
157+
c_path = c_resources.joinpath(source_path.relative_to(sources)).with_suffix(
158+
'.pyc'
159+
)
157160
py_compile.compile(source_path, c_path)
158161
self.fixtures.enter_context(import_helper.DirsOnSysPath(bin_site))
159162

0 commit comments

Comments
 (0)