Skip to content

Commit a7b1b80

Browse files
committed
Re-implement _block_standard as a wrapper function around _adapters.TraversableResourcesLoader and ensure that the known standard readers are replaced by readers from importlib_resources.
1 parent 527173b commit a7b1b80

File tree

1 file changed

+38
-13
lines changed

1 file changed

+38
-13
lines changed

importlib_resources/future/adapters.py

Lines changed: 38 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,44 @@
1-
import contextlib
1+
import functools
22
import pathlib
33
from contextlib import suppress
44
from types import SimpleNamespace
55

66
from .. import readers, _adapters
77

88

9+
def _block_standard(reader_getter):
10+
"""
11+
Wrap _adapters.TraversableResourcesLoader.get_resource_reader
12+
and intercept any standard library readers.
13+
"""
14+
15+
@functools.wraps(reader_getter)
16+
def wrapper(*args, **kwargs):
17+
"""
18+
If the reader is from the standard library, return None to allow
19+
allow likely newer implementations in this library to take precedence.
20+
"""
21+
try:
22+
reader = reader_getter(*args, **kwargs)
23+
except NotADirectoryError:
24+
# MultiplexedPath may fail on zip subdirectory
25+
return
26+
# Python 3.10+
27+
if reader.__class__.__module__.startswith('importlib.resources.'):
28+
return
29+
# Python 3.8, 3.9
30+
if isinstance(reader, _adapters.CompatibilityFiles) and (
31+
reader.spec.loader.__class__.__module__.startswith('zipimport')
32+
or reader.spec.loader.__class__.__module__.startswith(
33+
'_frozen_importlib_external'
34+
)
35+
):
36+
return
37+
return reader
38+
39+
return wrapper
40+
41+
942
class TraversableResourcesLoader(_adapters.TraversableResourcesLoader):
1043
"""
1144
Adapt loaders to provide TraversableResources and other
@@ -16,18 +49,10 @@ class TraversableResourcesLoader(_adapters.TraversableResourcesLoader):
1649
"""
1750

1851
def get_resource_reader(self, name):
19-
with contextlib.suppress(Exception):
20-
return self._block_standard(super().get_resource_reader(name))
21-
return self._standard_reader()
22-
23-
def _block_standard(self, reader):
24-
"""
25-
If the reader is from the standard library, raise an exception to
26-
allow likely newer implementations in this library to take precedence.
27-
"""
28-
if reader.__class__.__module__.startswith('importlib.resources.'):
29-
raise RuntimeError("Reader blocked to be superseded.")
30-
return reader
52+
return (
53+
_block_standard(super().get_resource_reader)(name)
54+
or self._standard_reader()
55+
)
3156

3257
def _standard_reader(self):
3358
return self._zip_reader() or self._namespace_reader() or self._file_reader()

0 commit comments

Comments
 (0)