7 from contextlib
import suppress
8 from typing
import Union
11 if sys
.version_info
>= (3, 10):
12 from zipfile
import Path
as ZipPath
# type: ignore
14 from ..zipp
import Path
as ZipPath
# type: ignore
18 from typing
import runtime_checkable
# type: ignore
21 def runtime_checkable(cls
): # type: ignore
26 from typing
import Protocol
# type: ignore
28 Protocol
= abc
.ABC
# type: ignore
31 class TraversableResourcesLoader
:
33 Adapt loaders to provide TraversableResources and other
36 Used primarily for Python 3.9 and earlier where the native
37 loaders do not yet implement TraversableResources.
40 def __init__(self
, spec
):
45 return self
.spec
.origin
47 def get_resource_reader(self
, name
):
48 from . import readers
, _adapters
50 def _zip_reader(spec
):
51 with suppress(AttributeError):
52 return readers
.ZipReader(spec
.loader
, spec
.name
)
54 def _namespace_reader(spec
):
55 with suppress(AttributeError, ValueError):
56 return readers
.NamespaceReader(spec
.submodule_search_locations
)
58 def _available_reader(spec
):
59 with suppress(AttributeError):
60 return spec
.loader
.get_resource_reader(spec
.name
)
62 def _native_reader(spec
):
63 reader
= _available_reader(spec
)
64 return reader
if hasattr(reader
, 'files') else None
66 def _file_reader(spec
):
68 path
= pathlib
.Path(self
.path
)
72 return readers
.FileReader(self
)
75 # native reader if it supplies 'files'
76 _native_reader(self
.spec
)
78 # local ZipReader if a zip module
79 _zip_reader(self
.spec
)
81 # local NamespaceReader if a namespace module
82 _namespace_reader(self
.spec
)
85 _file_reader(self
.spec
)
86 # fallback - adapt the spec ResourceReader to TraversableReader
87 or _adapters
.CompatibilityFiles(self
.spec
)
91 def wrap_spec(package
):
93 Construct a package spec with traversable compatibility
94 on the spec/loader/reader.
96 Supersedes _adapters.wrap_spec to use TraversableResourcesLoader
97 from above for older Python compatibility (<3.10).
99 from . import _adapters
101 return _adapters
.SpecLoaderAdapter(package
.__spec
__, TraversableResourcesLoader
)
104 if sys
.version_info
>= (3, 9):
105 StrPath
= Union
[str, os
.PathLike
[str]]
107 # PathLike is only subscriptable at runtime in 3.9+
108 StrPath
= Union
[str, "os.PathLike[str]"]