]> crepu.dev Git - config.git/blame - djavu-asus/elpy/rpc-venv/lib/python3.11/site-packages/pathspec/pathspec.py
ActualizaciĆ³n de Readme
[config.git] / djavu-asus / elpy / rpc-venv / lib / python3.11 / site-packages / pathspec / pathspec.py
CommitLineData
53e6db90
DC
1"""
2This module provides an object oriented interface for pattern matching of files.
3"""
4
5from collections.abc import (
6 Collection as CollectionType)
7from itertools import (
8 zip_longest)
9from typing import (
10 AnyStr,
11 Callable,
12 Collection,
13 Iterable,
14 Iterator,
15 Optional,
16 Type,
17 TypeVar,
18 Union)
19
20from . import util
21from .pattern import (
22 Pattern)
23from .util import (
24 StrPath,
25 TreeEntry,
26 _filter_patterns,
27 _is_iterable,
28 match_file,
29 normalize_file)
30
31Self = TypeVar("Self", bound="PathSpec")
32"""
33:class:`PathSpec` self type hint to support Python v<3.11 using PEP 673
34recommendation.
35"""
36
37
38class PathSpec(object):
39 """
40 The :class:`PathSpec` class is a wrapper around a list of compiled
41 :class:`.Pattern` instances.
42 """
43
44 def __init__(self, patterns: Iterable[Pattern]) -> None:
45 """
46 Initializes the :class:`PathSpec` instance.
47
48 *patterns* (:class:`~collections.abc.Collection` or :class:`~collections.abc.Iterable`)
49 yields each compiled pattern (:class:`.Pattern`).
50 """
51
52 self.patterns = patterns if isinstance(patterns, CollectionType) else list(patterns)
53 """
54 *patterns* (:class:`~collections.abc.Collection` of :class:`.Pattern`)
55 contains the compiled patterns.
56 """
57
58 def __eq__(self, other: object) -> bool:
59 """
60 Tests the equality of this path-spec with *other* (:class:`PathSpec`)
61 by comparing their :attr:`~PathSpec.patterns` attributes.
62 """
63 if isinstance(other, PathSpec):
64 paired_patterns = zip_longest(self.patterns, other.patterns)
65 return all(a == b for a, b in paired_patterns)
66 else:
67 return NotImplemented
68
69 def __len__(self) -> int:
70 """
71 Returns the number of compiled patterns this path-spec contains
72 (:class:`int`).
73 """
74 return len(self.patterns)
75
76 def __add__(self: Self, other: "PathSpec") -> Self:
77 """
78 Combines the :attr:`Pathspec.patterns` patterns from two
79 :class:`PathSpec` instances.
80 """
81 if isinstance(other, PathSpec):
82 return self.__class__(self.patterns + other.patterns)
83 else:
84 return NotImplemented
85
86 def __iadd__(self: Self, other: "PathSpec") -> Self:
87 """
88 Adds the :attr:`Pathspec.patterns` patterns from one :class:`PathSpec`
89 instance to this instance.
90 """
91 if isinstance(other, PathSpec):
92 self.patterns += other.patterns
93 return self
94 else:
95 return NotImplemented
96
97 @classmethod
98 def from_lines(
99 cls: Type[Self],
100 pattern_factory: Union[str, Callable[[AnyStr], Pattern]],
101 lines: Iterable[AnyStr],
102 ) -> Self:
103 """
104 Compiles the pattern lines.
105
106 *pattern_factory* can be either the name of a registered pattern factory
107 (:class:`str`), or a :class:`~collections.abc.Callable` used to compile
108 patterns. It must accept an uncompiled pattern (:class:`str`) and return the
109 compiled pattern (:class:`.Pattern`).
110
111 *lines* (:class:`~collections.abc.Iterable`) yields each uncompiled pattern
112 (:class:`str`). This simply has to yield each line so that it can be a
113 :class:`io.TextIOBase` (e.g., from :func:`open` or :class:`io.StringIO`) or
114 the result from :meth:`str.splitlines`.
115
116 Returns the :class:`PathSpec` instance.
117 """
118 if isinstance(pattern_factory, str):
119 pattern_factory = util.lookup_pattern(pattern_factory)
120
121 if not callable(pattern_factory):
122 raise TypeError(f"pattern_factory:{pattern_factory!r} is not callable.")
123
124 if not _is_iterable(lines):
125 raise TypeError(f"lines:{lines!r} is not an iterable.")
126
127 patterns = [pattern_factory(line) for line in lines if line]
128 return cls(patterns)
129
130 def match_entries(
131 self,
132 entries: Iterable[TreeEntry],
133 separators: Optional[Collection[str]] = None,
134 *,
135 negate: Optional[bool] = None,
136 ) -> Iterator[TreeEntry]:
137 """
138 Matches the entries to this path-spec.
139
140 *entries* (:class:`~collections.abc.Iterable` of :class:`~util.TreeEntry`)
141 contains the entries to be matched against :attr:`self.patterns <PathSpec.patterns>`.
142
143 *separators* (:class:`~collections.abc.Collection` of :class:`str`; or
144 :data:`None`) optionally contains the path separators to normalize. See
145 :func:`~pathspec.util.normalize_file` for more information.
146
147 *negate* (:class:`bool` or :data:`None`) is whether to negate the match
148 results of the patterns. If :data:`True`, a pattern matching a file will
149 exclude the file rather than include it. Default is :data:`None` for
150 :data:`False`.
151
152 Returns the matched entries (:class:`~collections.abc.Iterator` of
153 :class:`~util.TreeEntry`).
154 """
155 if not _is_iterable(entries):
156 raise TypeError(f"entries:{entries!r} is not an iterable.")
157
158 use_patterns = _filter_patterns(self.patterns)
159 for entry in entries:
160 norm_file = normalize_file(entry.path, separators)
161 is_match = self._match_file(use_patterns, norm_file)
162
163 if negate:
164 is_match = not is_match
165
166 if is_match:
167 yield entry
168
169 # Match files using the `match_file()` utility function. Subclasses may
170 # override this method as an instance method. It does not have to be a static
171 # method.
172 _match_file = staticmethod(match_file)
173
174 def match_file(
175 self,
176 file: StrPath,
177 separators: Optional[Collection[str]] = None,
178 ) -> bool:
179 """
180 Matches the file to this path-spec.
181
182 *file* (:class:`str` or :class:`os.PathLike[str]`) is the file path to be
183 matched against :attr:`self.patterns <PathSpec.patterns>`.
184
185 *separators* (:class:`~collections.abc.Collection` of :class:`str`)
186 optionally contains the path separators to normalize. See
187 :func:`~pathspec.util.normalize_file` for more information.
188
189 Returns :data:`True` if *file* matched; otherwise, :data:`False`.
190 """
191 norm_file = util.normalize_file(file, separators=separators)
192 return self._match_file(self.patterns, norm_file)
193
194 def match_files(
195 self,
196 files: Iterable[StrPath],
197 separators: Optional[Collection[str]] = None,
198 *,
199 negate: Optional[bool] = None,
200 ) -> Iterator[StrPath]:
201 """
202 Matches the files to this path-spec.
203
204 *files* (:class:`~collections.abc.Iterable` of :class:`str` or
205 :class:`os.PathLike[str]`) contains the file paths to be matched against
206 :attr:`self.patterns <PathSpec.patterns>`.
207
208 *separators* (:class:`~collections.abc.Collection` of :class:`str`; or
209 :data:`None`) optionally contains the path separators to normalize. See
210 :func:`~pathspec.util.normalize_file` for more information.
211
212 *negate* (:class:`bool` or :data:`None`) is whether to negate the match
213 results of the patterns. If :data:`True`, a pattern matching a file will
214 exclude the file rather than include it. Default is :data:`None` for
215 :data:`False`.
216
217 Returns the matched files (:class:`~collections.abc.Iterator` of
218 :class:`str` or :class:`os.PathLike[str]`).
219 """
220 if not _is_iterable(files):
221 raise TypeError(f"files:{files!r} is not an iterable.")
222
223 use_patterns = _filter_patterns(self.patterns)
224 for orig_file in files:
225 norm_file = normalize_file(orig_file, separators)
226 is_match = self._match_file(use_patterns, norm_file)
227
228 if negate:
229 is_match = not is_match
230
231 if is_match:
232 yield orig_file
233
234 def match_tree_entries(
235 self,
236 root: StrPath,
237 on_error: Optional[Callable] = None,
238 follow_links: Optional[bool] = None,
239 *,
240 negate: Optional[bool] = None,
241 ) -> Iterator[TreeEntry]:
242 """
243 Walks the specified root path for all files and matches them to this
244 path-spec.
245
246 *root* (:class:`str` or :class:`os.PathLike[str]`) is the root directory to
247 search.
248
249 *on_error* (:class:`~collections.abc.Callable` or :data:`None`) optionally
250 is the error handler for file-system exceptions. See
251 :func:`~pathspec.util.iter_tree_entries` for more information.
252
253 *follow_links* (:class:`bool` or :data:`None`) optionally is whether to walk
254 symbolic links that resolve to directories. See
255 :func:`~pathspec.util.iter_tree_files` for more information.
256
257 *negate* (:class:`bool` or :data:`None`) is whether to negate the match
258 results of the patterns. If :data:`True`, a pattern matching a file will
259 exclude the file rather than include it. Default is :data:`None` for
260 :data:`False`.
261
262 Returns the matched files (:class:`~collections.abc.Iterator` of
263 :class:`.TreeEntry`).
264 """
265 entries = util.iter_tree_entries(root, on_error=on_error, follow_links=follow_links)
266 yield from self.match_entries(entries, negate=negate)
267
268 def match_tree_files(
269 self,
270 root: StrPath,
271 on_error: Optional[Callable] = None,
272 follow_links: Optional[bool] = None,
273 *,
274 negate: Optional[bool] = None,
275 ) -> Iterator[str]:
276 """
277 Walks the specified root path for all files and matches them to this
278 path-spec.
279
280 *root* (:class:`str` or :class:`os.PathLike[str]`) is the root directory to
281 search for files.
282
283 *on_error* (:class:`~collections.abc.Callable` or :data:`None`) optionally
284 is the error handler for file-system exceptions. See
285 :func:`~pathspec.util.iter_tree_files` for more information.
286
287 *follow_links* (:class:`bool` or :data:`None`) optionally is whether to walk
288 symbolic links that resolve to directories. See
289 :func:`~pathspec.util.iter_tree_files` for more information.
290
291 *negate* (:class:`bool` or :data:`None`) is whether to negate the match
292 results of the patterns. If :data:`True`, a pattern matching a file will
293 exclude the file rather than include it. Default is :data:`None` for
294 :data:`False`.
295
296 Returns the matched files (:class:`~collections.abc.Iterable` of
297 :class:`str`).
298 """
299 files = util.iter_tree_files(root, on_error=on_error, follow_links=follow_links)
300 yield from self.match_files(files, negate=negate)
301
302 # Alias `match_tree_files()` as `match_tree()` for backward compatibility
303 # before v0.3.2.
304 match_tree = match_tree_files