prolove.github.io
/
mypython
/Lib
/site-packages
/pkg_resources
/_vendor
/importlib_resources
/_compat.py
# flake8: noqa | |
import abc | |
import sys | |
import pathlib | |
from contextlib import suppress | |
if sys.version_info >= (3, 10): | |
from zipfile import Path as ZipPath # type: ignore | |
else: | |
from ..zipp import Path as ZipPath # type: ignore | |
try: | |
from typing import runtime_checkable # type: ignore | |
except ImportError: | |
def runtime_checkable(cls): # type: ignore | |
return cls | |
try: | |
from typing import Protocol # type: ignore | |
except ImportError: | |
Protocol = abc.ABC # type: ignore | |
class TraversableResourcesLoader: | |
""" | |
Adapt loaders to provide TraversableResources and other | |
compatibility. | |
Used primarily for Python 3.9 and earlier where the native | |
loaders do not yet implement TraversableResources. | |
""" | |
def __init__(self, spec): | |
self.spec = spec | |
def path(self): | |
return self.spec.origin | |
def get_resource_reader(self, name): | |
from . import readers, _adapters | |
def _zip_reader(spec): | |
with suppress(AttributeError): | |
return readers.ZipReader(spec.loader, spec.name) | |
def _namespace_reader(spec): | |
with suppress(AttributeError, ValueError): | |
return readers.NamespaceReader(spec.submodule_search_locations) | |
def _available_reader(spec): | |
with suppress(AttributeError): | |
return spec.loader.get_resource_reader(spec.name) | |
def _native_reader(spec): | |
reader = _available_reader(spec) | |
return reader if hasattr(reader, 'files') else None | |
def _file_reader(spec): | |
try: | |
path = pathlib.Path(self.path) | |
except TypeError: | |
return None | |
if path.exists(): | |
return readers.FileReader(self) | |
return ( | |
# native reader if it supplies 'files' | |
_native_reader(self.spec) | |
or | |
# local ZipReader if a zip module | |
_zip_reader(self.spec) | |
or | |
# local NamespaceReader if a namespace module | |
_namespace_reader(self.spec) | |
or | |
# local FileReader | |
_file_reader(self.spec) | |
# fallback - adapt the spec ResourceReader to TraversableReader | |
or _adapters.CompatibilityFiles(self.spec) | |
) | |
def wrap_spec(package): | |
""" | |
Construct a package spec with traversable compatibility | |
on the spec/loader/reader. | |
Supersedes _adapters.wrap_spec to use TraversableResourcesLoader | |
from above for older Python compatibility (<3.10). | |
""" | |
from . import _adapters | |
return _adapters.SpecLoaderAdapter(package.__spec__, TraversableResourcesLoader) | |