Skip to content

Commit

Permalink
Re-implement _block_standard as a wrapper function around _adapters.T…
Browse files Browse the repository at this point in the history
…raversableResourcesLoader and ensure that the known standard readers are replaced by readers from importlib_resources.
  • Loading branch information
jaraco committed Mar 6, 2024
1 parent 527173b commit a7b1b80
Showing 1 changed file with 38 additions and 13 deletions.
51 changes: 38 additions & 13 deletions importlib_resources/future/adapters.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,44 @@
import contextlib
import functools
import pathlib
from contextlib import suppress
from types import SimpleNamespace

from .. import readers, _adapters


def _block_standard(reader_getter):
"""
Wrap _adapters.TraversableResourcesLoader.get_resource_reader
and intercept any standard library readers.
"""

@functools.wraps(reader_getter)
def wrapper(*args, **kwargs):
"""
If the reader is from the standard library, return None to allow
allow likely newer implementations in this library to take precedence.
"""
try:
reader = reader_getter(*args, **kwargs)
except NotADirectoryError:
# MultiplexedPath may fail on zip subdirectory
return
# Python 3.10+
if reader.__class__.__module__.startswith('importlib.resources.'):
return
# Python 3.8, 3.9
if isinstance(reader, _adapters.CompatibilityFiles) and (
reader.spec.loader.__class__.__module__.startswith('zipimport')
or reader.spec.loader.__class__.__module__.startswith(
'_frozen_importlib_external'
)
):
return
return reader

return wrapper


class TraversableResourcesLoader(_adapters.TraversableResourcesLoader):
"""
Adapt loaders to provide TraversableResources and other
Expand All @@ -16,18 +49,10 @@ class TraversableResourcesLoader(_adapters.TraversableResourcesLoader):
"""

def get_resource_reader(self, name):
with contextlib.suppress(Exception):
return self._block_standard(super().get_resource_reader(name))
return self._standard_reader()

def _block_standard(self, reader):
"""
If the reader is from the standard library, raise an exception to
allow likely newer implementations in this library to take precedence.
"""
if reader.__class__.__module__.startswith('importlib.resources.'):
raise RuntimeError("Reader blocked to be superseded.")
return reader
return (
_block_standard(super().get_resource_reader)(name)
or self._standard_reader()
)

def _standard_reader(self):
return self._zip_reader() or self._namespace_reader() or self._file_reader()
Expand Down

0 comments on commit a7b1b80

Please sign in to comment.