]> jfr.im git - dlqueue.git/blame - venv/lib/python3.11/site-packages/setuptools/_vendor/importlib_resources/abc.py
init: venv aand flask
[dlqueue.git] / venv / lib / python3.11 / site-packages / setuptools / _vendor / importlib_resources / abc.py
CommitLineData
e0df8241
JR
1import abc
2import io
3import itertools
4import pathlib
5from typing import Any, BinaryIO, Iterable, Iterator, NoReturn, Text, Optional
6
7from ._compat import runtime_checkable, Protocol, StrPath
8
9
10__all__ = ["ResourceReader", "Traversable", "TraversableResources"]
11
12
13class ResourceReader(metaclass=abc.ABCMeta):
14 """Abstract base class for loaders to provide resource reading support."""
15
16 @abc.abstractmethod
17 def open_resource(self, resource: Text) -> BinaryIO:
18 """Return an opened, file-like object for binary reading.
19
20 The 'resource' argument is expected to represent only a file name.
21 If the resource cannot be found, FileNotFoundError is raised.
22 """
23 # This deliberately raises FileNotFoundError instead of
24 # NotImplementedError so that if this method is accidentally called,
25 # it'll still do the right thing.
26 raise FileNotFoundError
27
28 @abc.abstractmethod
29 def resource_path(self, resource: Text) -> Text:
30 """Return the file system path to the specified resource.
31
32 The 'resource' argument is expected to represent only a file name.
33 If the resource does not exist on the file system, raise
34 FileNotFoundError.
35 """
36 # This deliberately raises FileNotFoundError instead of
37 # NotImplementedError so that if this method is accidentally called,
38 # it'll still do the right thing.
39 raise FileNotFoundError
40
41 @abc.abstractmethod
42 def is_resource(self, path: Text) -> bool:
43 """Return True if the named 'path' is a resource.
44
45 Files are resources, directories are not.
46 """
47 raise FileNotFoundError
48
49 @abc.abstractmethod
50 def contents(self) -> Iterable[str]:
51 """Return an iterable of entries in `package`."""
52 raise FileNotFoundError
53
54
55class TraversalError(Exception):
56 pass
57
58
59@runtime_checkable
60class Traversable(Protocol):
61 """
62 An object with a subset of pathlib.Path methods suitable for
63 traversing directories and opening files.
64
65 Any exceptions that occur when accessing the backing resource
66 may propagate unaltered.
67 """
68
69 @abc.abstractmethod
70 def iterdir(self) -> Iterator["Traversable"]:
71 """
72 Yield Traversable objects in self
73 """
74
75 def read_bytes(self) -> bytes:
76 """
77 Read contents of self as bytes
78 """
79 with self.open('rb') as strm:
80 return strm.read()
81
82 def read_text(self, encoding: Optional[str] = None) -> str:
83 """
84 Read contents of self as text
85 """
86 with self.open(encoding=encoding) as strm:
87 return strm.read()
88
89 @abc.abstractmethod
90 def is_dir(self) -> bool:
91 """
92 Return True if self is a directory
93 """
94
95 @abc.abstractmethod
96 def is_file(self) -> bool:
97 """
98 Return True if self is a file
99 """
100
101 def joinpath(self, *descendants: StrPath) -> "Traversable":
102 """
103 Return Traversable resolved with any descendants applied.
104
105 Each descendant should be a path segment relative to self
106 and each may contain multiple levels separated by
107 ``posixpath.sep`` (``/``).
108 """
109 if not descendants:
110 return self
111 names = itertools.chain.from_iterable(
112 path.parts for path in map(pathlib.PurePosixPath, descendants)
113 )
114 target = next(names)
115 matches = (
116 traversable for traversable in self.iterdir() if traversable.name == target
117 )
118 try:
119 match = next(matches)
120 except StopIteration:
121 raise TraversalError(
122 "Target not found during traversal.", target, list(names)
123 )
124 return match.joinpath(*names)
125
126 def __truediv__(self, child: StrPath) -> "Traversable":
127 """
128 Return Traversable child in self
129 """
130 return self.joinpath(child)
131
132 @abc.abstractmethod
133 def open(self, mode='r', *args, **kwargs):
134 """
135 mode may be 'r' or 'rb' to open as text or binary. Return a handle
136 suitable for reading (same as pathlib.Path.open).
137
138 When opening as text, accepts encoding parameters such as those
139 accepted by io.TextIOWrapper.
140 """
141
142 @property
143 @abc.abstractmethod
144 def name(self) -> str:
145 """
146 The base name of this object without any parent references.
147 """
148
149
150class TraversableResources(ResourceReader):
151 """
152 The required interface for providing traversable
153 resources.
154 """
155
156 @abc.abstractmethod
157 def files(self) -> "Traversable":
158 """Return a Traversable object for the loaded package."""
159
160 def open_resource(self, resource: StrPath) -> io.BufferedReader:
161 return self.files().joinpath(resource).open('rb')
162
163 def resource_path(self, resource: Any) -> NoReturn:
164 raise FileNotFoundError(resource)
165
166 def is_resource(self, path: StrPath) -> bool:
167 return self.files().joinpath(path).is_file()
168
169 def contents(self) -> Iterator[str]:
170 return (item.name for item in self.files().iterdir())