src/black/files.py
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- | import io
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- | import os
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- | import sys
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- | from functools import lru_cache
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- | from pathlib import Path
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- | from typing import (
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- | TYPE_CHECKING,
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- | Any,
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- | Dict,
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- | Iterable,
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- | Iterator,
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- | List,
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- | Optional,
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- | Pattern,
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- | Sequence,
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- | Tuple,
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- | Union,
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- | )
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- |
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- | from mypy_extensions import mypyc_attr
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- | from packaging.specifiers import InvalidSpecifier, Specifier, SpecifierSet
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- | from packaging.version import InvalidVersion, Version
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- | from pathspec import PathSpec
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- | from pathspec.patterns.gitwildmatch import GitWildMatchPatternError
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- |
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- | if sys.version_info >= (3, 11):
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- | try:
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- | import tomllib
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- | except ImportError:
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- | # Help users on older alphas
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- | if not TYPE_CHECKING:
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- | import tomli as tomllib
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- | else:
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- | import tomli as tomllib
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- |
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- | from black.handle_ipynb_magics import jupyter_dependencies_are_installed
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- | from black.mode import TargetVersion
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- | from black.output import err
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- | from black.report import Report
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- |
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- | if TYPE_CHECKING:
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- | import colorama # noqa: F401
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- |
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- |
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- | @lru_cache
0045 0019 0024 0002 0009 0010 0002 -- 13 005 011 007 013 016 020 0080.00 0236.36 0002.95 | def find_project_root(
0045 0019 0024 0002 0009 0010 0002 -- 13 005 011 007 013 016 020 0080.00 0236.36 0002.95 | srcs: Sequence[str], stdin_filename: Optional[str] = None
0045 0019 0024 0002 0009 0010 0002 -- 13 005 011 007 013 016 020 0080.00 0236.36 0002.95 | ) -> Tuple[Path, str]:
0045 0019 0024 0002 0009 0010 0002 -- 13 005 011 007 013 016 020 0080.00 0236.36 0002.95 | """Return a directory containing .git, .hg, or pyproject.toml.
0045 0019 0024 0002 0009 0010 0002 -- 13 005 011 007 013 016 020 0080.00 0236.36 0002.95 |
0045 0019 0024 0002 0009 0010 0002 -- 13 005 011 007 013 016 020 0080.00 0236.36 0002.95 | That directory will be a common parent of all files and directories
0045 0019 0024 0002 0009 0010 0002 -- 13 005 011 007 013 016 020 0080.00 0236.36 0002.95 | passed in `srcs`.
0045 0019 0024 0002 0009 0010 0002 -- 13 005 011 007 013 016 020 0080.00 0236.36 0002.95 |
0045 0019 0024 0002 0009 0010 0002 -- 13 005 011 007 013 016 020 0080.00 0236.36 0002.95 | If no directory in the tree contains a marker that would specify it's the
0045 0019 0024 0002 0009 0010 0002 -- 13 005 011 007 013 016 020 0080.00 0236.36 0002.95 | project root, the root of the file system is returned.
0045 0019 0024 0002 0009 0010 0002 -- 13 005 011 007 013 016 020 0080.00 0236.36 0002.95 |
0045 0019 0024 0002 0009 0010 0002 -- 13 005 011 007 013 016 020 0080.00 0236.36 0002.95 | Returns a two-tuple with the first element as the project root path and
0045 0019 0024 0002 0009 0010 0002 -- 13 005 011 007 013 016 020 0080.00 0236.36 0002.95 | the second element as a string describing the method by which the
0045 0019 0024 0002 0009 0010 0002 -- 13 005 011 007 013 016 020 0080.00 0236.36 0002.95 | project root was discovered.
0045 0019 0024 0002 0009 0010 0002 -- 13 005 011 007 013 016 020 0080.00 0236.36 0002.95 | """
0045 0019 0024 0002 0009 0010 0002 -- 13 005 011 007 013 016 020 0080.00 0236.36 0002.95 | if stdin_filename is not None:
0045 0019 0024 0002 0009 0010 0002 -- 13 005 011 007 013 016 020 0080.00 0236.36 0002.95 | srcs = tuple(stdin_filename if s == "-" else s for s in srcs)
0045 0019 0024 0002 0009 0010 0002 -- 13 005 011 007 013 016 020 0080.00 0236.36 0002.95 | if not srcs:
0045 0019 0024 0002 0009 0010 0002 -- 13 005 011 007 013 016 020 0080.00 0236.36 0002.95 | srcs = [str(Path.cwd().resolve())]
0045 0019 0024 0002 0009 0010 0002 -- 13 005 011 007 013 016 020 0080.00 0236.36 0002.95 |
0045 0019 0024 0002 0009 0010 0002 -- 13 005 011 007 013 016 020 0080.00 0236.36 0002.95 | path_srcs = [Path(Path.cwd(), src).resolve() for src in srcs]
0045 0019 0024 0002 0009 0010 0002 -- 13 005 011 007 013 016 020 0080.00 0236.36 0002.95 |
0045 0019 0024 0002 0009 0010 0002 -- 13 005 011 007 013 016 020 0080.00 0236.36 0002.95 | # A list of lists of parents for each 'src'. 'src' is included as a
0045 0019 0024 0002 0009 0010 0002 -- 13 005 011 007 013 016 020 0080.00 0236.36 0002.95 | # "parent" of itself if it is a directory
0045 0019 0024 0002 0009 0010 0002 -- 13 005 011 007 013 016 020 0080.00 0236.36 0002.95 | src_parents = [
0045 0019 0024 0002 0009 0010 0002 -- 13 005 011 007 013 016 020 0080.00 0236.36 0002.95 | list(path.parents) + ([path] if path.is_dir() else []) for path in path_srcs
0045 0019 0024 0002 0009 0010 0002 -- 13 005 011 007 013 016 020 0080.00 0236.36 0002.95 | ]
0045 0019 0024 0002 0009 0010 0002 -- 13 005 011 007 013 016 020 0080.00 0236.36 0002.95 |
0045 0019 0024 0002 0009 0010 0002 -- 13 005 011 007 013 016 020 0080.00 0236.36 0002.95 | common_base = max(
0045 0019 0024 0002 0009 0010 0002 -- 13 005 011 007 013 016 020 0080.00 0236.36 0002.95 | set.intersection(*(set(parents) for parents in src_parents)),
0045 0019 0024 0002 0009 0010 0002 -- 13 005 011 007 013 016 020 0080.00 0236.36 0002.95 | key=lambda path: path.parts,
0045 0019 0024 0002 0009 0010 0002 -- 13 005 011 007 013 016 020 0080.00 0236.36 0002.95 | )
0045 0019 0024 0002 0009 0010 0002 -- 13 005 011 007 013 016 020 0080.00 0236.36 0002.95 |
0045 0019 0024 0002 0009 0010 0002 -- 13 005 011 007 013 016 020 0080.00 0236.36 0002.95 | for directory in (common_base, *common_base.parents):
0045 0019 0024 0002 0009 0010 0002 -- 13 005 011 007 013 016 020 0080.00 0236.36 0002.95 | if (directory / ".git").exists():
0045 0019 0024 0002 0009 0010 0002 -- 13 005 011 007 013 016 020 0080.00 0236.36 0002.95 | return directory, ".git directory"
0045 0019 0024 0002 0009 0010 0002 -- 13 005 011 007 013 016 020 0080.00 0236.36 0002.95 |
0045 0019 0024 0002 0009 0010 0002 -- 13 005 011 007 013 016 020 0080.00 0236.36 0002.95 | if (directory / ".hg").is_dir():
0045 0019 0024 0002 0009 0010 0002 -- 13 005 011 007 013 016 020 0080.00 0236.36 0002.95 | return directory, ".hg directory"
0045 0019 0024 0002 0009 0010 0002 -- 13 005 011 007 013 016 020 0080.00 0236.36 0002.95 |
0045 0019 0024 0002 0009 0010 0002 -- 13 005 011 007 013 016 020 0080.00 0236.36 0002.95 | if (directory / "pyproject.toml").is_file():
0045 0019 0024 0002 0009 0010 0002 -- 13 005 011 007 013 016 020 0080.00 0236.36 0002.95 | return directory, "pyproject.toml"
0045 0019 0024 0002 0009 0010 0002 -- 13 005 011 007 013 016 020 0080.00 0236.36 0002.95 |
0045 0019 0024 0002 0009 0010 0002 -- 13 005 011 007 013 016 020 0080.00 0236.36 0002.95 | return directory, "file system root"
0045 0019 0024 0002 0009 0010 0002 -- -- --- --- --- --- --- --- ------- ------- ------- |
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- |
0020 0012 0017 0001 0000 0001 0002 -- 04 001 002 001 002 003 003 0004.75 0002.38 0000.50 | def find_pyproject_toml(
0020 0012 0017 0001 0000 0001 0002 -- 04 001 002 001 002 003 003 0004.75 0002.38 0000.50 | path_search_start: Tuple[str, ...], stdin_filename: Optional[str] = None
0020 0012 0017 0001 0000 0001 0002 -- 04 001 002 001 002 003 003 0004.75 0002.38 0000.50 | ) -> Optional[str]:
0020 0012 0017 0001 0000 0001 0002 -- 04 001 002 001 002 003 003 0004.75 0002.38 0000.50 | """Find the absolute filepath to a pyproject.toml if it exists"""
0020 0012 0017 0001 0000 0001 0002 -- 04 001 002 001 002 003 003 0004.75 0002.38 0000.50 | path_project_root, _ = find_project_root(path_search_start, stdin_filename)
0020 0012 0017 0001 0000 0001 0002 -- 04 001 002 001 002 003 003 0004.75 0002.38 0000.50 | path_pyproject_toml = path_project_root / "pyproject.toml"
0020 0012 0017 0001 0000 0001 0002 -- 04 001 002 001 002 003 003 0004.75 0002.38 0000.50 | if path_pyproject_toml.is_file():
0020 0012 0017 0001 0000 0001 0002 -- 04 001 002 001 002 003 003 0004.75 0002.38 0000.50 | return str(path_pyproject_toml)
0020 0012 0017 0001 0000 0001 0002 -- 04 001 002 001 002 003 003 0004.75 0002.38 0000.50 |
0020 0012 0017 0001 0000 0001 0002 -- 04 001 002 001 002 003 003 0004.75 0002.38 0000.50 | try:
0020 0012 0017 0001 0000 0001 0002 -- 04 001 002 001 002 003 003 0004.75 0002.38 0000.50 | path_user_pyproject_toml = find_user_pyproject_toml()
0020 0012 0017 0001 0000 0001 0002 -- 04 001 002 001 002 003 003 0004.75 0002.38 0000.50 | return (
0020 0012 0017 0001 0000 0001 0002 -- 04 001 002 001 002 003 003 0004.75 0002.38 0000.50 | str(path_user_pyproject_toml)
0020 0012 0017 0001 0000 0001 0002 -- 04 001 002 001 002 003 003 0004.75 0002.38 0000.50 | if path_user_pyproject_toml.is_file()
0020 0012 0017 0001 0000 0001 0002 -- 04 001 002 001 002 003 003 0004.75 0002.38 0000.50 | else None
0020 0012 0017 0001 0000 0001 0002 -- 04 001 002 001 002 003 003 0004.75 0002.38 0000.50 | )
0020 0012 0017 0001 0000 0001 0002 -- 04 001 002 001 002 003 003 0004.75 0002.38 0000.50 | except (PermissionError, RuntimeError) as e:
0020 0012 0017 0001 0000 0001 0002 -- 04 001 002 001 002 003 003 0004.75 0002.38 0000.50 | # We do not have access to the user-level config directory, so ignore it.
0020 0012 0017 0001 0000 0001 0002 -- 04 001 002 001 002 003 003 0004.75 0002.38 0000.50 | err(f"Ignoring user configuration directory due to {e!r}")
0020 0012 0017 0001 0000 0001 0002 -- 04 001 002 001 002 003 003 0004.75 0002.38 0000.50 | return None
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- |
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- |
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- | @mypyc_attr(patchable=True)
0017 0014 0011 0000 0003 0003 0000 -- 05 002 004 002 004 006 006 0015.51 0015.51 0001.00 | def parse_pyproject_toml(path_config: str) -> Dict[str, Any]:
0017 0014 0011 0000 0003 0003 0000 -- 05 002 004 002 004 006 006 0015.51 0015.51 0001.00 | """Parse a pyproject toml file, pulling out relevant parts for Black.
0017 0014 0011 0000 0003 0003 0000 -- 05 002 004 002 004 006 006 0015.51 0015.51 0001.00 |
0017 0014 0011 0000 0003 0003 0000 -- 05 002 004 002 004 006 006 0015.51 0015.51 0001.00 | If parsing fails, will raise a tomllib.TOMLDecodeError.
0017 0014 0011 0000 0003 0003 0000 -- 05 002 004 002 004 006 006 0015.51 0015.51 0001.00 | """
0017 0014 0011 0000 0003 0003 0000 -- 05 002 004 002 004 006 006 0015.51 0015.51 0001.00 | with open(path_config, "rb") as f:
0017 0014 0011 0000 0003 0003 0000 -- 05 002 004 002 004 006 006 0015.51 0015.51 0001.00 | pyproject_toml = tomllib.load(f)
0017 0014 0011 0000 0003 0003 0000 -- 05 002 004 002 004 006 006 0015.51 0015.51 0001.00 | config: Dict[str, Any] = pyproject_toml.get("tool", {}).get("black", {})
0017 0014 0011 0000 0003 0003 0000 -- 05 002 004 002 004 006 006 0015.51 0015.51 0001.00 | config = {k.replace("--", "").replace("-", "_"): v for k, v in config.items()}
0017 0014 0011 0000 0003 0003 0000 -- 05 002 004 002 004 006 006 0015.51 0015.51 0001.00 |
0017 0014 0011 0000 0003 0003 0000 -- 05 002 004 002 004 006 006 0015.51 0015.51 0001.00 | if "target_version" not in config:
0017 0014 0011 0000 0003 0003 0000 -- 05 002 004 002 004 006 006 0015.51 0015.51 0001.00 | inferred_target_version = infer_target_version(pyproject_toml)
0017 0014 0011 0000 0003 0003 0000 -- 05 002 004 002 004 006 006 0015.51 0015.51 0001.00 | if inferred_target_version is not None:
0017 0014 0011 0000 0003 0003 0000 -- 05 002 004 002 004 006 006 0015.51 0015.51 0001.00 | config["target_version"] = [v.name.lower() for v in inferred_target_version]
0017 0014 0011 0000 0003 0003 0000 -- 05 002 004 002 004 006 006 0015.51 0015.51 0001.00 |
0017 0014 0011 0000 0003 0003 0000 -- 05 002 004 002 004 006 006 0015.51 0015.51 0001.00 | return config
0017 0014 0011 0000 0003 0003 0000 -- -- --- --- --- --- --- --- ------- ------- ------- |
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- |
0023 0014 0015 0000 0005 0003 0000 -- 04 001 002 001 002 003 003 0004.75 0002.38 0000.50 | def infer_target_version(
0023 0014 0015 0000 0005 0003 0000 -- 04 001 002 001 002 003 003 0004.75 0002.38 0000.50 | pyproject_toml: Dict[str, Any]
0023 0014 0015 0000 0005 0003 0000 -- 04 001 002 001 002 003 003 0004.75 0002.38 0000.50 | ) -> Optional[List[TargetVersion]]:
0023 0014 0015 0000 0005 0003 0000 -- 04 001 002 001 002 003 003 0004.75 0002.38 0000.50 | """Infer Black's target version from the project metadata in pyproject.toml.
0023 0014 0015 0000 0005 0003 0000 -- 04 001 002 001 002 003 003 0004.75 0002.38 0000.50 |
0023 0014 0015 0000 0005 0003 0000 -- 04 001 002 001 002 003 003 0004.75 0002.38 0000.50 | Supports the PyPA standard format (PEP 621):
0023 0014 0015 0000 0005 0003 0000 -- 04 001 002 001 002 003 003 0004.75 0002.38 0000.50 | https://packaging.python.org/en/latest/specifications/declaring-project-metadata/#requires-python
0023 0014 0015 0000 0005 0003 0000 -- 04 001 002 001 002 003 003 0004.75 0002.38 0000.50 |
0023 0014 0015 0000 0005 0003 0000 -- 04 001 002 001 002 003 003 0004.75 0002.38 0000.50 | If the target version cannot be inferred, returns None.
0023 0014 0015 0000 0005 0003 0000 -- 04 001 002 001 002 003 003 0004.75 0002.38 0000.50 | """
0023 0014 0015 0000 0005 0003 0000 -- 04 001 002 001 002 003 003 0004.75 0002.38 0000.50 | project_metadata = pyproject_toml.get("project", {})
0023 0014 0015 0000 0005 0003 0000 -- 04 001 002 001 002 003 003 0004.75 0002.38 0000.50 | requires_python = project_metadata.get("requires-python", None)
0023 0014 0015 0000 0005 0003 0000 -- 04 001 002 001 002 003 003 0004.75 0002.38 0000.50 | if requires_python is not None:
0023 0014 0015 0000 0005 0003 0000 -- 04 001 002 001 002 003 003 0004.75 0002.38 0000.50 | try:
0023 0014 0015 0000 0005 0003 0000 -- 04 001 002 001 002 003 003 0004.75 0002.38 0000.50 | return parse_req_python_version(requires_python)
0023 0014 0015 0000 0005 0003 0000 -- 04 001 002 001 002 003 003 0004.75 0002.38 0000.50 | except InvalidVersion:
0023 0014 0015 0000 0005 0003 0000 -- 04 001 002 001 002 003 003 0004.75 0002.38 0000.50 | pass
0023 0014 0015 0000 0005 0003 0000 -- 04 001 002 001 002 003 003 0004.75 0002.38 0000.50 | try:
0023 0014 0015 0000 0005 0003 0000 -- 04 001 002 001 002 003 003 0004.75 0002.38 0000.50 | return parse_req_python_specifier(requires_python)
0023 0014 0015 0000 0005 0003 0000 -- 04 001 002 001 002 003 003 0004.75 0002.38 0000.50 | except (InvalidSpecifier, InvalidVersion):
0023 0014 0015 0000 0005 0003 0000 -- 04 001 002 001 002 003 003 0004.75 0002.38 0000.50 | pass
0023 0014 0015 0000 0005 0003 0000 -- 04 001 002 001 002 003 003 0004.75 0002.38 0000.50 |
0023 0014 0015 0000 0005 0003 0000 -- 04 001 002 001 002 003 003 0004.75 0002.38 0000.50 | return None
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- |
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- |
0013 0009 0008 0000 0004 0001 0000 -- 03 001 002 001 002 003 003 0004.75 0002.38 0000.50 | def parse_req_python_version(requires_python: str) -> Optional[List[TargetVersion]]:
0013 0009 0008 0000 0004 0001 0000 -- 03 001 002 001 002 003 003 0004.75 0002.38 0000.50 | """Parse a version string (i.e. ``"3.7"``) to a list of TargetVersion.
0013 0009 0008 0000 0004 0001 0000 -- 03 001 002 001 002 003 003 0004.75 0002.38 0000.50 |
0013 0009 0008 0000 0004 0001 0000 -- 03 001 002 001 002 003 003 0004.75 0002.38 0000.50 | If parsing fails, will raise a packaging.version.InvalidVersion error.
0013 0009 0008 0000 0004 0001 0000 -- 03 001 002 001 002 003 003 0004.75 0002.38 0000.50 | If the parsed version cannot be mapped to a valid TargetVersion, returns None.
0013 0009 0008 0000 0004 0001 0000 -- 03 001 002 001 002 003 003 0004.75 0002.38 0000.50 | """
0013 0009 0008 0000 0004 0001 0000 -- 03 001 002 001 002 003 003 0004.75 0002.38 0000.50 | version = Version(requires_python)
0013 0009 0008 0000 0004 0001 0000 -- 03 001 002 001 002 003 003 0004.75 0002.38 0000.50 | if version.release[0] != 3:
0013 0009 0008 0000 0004 0001 0000 -- 03 001 002 001 002 003 003 0004.75 0002.38 0000.50 | return None
0013 0009 0008 0000 0004 0001 0000 -- 03 001 002 001 002 003 003 0004.75 0002.38 0000.50 | try:
0013 0009 0008 0000 0004 0001 0000 -- 03 001 002 001 002 003 003 0004.75 0002.38 0000.50 | return [TargetVersion(version.release[1])]
0013 0009 0008 0000 0004 0001 0000 -- 03 001 002 001 002 003 003 0004.75 0002.38 0000.50 | except (IndexError, ValueError):
0013 0009 0008 0000 0004 0001 0000 -- 03 001 002 001 002 003 003 0004.75 0002.38 0000.50 | return None
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- |
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- |
0015 0012 0009 0000 0004 0002 0000 -- 05 001 001 001 001 002 002 0002.00 0001.00 0000.50 | def parse_req_python_specifier(requires_python: str) -> Optional[List[TargetVersion]]:
0015 0012 0009 0000 0004 0002 0000 -- 05 001 001 001 001 002 002 0002.00 0001.00 0000.50 | """Parse a specifier string (i.e. ``">=3.7,<3.10"``) to a list of TargetVersion.
0015 0012 0009 0000 0004 0002 0000 -- 05 001 001 001 001 002 002 0002.00 0001.00 0000.50 |
0015 0012 0009 0000 0004 0002 0000 -- 05 001 001 001 001 002 002 0002.00 0001.00 0000.50 | If parsing fails, will raise a packaging.specifiers.InvalidSpecifier error.
0015 0012 0009 0000 0004 0002 0000 -- 05 001 001 001 001 002 002 0002.00 0001.00 0000.50 | If the parsed specifier cannot be mapped to a valid TargetVersion, returns None.
0015 0012 0009 0000 0004 0002 0000 -- 05 001 001 001 001 002 002 0002.00 0001.00 0000.50 | """
0015 0012 0009 0000 0004 0002 0000 -- 05 001 001 001 001 002 002 0002.00 0001.00 0000.50 | specifier_set = strip_specifier_set(SpecifierSet(requires_python))
0015 0012 0009 0000 0004 0002 0000 -- 05 001 001 001 001 002 002 0002.00 0001.00 0000.50 | if not specifier_set:
0015 0012 0009 0000 0004 0002 0000 -- 05 001 001 001 001 002 002 0002.00 0001.00 0000.50 | return None
0015 0012 0009 0000 0004 0002 0000 -- 05 001 001 001 001 002 002 0002.00 0001.00 0000.50 |
0015 0012 0009 0000 0004 0002 0000 -- 05 001 001 001 001 002 002 0002.00 0001.00 0000.50 | target_version_map = {f"3.{v.value}": v for v in TargetVersion}
0015 0012 0009 0000 0004 0002 0000 -- 05 001 001 001 001 002 002 0002.00 0001.00 0000.50 | compatible_versions: List[str] = list(specifier_set.filter(target_version_map))
0015 0012 0009 0000 0004 0002 0000 -- 05 001 001 001 001 002 002 0002.00 0001.00 0000.50 | if compatible_versions:
0015 0012 0009 0000 0004 0002 0000 -- 05 001 001 001 001 002 002 0002.00 0001.00 0000.50 | return [target_version_map[v] for v in compatible_versions]
0015 0012 0009 0000 0004 0002 0000 -- 05 001 001 001 001 002 002 0002.00 0001.00 0000.50 | return None
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- |
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- |
0023 0018 0017 0000 0004 0002 0000 -- 07 003 007 004 008 010 012 0039.86 0068.34 0001.71 | def strip_specifier_set(specifier_set: SpecifierSet) -> SpecifierSet:
0023 0018 0017 0000 0004 0002 0000 -- 07 003 007 004 008 010 012 0039.86 0068.34 0001.71 | """Strip minor versions for some specifiers in the specifier set.
0023 0018 0017 0000 0004 0002 0000 -- 07 003 007 004 008 010 012 0039.86 0068.34 0001.71 |
0023 0018 0017 0000 0004 0002 0000 -- 07 003 007 004 008 010 012 0039.86 0068.34 0001.71 | For background on version specifiers, see PEP 440:
0023 0018 0017 0000 0004 0002 0000 -- 07 003 007 004 008 010 012 0039.86 0068.34 0001.71 | https://peps.python.org/pep-0440/#version-specifiers
0023 0018 0017 0000 0004 0002 0000 -- 07 003 007 004 008 010 012 0039.86 0068.34 0001.71 | """
0023 0018 0017 0000 0004 0002 0000 -- 07 003 007 004 008 010 012 0039.86 0068.34 0001.71 | specifiers = []
0023 0018 0017 0000 0004 0002 0000 -- 07 003 007 004 008 010 012 0039.86 0068.34 0001.71 | for s in specifier_set:
0023 0018 0017 0000 0004 0002 0000 -- 07 003 007 004 008 010 012 0039.86 0068.34 0001.71 | if "*" in str(s):
0023 0018 0017 0000 0004 0002 0000 -- 07 003 007 004 008 010 012 0039.86 0068.34 0001.71 | specifiers.append(s)
0023 0018 0017 0000 0004 0002 0000 -- 07 003 007 004 008 010 012 0039.86 0068.34 0001.71 | elif s.operator in ["~=", "==", ">=", "==="]:
0023 0018 0017 0000 0004 0002 0000 -- 07 003 007 004 008 010 012 0039.86 0068.34 0001.71 | version = Version(s.version)
0023 0018 0017 0000 0004 0002 0000 -- 07 003 007 004 008 010 012 0039.86 0068.34 0001.71 | stripped = Specifier(f"{s.operator}{version.major}.{version.minor}")
0023 0018 0017 0000 0004 0002 0000 -- 07 003 007 004 008 010 012 0039.86 0068.34 0001.71 | specifiers.append(stripped)
0023 0018 0017 0000 0004 0002 0000 -- 07 003 007 004 008 010 012 0039.86 0068.34 0001.71 | elif s.operator == ">":
0023 0018 0017 0000 0004 0002 0000 -- 07 003 007 004 008 010 012 0039.86 0068.34 0001.71 | version = Version(s.version)
0023 0018 0017 0000 0004 0002 0000 -- 07 003 007 004 008 010 012 0039.86 0068.34 0001.71 | if len(version.release) > 2:
0023 0018 0017 0000 0004 0002 0000 -- 07 003 007 004 008 010 012 0039.86 0068.34 0001.71 | s = Specifier(f">={version.major}.{version.minor}")
0023 0018 0017 0000 0004 0002 0000 -- 07 003 007 004 008 010 012 0039.86 0068.34 0001.71 | specifiers.append(s)
0023 0018 0017 0000 0004 0002 0000 -- 07 003 007 004 008 010 012 0039.86 0068.34 0001.71 | else:
0023 0018 0017 0000 0004 0002 0000 -- 07 003 007 004 008 010 012 0039.86 0068.34 0001.71 | specifiers.append(s)
0023 0018 0017 0000 0004 0002 0000 -- 07 003 007 004 008 010 012 0039.86 0068.34 0001.71 |
0023 0018 0017 0000 0004 0002 0000 -- 07 003 007 004 008 010 012 0039.86 0068.34 0001.71 | return SpecifierSet(",".join(str(s) for s in specifiers))
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- |
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- |
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- | @lru_cache
0018 0009 0008 0001 0007 0002 0001 -- 02 002 006 003 006 008 009 0027.00 0027.00 0001.00 | def find_user_pyproject_toml() -> Path:
0018 0009 0008 0001 0007 0002 0001 -- 02 002 006 003 006 008 009 0027.00 0027.00 0001.00 | r"""Return the path to the top-level user configuration for black.
0018 0009 0008 0001 0007 0002 0001 -- 02 002 006 003 006 008 009 0027.00 0027.00 0001.00 |
0018 0009 0008 0001 0007 0002 0001 -- 02 002 006 003 006 008 009 0027.00 0027.00 0001.00 | This looks for ~\.black on Windows and ~/.config/black on Linux and other
0018 0009 0008 0001 0007 0002 0001 -- 02 002 006 003 006 008 009 0027.00 0027.00 0001.00 | Unix systems.
0018 0009 0008 0001 0007 0002 0001 -- 02 002 006 003 006 008 009 0027.00 0027.00 0001.00 |
0018 0009 0008 0001 0007 0002 0001 -- 02 002 006 003 006 008 009 0027.00 0027.00 0001.00 | May raise:
0018 0009 0008 0001 0007 0002 0001 -- 02 002 006 003 006 008 009 0027.00 0027.00 0001.00 | - RuntimeError: if the current user has no homedir
0018 0009 0008 0001 0007 0002 0001 -- 02 002 006 003 006 008 009 0027.00 0027.00 0001.00 | - PermissionError: if the current process cannot access the user's homedir
0018 0009 0008 0001 0007 0002 0001 -- 02 002 006 003 006 008 009 0027.00 0027.00 0001.00 | """
0018 0009 0008 0001 0007 0002 0001 -- 02 002 006 003 006 008 009 0027.00 0027.00 0001.00 | if sys.platform == "win32":
0018 0009 0008 0001 0007 0002 0001 -- 02 002 006 003 006 008 009 0027.00 0027.00 0001.00 | # Windows
0018 0009 0008 0001 0007 0002 0001 -- 02 002 006 003 006 008 009 0027.00 0027.00 0001.00 | user_config_path = Path.home() / ".black"
0018 0009 0008 0001 0007 0002 0001 -- 02 002 006 003 006 008 009 0027.00 0027.00 0001.00 | else:
0018 0009 0008 0001 0007 0002 0001 -- 02 002 006 003 006 008 009 0027.00 0027.00 0001.00 | config_root = os.environ.get("XDG_CONFIG_HOME", "~/.config")
0018 0009 0008 0001 0007 0002 0001 -- 02 002 006 003 006 008 009 0027.00 0027.00 0001.00 | user_config_path = Path(config_root).expanduser() / "black"
0018 0009 0008 0001 0007 0002 0001 -- 02 002 006 003 006 008 009 0027.00 0027.00 0001.00 | return user_config_path.resolve()
0018 0009 0008 0001 0007 0002 0001 -- -- --- --- --- --- --- --- ------- ------- ------- |
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- |
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- | @lru_cache
0013 0014 0012 0000 0000 0000 0001 -- 03 001 002 001 002 003 003 0004.75 0002.38 0000.50 | def get_gitignore(root: Path) -> PathSpec:
0013 0014 0012 0000 0000 0000 0001 -- 03 001 002 001 002 003 003 0004.75 0002.38 0000.50 | """Return a PathSpec matching gitignore content if present."""
0013 0014 0012 0000 0000 0000 0001 -- 03 001 002 001 002 003 003 0004.75 0002.38 0000.50 | gitignore = root / ".gitignore"
0013 0014 0012 0000 0000 0000 0001 -- 03 001 002 001 002 003 003 0004.75 0002.38 0000.50 | lines: List[str] = []
0013 0014 0012 0000 0000 0000 0001 -- 03 001 002 001 002 003 003 0004.75 0002.38 0000.50 | if gitignore.is_file():
0013 0014 0012 0000 0000 0000 0001 -- 03 001 002 001 002 003 003 0004.75 0002.38 0000.50 | with gitignore.open(encoding="utf-8") as gf:
0013 0014 0012 0000 0000 0000 0001 -- 03 001 002 001 002 003 003 0004.75 0002.38 0000.50 | lines = gf.readlines()
0013 0014 0012 0000 0000 0000 0001 -- 03 001 002 001 002 003 003 0004.75 0002.38 0000.50 | try:
0013 0014 0012 0000 0000 0000 0001 -- 03 001 002 001 002 003 003 0004.75 0002.38 0000.50 | return PathSpec.from_lines("gitwildmatch", lines)
0013 0014 0012 0000 0000 0000 0001 -- 03 001 002 001 002 003 003 0004.75 0002.38 0000.50 | except GitWildMatchPatternError as e:
0013 0014 0012 0000 0000 0000 0001 -- 03 001 002 001 002 003 003 0004.75 0002.38 0000.50 | err(f"Could not parse {gitignore}: {e}")
0013 0014 0012 0000 0000 0000 0001 -- 03 001 002 001 002 003 003 0004.75 0002.38 0000.50 | raise
0013 0014 0012 0000 0000 0000 0001 -- -- --- --- --- --- --- --- ------- ------- ------- |
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- |
0027 0016 0021 0000 0003 0003 0000 -- 06 001 002 001 002 003 003 0004.75 0002.38 0000.50 | def normalize_path_maybe_ignore(
0027 0016 0021 0000 0003 0003 0000 -- 06 001 002 001 002 003 003 0004.75 0002.38 0000.50 | path: Path,
0027 0016 0021 0000 0003 0003 0000 -- 06 001 002 001 002 003 003 0004.75 0002.38 0000.50 | root: Path,
0027 0016 0021 0000 0003 0003 0000 -- 06 001 002 001 002 003 003 0004.75 0002.38 0000.50 | report: Optional[Report] = None,
0027 0016 0021 0000 0003 0003 0000 -- 06 001 002 001 002 003 003 0004.75 0002.38 0000.50 | ) -> Optional[str]:
0027 0016 0021 0000 0003 0003 0000 -- 06 001 002 001 002 003 003 0004.75 0002.38 0000.50 | """Normalize `path`. May return `None` if `path` was ignored.
0027 0016 0021 0000 0003 0003 0000 -- 06 001 002 001 002 003 003 0004.75 0002.38 0000.50 |
0027 0016 0021 0000 0003 0003 0000 -- 06 001 002 001 002 003 003 0004.75 0002.38 0000.50 | `report` is where "path ignored" output goes.
0027 0016 0021 0000 0003 0003 0000 -- 06 001 002 001 002 003 003 0004.75 0002.38 0000.50 | """
0027 0016 0021 0000 0003 0003 0000 -- 06 001 002 001 002 003 003 0004.75 0002.38 0000.50 | try:
0027 0016 0021 0000 0003 0003 0000 -- 06 001 002 001 002 003 003 0004.75 0002.38 0000.50 | abspath = path if path.is_absolute() else Path.cwd() / path
0027 0016 0021 0000 0003 0003 0000 -- 06 001 002 001 002 003 003 0004.75 0002.38 0000.50 | normalized_path = abspath.resolve()
0027 0016 0021 0000 0003 0003 0000 -- 06 001 002 001 002 003 003 0004.75 0002.38 0000.50 | try:
0027 0016 0021 0000 0003 0003 0000 -- 06 001 002 001 002 003 003 0004.75 0002.38 0000.50 | root_relative_path = normalized_path.relative_to(root).as_posix()
0027 0016 0021 0000 0003 0003 0000 -- 06 001 002 001 002 003 003 0004.75 0002.38 0000.50 | except ValueError:
0027 0016 0021 0000 0003 0003 0000 -- 06 001 002 001 002 003 003 0004.75 0002.38 0000.50 | if report:
0027 0016 0021 0000 0003 0003 0000 -- 06 001 002 001 002 003 003 0004.75 0002.38 0000.50 | report.path_ignored(
0027 0016 0021 0000 0003 0003 0000 -- 06 001 002 001 002 003 003 0004.75 0002.38 0000.50 | path, f"is a symbolic link that points outside {root}"
0027 0016 0021 0000 0003 0003 0000 -- 06 001 002 001 002 003 003 0004.75 0002.38 0000.50 | )
0027 0016 0021 0000 0003 0003 0000 -- 06 001 002 001 002 003 003 0004.75 0002.38 0000.50 | return None
0027 0016 0021 0000 0003 0003 0000 -- 06 001 002 001 002 003 003 0004.75 0002.38 0000.50 |
0027 0016 0021 0000 0003 0003 0000 -- 06 001 002 001 002 003 003 0004.75 0002.38 0000.50 | except OSError as e:
0027 0016 0021 0000 0003 0003 0000 -- 06 001 002 001 002 003 003 0004.75 0002.38 0000.50 | if report:
0027 0016 0021 0000 0003 0003 0000 -- 06 001 002 001 002 003 003 0004.75 0002.38 0000.50 | report.path_ignored(path, f"cannot be read because {e}")
0027 0016 0021 0000 0003 0003 0000 -- 06 001 002 001 002 003 003 0004.75 0002.38 0000.50 | return None
0027 0016 0021 0000 0003 0003 0000 -- 06 001 002 001 002 003 003 0004.75 0002.38 0000.50 |
0027 0016 0021 0000 0003 0003 0000 -- 06 001 002 001 002 003 003 0004.75 0002.38 0000.50 | return root_relative_path
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- |
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- |
0016 0010 0014 0002 0000 0000 0002 -- 04 001 002 001 002 003 003 0004.75 0002.38 0000.50 | def _path_is_ignored(
0016 0010 0014 0002 0000 0000 0002 -- 04 001 002 001 002 003 003 0004.75 0002.38 0000.50 | root_relative_path: str,
0016 0010 0014 0002 0000 0000 0002 -- 04 001 002 001 002 003 003 0004.75 0002.38 0000.50 | root: Path,
0016 0010 0014 0002 0000 0000 0002 -- 04 001 002 001 002 003 003 0004.75 0002.38 0000.50 | gitignore_dict: Dict[Path, PathSpec],
0016 0010 0014 0002 0000 0000 0002 -- 04 001 002 001 002 003 003 0004.75 0002.38 0000.50 | ) -> bool:
0016 0010 0014 0002 0000 0000 0002 -- 04 001 002 001 002 003 003 0004.75 0002.38 0000.50 | path = root / root_relative_path
0016 0010 0014 0002 0000 0000 0002 -- 04 001 002 001 002 003 003 0004.75 0002.38 0000.50 | # Note that this logic is sensitive to the ordering of gitignore_dict. Callers must
0016 0010 0014 0002 0000 0000 0002 -- 04 001 002 001 002 003 003 0004.75 0002.38 0000.50 | # ensure that gitignore_dict is ordered from least specific to most specific.
0016 0010 0014 0002 0000 0000 0002 -- 04 001 002 001 002 003 003 0004.75 0002.38 0000.50 | for gitignore_path, pattern in gitignore_dict.items():
0016 0010 0014 0002 0000 0000 0002 -- 04 001 002 001 002 003 003 0004.75 0002.38 0000.50 | try:
0016 0010 0014 0002 0000 0000 0002 -- 04 001 002 001 002 003 003 0004.75 0002.38 0000.50 | relative_path = path.relative_to(gitignore_path).as_posix()
0016 0010 0014 0002 0000 0000 0002 -- 04 001 002 001 002 003 003 0004.75 0002.38 0000.50 | except ValueError:
0016 0010 0014 0002 0000 0000 0002 -- 04 001 002 001 002 003 003 0004.75 0002.38 0000.50 | break
0016 0010 0014 0002 0000 0000 0002 -- 04 001 002 001 002 003 003 0004.75 0002.38 0000.50 | if pattern.match_file(relative_path):
0016 0010 0014 0002 0000 0000 0002 -- 04 001 002 001 002 003 003 0004.75 0002.38 0000.50 | return True
0016 0010 0014 0002 0000 0000 0002 -- 04 001 002 001 002 003 003 0004.75 0002.38 0000.50 | return False
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- |
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- |
0006 0003 0006 0000 0000 0000 0000 -- 03 001 002 001 002 003 003 0004.75 0002.38 0000.50 | def path_is_excluded(
0006 0003 0006 0000 0000 0000 0000 -- 03 001 002 001 002 003 003 0004.75 0002.38 0000.50 | normalized_path: str,
0006 0003 0006 0000 0000 0000 0000 -- 03 001 002 001 002 003 003 0004.75 0002.38 0000.50 | pattern: Optional[Pattern[str]],
0006 0003 0006 0000 0000 0000 0000 -- 03 001 002 001 002 003 003 0004.75 0002.38 0000.50 | ) -> bool:
0006 0003 0006 0000 0000 0000 0000 -- 03 001 002 001 002 003 003 0004.75 0002.38 0000.50 | match = pattern.search(normalized_path) if pattern else None
0006 0003 0006 0000 0000 0000 0000 -- 03 001 002 001 002 003 003 0004.75 0002.38 0000.50 | return bool(match and match.group(0))
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- |
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- |
0087 0036 0066 0004 0006 0011 0004 -- 17 008 016 011 020 024 031 0142.13 0710.67 0005.00 | def gen_python_files(
0087 0036 0066 0004 0006 0011 0004 -- 17 008 016 011 020 024 031 0142.13 0710.67 0005.00 | paths: Iterable[Path],
0087 0036 0066 0004 0006 0011 0004 -- 17 008 016 011 020 024 031 0142.13 0710.67 0005.00 | root: Path,
0087 0036 0066 0004 0006 0011 0004 -- 17 008 016 011 020 024 031 0142.13 0710.67 0005.00 | include: Pattern[str],
0087 0036 0066 0004 0006 0011 0004 -- 17 008 016 011 020 024 031 0142.13 0710.67 0005.00 | exclude: Pattern[str],
0087 0036 0066 0004 0006 0011 0004 -- 17 008 016 011 020 024 031 0142.13 0710.67 0005.00 | extend_exclude: Optional[Pattern[str]],
0087 0036 0066 0004 0006 0011 0004 -- 17 008 016 011 020 024 031 0142.13 0710.67 0005.00 | force_exclude: Optional[Pattern[str]],
0087 0036 0066 0004 0006 0011 0004 -- 17 008 016 011 020 024 031 0142.13 0710.67 0005.00 | report: Report,
0087 0036 0066 0004 0006 0011 0004 -- 17 008 016 011 020 024 031 0142.13 0710.67 0005.00 | gitignore_dict: Optional[Dict[Path, PathSpec]],
0087 0036 0066 0004 0006 0011 0004 -- 17 008 016 011 020 024 031 0142.13 0710.67 0005.00 | *,
0087 0036 0066 0004 0006 0011 0004 -- 17 008 016 011 020 024 031 0142.13 0710.67 0005.00 | verbose: bool,
0087 0036 0066 0004 0006 0011 0004 -- 17 008 016 011 020 024 031 0142.13 0710.67 0005.00 | quiet: bool,
0087 0036 0066 0004 0006 0011 0004 -- 17 008 016 011 020 024 031 0142.13 0710.67 0005.00 | ) -> Iterator[Path]:
0087 0036 0066 0004 0006 0011 0004 -- 17 008 016 011 020 024 031 0142.13 0710.67 0005.00 | """Generate all files under `path` whose paths are not excluded by the
0087 0036 0066 0004 0006 0011 0004 -- 17 008 016 011 020 024 031 0142.13 0710.67 0005.00 | `exclude_regex`, `extend_exclude`, or `force_exclude` regexes,
0087 0036 0066 0004 0006 0011 0004 -- 17 008 016 011 020 024 031 0142.13 0710.67 0005.00 | but are included by the `include` regex.
0087 0036 0066 0004 0006 0011 0004 -- 17 008 016 011 020 024 031 0142.13 0710.67 0005.00 |
0087 0036 0066 0004 0006 0011 0004 -- 17 008 016 011 020 024 031 0142.13 0710.67 0005.00 | Symbolic links pointing outside of the `root` directory are ignored.
0087 0036 0066 0004 0006 0011 0004 -- 17 008 016 011 020 024 031 0142.13 0710.67 0005.00 |
0087 0036 0066 0004 0006 0011 0004 -- 17 008 016 011 020 024 031 0142.13 0710.67 0005.00 | `report` is where output about exclusions goes.
0087 0036 0066 0004 0006 0011 0004 -- 17 008 016 011 020 024 031 0142.13 0710.67 0005.00 | """
0087 0036 0066 0004 0006 0011 0004 -- 17 008 016 011 020 024 031 0142.13 0710.67 0005.00 |
0087 0036 0066 0004 0006 0011 0004 -- 17 008 016 011 020 024 031 0142.13 0710.67 0005.00 | assert root.is_absolute(), f"INTERNAL ERROR: `root` must be absolute but is {root}"
0087 0036 0066 0004 0006 0011 0004 -- 17 008 016 011 020 024 031 0142.13 0710.67 0005.00 | for child in paths:
0087 0036 0066 0004 0006 0011 0004 -- 17 008 016 011 020 024 031 0142.13 0710.67 0005.00 | root_relative_path = child.absolute().relative_to(root).as_posix()
0087 0036 0066 0004 0006 0011 0004 -- 17 008 016 011 020 024 031 0142.13 0710.67 0005.00 |
0087 0036 0066 0004 0006 0011 0004 -- 17 008 016 011 020 024 031 0142.13 0710.67 0005.00 | # First ignore files matching .gitignore, if passed
0087 0036 0066 0004 0006 0011 0004 -- 17 008 016 011 020 024 031 0142.13 0710.67 0005.00 | if gitignore_dict and _path_is_ignored(
0087 0036 0066 0004 0006 0011 0004 -- 17 008 016 011 020 024 031 0142.13 0710.67 0005.00 | root_relative_path, root, gitignore_dict
0087 0036 0066 0004 0006 0011 0004 -- 17 008 016 011 020 024 031 0142.13 0710.67 0005.00 | ):
0087 0036 0066 0004 0006 0011 0004 -- 17 008 016 011 020 024 031 0142.13 0710.67 0005.00 | report.path_ignored(child, "matches a .gitignore file content")
0087 0036 0066 0004 0006 0011 0004 -- 17 008 016 011 020 024 031 0142.13 0710.67 0005.00 | continue
0087 0036 0066 0004 0006 0011 0004 -- 17 008 016 011 020 024 031 0142.13 0710.67 0005.00 |
0087 0036 0066 0004 0006 0011 0004 -- 17 008 016 011 020 024 031 0142.13 0710.67 0005.00 | # Then ignore with `--exclude` `--extend-exclude` and `--force-exclude` options.
0087 0036 0066 0004 0006 0011 0004 -- 17 008 016 011 020 024 031 0142.13 0710.67 0005.00 | root_relative_path = "/" + root_relative_path
0087 0036 0066 0004 0006 0011 0004 -- 17 008 016 011 020 024 031 0142.13 0710.67 0005.00 | if child.is_dir():
0087 0036 0066 0004 0006 0011 0004 -- 17 008 016 011 020 024 031 0142.13 0710.67 0005.00 | root_relative_path += "/"
0087 0036 0066 0004 0006 0011 0004 -- 17 008 016 011 020 024 031 0142.13 0710.67 0005.00 |
0087 0036 0066 0004 0006 0011 0004 -- 17 008 016 011 020 024 031 0142.13 0710.67 0005.00 | if path_is_excluded(root_relative_path, exclude):
0087 0036 0066 0004 0006 0011 0004 -- 17 008 016 011 020 024 031 0142.13 0710.67 0005.00 | report.path_ignored(child, "matches the --exclude regular expression")
0087 0036 0066 0004 0006 0011 0004 -- 17 008 016 011 020 024 031 0142.13 0710.67 0005.00 | continue
0087 0036 0066 0004 0006 0011 0004 -- 17 008 016 011 020 024 031 0142.13 0710.67 0005.00 |
0087 0036 0066 0004 0006 0011 0004 -- 17 008 016 011 020 024 031 0142.13 0710.67 0005.00 | if path_is_excluded(root_relative_path, extend_exclude):
0087 0036 0066 0004 0006 0011 0004 -- 17 008 016 011 020 024 031 0142.13 0710.67 0005.00 | report.path_ignored(
0087 0036 0066 0004 0006 0011 0004 -- 17 008 016 011 020 024 031 0142.13 0710.67 0005.00 | child, "matches the --extend-exclude regular expression"
0087 0036 0066 0004 0006 0011 0004 -- 17 008 016 011 020 024 031 0142.13 0710.67 0005.00 | )
0087 0036 0066 0004 0006 0011 0004 -- 17 008 016 011 020 024 031 0142.13 0710.67 0005.00 | continue
0087 0036 0066 0004 0006 0011 0004 -- 17 008 016 011 020 024 031 0142.13 0710.67 0005.00 |
0087 0036 0066 0004 0006 0011 0004 -- 17 008 016 011 020 024 031 0142.13 0710.67 0005.00 | if path_is_excluded(root_relative_path, force_exclude):
0087 0036 0066 0004 0006 0011 0004 -- 17 008 016 011 020 024 031 0142.13 0710.67 0005.00 | report.path_ignored(child, "matches the --force-exclude regular expression")
0087 0036 0066 0004 0006 0011 0004 -- 17 008 016 011 020 024 031 0142.13 0710.67 0005.00 | continue
0087 0036 0066 0004 0006 0011 0004 -- 17 008 016 011 020 024 031 0142.13 0710.67 0005.00 |
0087 0036 0066 0004 0006 0011 0004 -- 17 008 016 011 020 024 031 0142.13 0710.67 0005.00 | normalized_path = normalize_path_maybe_ignore(child, root, report)
0087 0036 0066 0004 0006 0011 0004 -- 17 008 016 011 020 024 031 0142.13 0710.67 0005.00 | if normalized_path is None:
0087 0036 0066 0004 0006 0011 0004 -- 17 008 016 011 020 024 031 0142.13 0710.67 0005.00 | continue
0087 0036 0066 0004 0006 0011 0004 -- 17 008 016 011 020 024 031 0142.13 0710.67 0005.00 |
0087 0036 0066 0004 0006 0011 0004 -- 17 008 016 011 020 024 031 0142.13 0710.67 0005.00 | if child.is_dir():
0087 0036 0066 0004 0006 0011 0004 -- 17 008 016 011 020 024 031 0142.13 0710.67 0005.00 | # If gitignore is None, gitignore usage is disabled, while a Falsey
0087 0036 0066 0004 0006 0011 0004 -- 17 008 016 011 020 024 031 0142.13 0710.67 0005.00 | # gitignore is when the directory doesn't have a .gitignore file.
0087 0036 0066 0004 0006 0011 0004 -- 17 008 016 011 020 024 031 0142.13 0710.67 0005.00 | if gitignore_dict is not None:
0087 0036 0066 0004 0006 0011 0004 -- 17 008 016 011 020 024 031 0142.13 0710.67 0005.00 | new_gitignore_dict = {
0087 0036 0066 0004 0006 0011 0004 -- 17 008 016 011 020 024 031 0142.13 0710.67 0005.00 | **gitignore_dict,
0087 0036 0066 0004 0006 0011 0004 -- 17 008 016 011 020 024 031 0142.13 0710.67 0005.00 | root / child: get_gitignore(child),
0087 0036 0066 0004 0006 0011 0004 -- 17 008 016 011 020 024 031 0142.13 0710.67 0005.00 | }
0087 0036 0066 0004 0006 0011 0004 -- 17 008 016 011 020 024 031 0142.13 0710.67 0005.00 | else:
0087 0036 0066 0004 0006 0011 0004 -- 17 008 016 011 020 024 031 0142.13 0710.67 0005.00 | new_gitignore_dict = None
0087 0036 0066 0004 0006 0011 0004 -- 17 008 016 011 020 024 031 0142.13 0710.67 0005.00 | yield from gen_python_files(
0087 0036 0066 0004 0006 0011 0004 -- 17 008 016 011 020 024 031 0142.13 0710.67 0005.00 | child.iterdir(),
0087 0036 0066 0004 0006 0011 0004 -- 17 008 016 011 020 024 031 0142.13 0710.67 0005.00 | root,
0087 0036 0066 0004 0006 0011 0004 -- 17 008 016 011 020 024 031 0142.13 0710.67 0005.00 | include,
0087 0036 0066 0004 0006 0011 0004 -- 17 008 016 011 020 024 031 0142.13 0710.67 0005.00 | exclude,
0087 0036 0066 0004 0006 0011 0004 -- 17 008 016 011 020 024 031 0142.13 0710.67 0005.00 | extend_exclude,
0087 0036 0066 0004 0006 0011 0004 -- 17 008 016 011 020 024 031 0142.13 0710.67 0005.00 | force_exclude,
0087 0036 0066 0004 0006 0011 0004 -- 17 008 016 011 020 024 031 0142.13 0710.67 0005.00 | report,
0087 0036 0066 0004 0006 0011 0004 -- 17 008 016 011 020 024 031 0142.13 0710.67 0005.00 | new_gitignore_dict,
0087 0036 0066 0004 0006 0011 0004 -- 17 008 016 011 020 024 031 0142.13 0710.67 0005.00 | verbose=verbose,
0087 0036 0066 0004 0006 0011 0004 -- 17 008 016 011 020 024 031 0142.13 0710.67 0005.00 | quiet=quiet,
0087 0036 0066 0004 0006 0011 0004 -- 17 008 016 011 020 024 031 0142.13 0710.67 0005.00 | )
0087 0036 0066 0004 0006 0011 0004 -- 17 008 016 011 020 024 031 0142.13 0710.67 0005.00 |
0087 0036 0066 0004 0006 0011 0004 -- 17 008 016 011 020 024 031 0142.13 0710.67 0005.00 | elif child.is_file():
0087 0036 0066 0004 0006 0011 0004 -- 17 008 016 011 020 024 031 0142.13 0710.67 0005.00 | if child.suffix == ".ipynb" and not jupyter_dependencies_are_installed(
0087 0036 0066 0004 0006 0011 0004 -- 17 008 016 011 020 024 031 0142.13 0710.67 0005.00 | warn=verbose or not quiet
0087 0036 0066 0004 0006 0011 0004 -- 17 008 016 011 020 024 031 0142.13 0710.67 0005.00 | ):
0087 0036 0066 0004 0006 0011 0004 -- 17 008 016 011 020 024 031 0142.13 0710.67 0005.00 | continue
0087 0036 0066 0004 0006 0011 0004 -- 17 008 016 011 020 024 031 0142.13 0710.67 0005.00 | include_match = include.search(root_relative_path) if include else True
0087 0036 0066 0004 0006 0011 0004 -- 17 008 016 011 020 024 031 0142.13 0710.67 0005.00 | if include_match:
0087 0036 0066 0004 0006 0011 0004 -- 17 008 016 011 020 024 031 0142.13 0710.67 0005.00 | yield child
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- |
---- ---- ---- ---- ---- ---- ---- -- -- --- --- --- --- --- --- ------- ------- ------- |
0018 0008 0009 0001 0007 0001 0001 -- 03 000 000 000 000 000 000 0000.00 0000.00 0000.00 | def wrap_stream_for_windows(
0018 0008 0009 0001 0007 0001 0001 -- 03 000 000 000 000 000 000 0000.00 0000.00 0000.00 | f: io.TextIOWrapper,
0018 0008 0009 0001 0007 0001 0001 -- 03 000 000 000 000 000 000 0000.00 0000.00 0000.00 | ) -> Union[io.TextIOWrapper, "colorama.AnsiToWin32"]:
0018 0008 0009 0001 0007 0001 0001 -- 03 000 000 000 000 000 000 0000.00 0000.00 0000.00 | """
0018 0008 0009 0001 0007 0001 0001 -- 03 000 000 000 000 000 000 0000.00 0000.00 0000.00 | Wrap stream with colorama's wrap_stream so colors are shown on Windows.
0018 0008 0009 0001 0007 0001 0001 -- 03 000 000 000 000 000 000 0000.00 0000.00 0000.00 |
0018 0008 0009 0001 0007 0001 0001 -- 03 000 000 000 000 000 000 0000.00 0000.00 0000.00 | If `colorama` is unavailable, the original stream is returned unmodified.
0018 0008 0009 0001 0007 0001 0001 -- 03 000 000 000 000 000 000 0000.00 0000.00 0000.00 | Otherwise, the `wrap_stream()` function determines whether the stream needs
0018 0008 0009 0001 0007 0001 0001 -- 03 000 000 000 000 000 000 0000.00 0000.00 0000.00 | to be wrapped for a Windows environment and will accordingly either return
0018 0008 0009 0001 0007 0001 0001 -- 03 000 000 000 000 000 000 0000.00 0000.00 0000.00 | an `AnsiToWin32` wrapper or the original stream.
0018 0008 0009 0001 0007 0001 0001 -- 03 000 000 000 000 000 000 0000.00 0000.00 0000.00 | """
0018 0008 0009 0001 0007 0001 0001 -- 03 000 000 000 000 000 000 0000.00 0000.00 0000.00 | try:
0018 0008 0009 0001 0007 0001 0001 -- 03 000 000 000 000 000 000 0000.00 0000.00 0000.00 | from colorama.initialise import wrap_stream
0018 0008 0009 0001 0007 0001 0001 -- 03 000 000 000 000 000 000 0000.00 0000.00 0000.00 | except ImportError:
0018 0008 0009 0001 0007 0001 0001 -- 03 000 000 000 000 000 000 0000.00 0000.00 0000.00 | return f
0018 0008 0009 0001 0007 0001 0001 -- 03 000 000 000 000 000 000 0000.00 0000.00 0000.00 | else:
0018 0008 0009 0001 0007 0001 0001 -- 03 000 000 000 000 000 000 0000.00 0000.00 0000.00 | # Set `strip=False` to avoid needing to modify test_express_diff_with_color.
0018 0008 0009 0001 0007 0001 0001 -- 03 000 000 000 000 000 000 0000.00 0000.00 0000.00 | return wrap_stream(f, convert=None, strip=False, autoreset=False, wrap=True)