Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/importlib_resources/_compat.py: 76%
58 statements
« prev ^ index » next coverage.py v7.3.2, created at 2023-12-08 06:51 +0000
« prev ^ index » next coverage.py v7.3.2, created at 2023-12-08 06:51 +0000
1# flake8: noqa
3import abc
4import os
5import sys
6import pathlib
7import warnings
8from contextlib import suppress
9from typing import Union
12if sys.version_info >= (3, 10):
13 from zipfile import Path as ZipPath # type: ignore
14else:
15 from zipp import Path as ZipPath # type: ignore
18try:
19 from typing import runtime_checkable # type: ignore
20except ImportError:
22 def runtime_checkable(cls): # type: ignore
23 return cls
26try:
27 from typing import Protocol # type: ignore
28except ImportError:
29 Protocol = abc.ABC # type: ignore
32class TraversableResourcesLoader:
33 """
34 Adapt loaders to provide TraversableResources and other
35 compatibility.
37 Used primarily for Python 3.9 and earlier where the native
38 loaders do not yet implement TraversableResources.
39 """
41 def __init__(self, spec):
42 self.spec = spec
44 @property
45 def path(self):
46 return self.spec.origin
48 def get_resource_reader(self, name):
49 from . import readers, _adapters
51 def _zip_reader(spec):
52 with suppress(AttributeError):
53 return readers.ZipReader(spec.loader, spec.name)
55 def _namespace_reader(spec):
56 with suppress(AttributeError, ValueError):
57 return readers.NamespaceReader(spec.submodule_search_locations)
59 def _available_reader(spec):
60 with suppress(AttributeError):
61 return spec.loader.get_resource_reader(spec.name)
63 def _native_reader(spec):
64 reader = _available_reader(spec)
65 return reader if hasattr(reader, 'files') else None
67 def _file_reader(spec):
68 try:
69 path = pathlib.Path(self.path)
70 except TypeError:
71 return None
72 if path.exists():
73 return readers.FileReader(self)
75 return (
76 # local ZipReader if a zip module
77 _zip_reader(self.spec)
78 or
79 # local NamespaceReader if a namespace module
80 _namespace_reader(self.spec)
81 or
82 # local FileReader
83 _file_reader(self.spec)
84 or
85 # native reader if it supplies 'files'
86 _native_reader(self.spec)
87 or
88 # fallback - adapt the spec ResourceReader to TraversableReader
89 _adapters.CompatibilityFiles(self.spec)
90 )
93def wrap_spec(package):
94 """
95 Construct a package spec with traversable compatibility
96 on the spec/loader/reader.
98 Supersedes _adapters.wrap_spec to use TraversableResourcesLoader
99 from above for older Python compatibility (<3.10).
100 """
101 from . import _adapters
103 return _adapters.SpecLoaderAdapter(package.__spec__, TraversableResourcesLoader)
106if sys.version_info >= (3, 9):
107 StrPath = Union[str, os.PathLike[str]]
108else:
109 # PathLike is only subscriptable at runtime in 3.9+
110 StrPath = Union[str, "os.PathLike[str]"]
113def ensure_traversable(path):
114 """
115 Convert deprecated string arguments to traversables (pathlib.Path).
116 """
117 if not isinstance(path, str):
118 return path
120 warnings.warn(
121 "String arguments are deprecated. Pass a Traversable instead.",
122 DeprecationWarning,
123 stacklevel=3,
124 )
126 return pathlib.Path(path)