Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
_adapters.py169 linesDownload Raw Back to importlib_resources
1from contextlib import suppress2from io import TextIOWrapper3 4from . import abc5 6 7class SpecLoaderAdapter:8    """9    Adapt a package spec to adapt the underlying loader.10    """11 12    def __init__(self, spec, adapter=lambda spec: spec.loader):13        self.spec = spec14        self.loader = adapter(spec)15 16    def __getattr__(self, name):17        return getattr(self.spec, name)18 19 20class TraversableResourcesLoader:21    """22    Adapt a loader to provide TraversableResources.23    """24 25    def __init__(self, spec):26        self.spec = spec27 28    def get_resource_reader(self, name):29        return CompatibilityFiles(self.spec)._native()30 31 32def _io_wrapper(file, mode='r', *args, **kwargs):33    if mode == 'r':34        return TextIOWrapper(file, *args, **kwargs)35    elif mode == 'rb':36        return file37    raise ValueError(f"Invalid mode value '{mode}', only 'r' and 'rb' are supported")38 39 40class CompatibilityFiles:41    """42    Adapter for an existing or non-existent resource reader43    to provide a compatibility .files().44    """45 46    class SpecPath(abc.Traversable):47        """48        Path tied to a module spec.49        Can be read and exposes the resource reader children.50        """51 52        def __init__(self, spec, reader):53            self._spec = spec54            self._reader = reader55 56        def iterdir(self):57            if not self._reader:58                return iter(())59            return iter(60                CompatibilityFiles.ChildPath(self._reader, path)61                for path in self._reader.contents()62            )63 64        def is_file(self):65            return False66 67        is_dir = is_file68 69        def joinpath(self, other):70            if not self._reader:71                return CompatibilityFiles.OrphanPath(other)72            return CompatibilityFiles.ChildPath(self._reader, other)73 74        @property75        def name(self):76            return self._spec.name77 78        def open(self, mode='r', *args, **kwargs):79            return _io_wrapper(self._reader.open_resource(None), mode, *args, **kwargs)80 81    class ChildPath(abc.Traversable):82        """83        Path tied to a resource reader child.84        Can be read but doesn't expose any meaningful children.85        """86 87        def __init__(self, reader, name):88            self._reader = reader89            self._name = name90 91        def iterdir(self):92            return iter(())93 94        def is_file(self):95            return self._reader.is_resource(self.name)96 97        def is_dir(self):98            return not self.is_file()99 100        def joinpath(self, other):101            return CompatibilityFiles.OrphanPath(self.name, other)102 103        @property104        def name(self):105            return self._name106 107        def open(self, mode='r', *args, **kwargs):108            return _io_wrapper(109                self._reader.open_resource(self.name), mode, *args, **kwargs110            )111 112    class OrphanPath(abc.Traversable):113        """114        Orphan path, not tied to a module spec or resource reader.115        Can't be read and doesn't expose any meaningful children.116        """117 118        def __init__(self, *path_parts):119            if len(path_parts) < 1:120                raise ValueError('Need at least one path part to construct a path')121            self._path = path_parts122 123        def iterdir(self):124            return iter(())125 126        def is_file(self):127            return False128 129        is_dir = is_file130 131        def joinpath(self, other):132            return CompatibilityFiles.OrphanPath(*self._path, other)133 134        @property135        def name(self):136            return self._path[-1]137 138        def open(self, mode='r', *args, **kwargs):139            raise FileNotFoundError("Can't open orphan path")140 141    def __init__(self, spec):142        self.spec = spec143 144    @property145    def _reader(self):146        with suppress(AttributeError):147            return self.spec.loader.get_resource_reader(self.spec.name)148 149    def _native(self):150        """151        Return the native reader if it supports files().152        """153        reader = self._reader154        return reader if hasattr(reader, 'files') else self155 156    def __getattr__(self, attr):157        return getattr(self._reader, attr)158 159    def files(self):160        return CompatibilityFiles.SpecPath(self.spec, self._reader)161 162 163def wrap_spec(package):164    """165    Construct a package spec with traversable compatibility166    on the spec/loader/reader.167    """168    return SpecLoaderAdapter(package.__spec__, TraversableResourcesLoader)169