]> git.madduck.net Git - etc/vim.git/blob - black.py

madduck's git repository

Every one of the projects in this repository is available at the canonical URL git://git.madduck.net/madduck/pub/<projectpath> — see each project's metadata for the exact URL.

All patches and comments are welcome. Please squash your changes to logical commits before using git-format-patch and git-send-email to patches@git.madduck.net. If you'd read over the Git project's submission guidelines and adhered to them, I'd be especially grateful.

SSH access, as well as push access can be individually arranged.

If you use my repositories frequently, consider adding the following snippet to ~/.gitconfig and using the third clone URL listed for each project:

[url "git://git.madduck.net/madduck/"]
  insteadOf = madduck:

Fix long trivial assignments being wrapped in unnecessary parentheses
[etc/vim.git] / black.py
1 import asyncio
2 from asyncio.base_events import BaseEventLoop
3 from concurrent.futures import Executor, ProcessPoolExecutor
4 from datetime import datetime
5 from enum import Enum, Flag
6 from functools import partial, wraps
7 import io
8 import keyword
9 import logging
10 from multiprocessing import Manager
11 import os
12 from pathlib import Path
13 import pickle
14 import re
15 import signal
16 import sys
17 import tokenize
18 from typing import (
19     Any,
20     Callable,
21     Collection,
22     Dict,
23     Generic,
24     Iterable,
25     Iterator,
26     List,
27     Optional,
28     Pattern,
29     Sequence,
30     Set,
31     Tuple,
32     Type,
33     TypeVar,
34     Union,
35     cast,
36 )
37
38 from appdirs import user_cache_dir
39 from attr import dataclass, Factory
40 import click
41
42 # lib2to3 fork
43 from blib2to3.pytree import Node, Leaf, type_repr
44 from blib2to3 import pygram, pytree
45 from blib2to3.pgen2 import driver, token
46 from blib2to3.pgen2.parse import ParseError
47
48
49 __version__ = "18.5b1"
50 DEFAULT_LINE_LENGTH = 88
51 DEFAULT_EXCLUDES = (
52     r"/(\.git|\.hg|\.mypy_cache|\.tox|\.venv|_build|buck-out|build|dist)/"
53 )
54 DEFAULT_INCLUDES = r"\.pyi?$"
55 CACHE_DIR = Path(user_cache_dir("black", version=__version__))
56
57
58 # types
59 FileContent = str
60 Encoding = str
61 NewLine = str
62 Depth = int
63 NodeType = int
64 LeafID = int
65 Priority = int
66 Index = int
67 LN = Union[Leaf, Node]
68 SplitFunc = Callable[["Line", bool], Iterator["Line"]]
69 Timestamp = float
70 FileSize = int
71 CacheInfo = Tuple[Timestamp, FileSize]
72 Cache = Dict[Path, CacheInfo]
73 out = partial(click.secho, bold=True, err=True)
74 err = partial(click.secho, fg="red", err=True)
75
76 pygram.initialize(CACHE_DIR)
77 syms = pygram.python_symbols
78
79
80 class NothingChanged(UserWarning):
81     """Raised by :func:`format_file` when reformatted code is the same as source."""
82
83
84 class CannotSplit(Exception):
85     """A readable split that fits the allotted line length is impossible.
86
87     Raised by :func:`left_hand_split`, :func:`right_hand_split`, and
88     :func:`delimiter_split`.
89     """
90
91
92 class FormatError(Exception):
93     """Base exception for `# fmt: on` and `# fmt: off` handling.
94
95     It holds the number of bytes of the prefix consumed before the format
96     control comment appeared.
97     """
98
99     def __init__(self, consumed: int) -> None:
100         super().__init__(consumed)
101         self.consumed = consumed
102
103     def trim_prefix(self, leaf: Leaf) -> None:
104         leaf.prefix = leaf.prefix[self.consumed :]
105
106     def leaf_from_consumed(self, leaf: Leaf) -> Leaf:
107         """Returns a new Leaf from the consumed part of the prefix."""
108         unformatted_prefix = leaf.prefix[: self.consumed]
109         return Leaf(token.NEWLINE, unformatted_prefix)
110
111
112 class FormatOn(FormatError):
113     """Found a comment like `# fmt: on` in the file."""
114
115
116 class FormatOff(FormatError):
117     """Found a comment like `# fmt: off` in the file."""
118
119
120 class WriteBack(Enum):
121     NO = 0
122     YES = 1
123     DIFF = 2
124
125     @classmethod
126     def from_configuration(cls, *, check: bool, diff: bool) -> "WriteBack":
127         if check and not diff:
128             return cls.NO
129
130         return cls.DIFF if diff else cls.YES
131
132
133 class Changed(Enum):
134     NO = 0
135     CACHED = 1
136     YES = 2
137
138
139 class FileMode(Flag):
140     AUTO_DETECT = 0
141     PYTHON36 = 1
142     PYI = 2
143     NO_STRING_NORMALIZATION = 4
144
145     @classmethod
146     def from_configuration(
147         cls, *, py36: bool, pyi: bool, skip_string_normalization: bool
148     ) -> "FileMode":
149         mode = cls.AUTO_DETECT
150         if py36:
151             mode |= cls.PYTHON36
152         if pyi:
153             mode |= cls.PYI
154         if skip_string_normalization:
155             mode |= cls.NO_STRING_NORMALIZATION
156         return mode
157
158
159 @click.command()
160 @click.option(
161     "-l",
162     "--line-length",
163     type=int,
164     default=DEFAULT_LINE_LENGTH,
165     help="How many character per line to allow.",
166     show_default=True,
167 )
168 @click.option(
169     "--py36",
170     is_flag=True,
171     help=(
172         "Allow using Python 3.6-only syntax on all input files.  This will put "
173         "trailing commas in function signatures and calls also after *args and "
174         "**kwargs.  [default: per-file auto-detection]"
175     ),
176 )
177 @click.option(
178     "--pyi",
179     is_flag=True,
180     help=(
181         "Format all input files like typing stubs regardless of file extension "
182         "(useful when piping source on standard input)."
183     ),
184 )
185 @click.option(
186     "-S",
187     "--skip-string-normalization",
188     is_flag=True,
189     help="Don't normalize string quotes or prefixes.",
190 )
191 @click.option(
192     "--check",
193     is_flag=True,
194     help=(
195         "Don't write the files back, just return the status.  Return code 0 "
196         "means nothing would change.  Return code 1 means some files would be "
197         "reformatted.  Return code 123 means there was an internal error."
198     ),
199 )
200 @click.option(
201     "--diff",
202     is_flag=True,
203     help="Don't write the files back, just output a diff for each file on stdout.",
204 )
205 @click.option(
206     "--fast/--safe",
207     is_flag=True,
208     help="If --fast given, skip temporary sanity checks. [default: --safe]",
209 )
210 @click.option(
211     "--include",
212     type=str,
213     default=DEFAULT_INCLUDES,
214     help=(
215         "A regular expression that matches files and directories that should be "
216         "included on recursive searches.  An empty value means all files are "
217         "included regardless of the name.  Use forward slashes for directories on "
218         "all platforms (Windows, too).  Exclusions are calculated first, inclusions "
219         "later."
220     ),
221     show_default=True,
222 )
223 @click.option(
224     "--exclude",
225     type=str,
226     default=DEFAULT_EXCLUDES,
227     help=(
228         "A regular expression that matches files and directories that should be "
229         "excluded on recursive searches.  An empty value means no paths are excluded. "
230         "Use forward slashes for directories on all platforms (Windows, too).  "
231         "Exclusions are calculated first, inclusions later."
232     ),
233     show_default=True,
234 )
235 @click.option(
236     "-q",
237     "--quiet",
238     is_flag=True,
239     help=(
240         "Don't emit non-error messages to stderr. Errors are still emitted, "
241         "silence those with 2>/dev/null."
242     ),
243 )
244 @click.option(
245     "-v",
246     "--verbose",
247     is_flag=True,
248     help=(
249         "Also emit messages to stderr about files that were not changed or were "
250         "ignored due to --exclude=."
251     ),
252 )
253 @click.version_option(version=__version__)
254 @click.argument(
255     "src",
256     nargs=-1,
257     type=click.Path(
258         exists=True, file_okay=True, dir_okay=True, readable=True, allow_dash=True
259     ),
260 )
261 @click.pass_context
262 def main(
263     ctx: click.Context,
264     line_length: int,
265     check: bool,
266     diff: bool,
267     fast: bool,
268     pyi: bool,
269     py36: bool,
270     skip_string_normalization: bool,
271     quiet: bool,
272     verbose: bool,
273     include: str,
274     exclude: str,
275     src: List[str],
276 ) -> None:
277     """The uncompromising code formatter."""
278     write_back = WriteBack.from_configuration(check=check, diff=diff)
279     mode = FileMode.from_configuration(
280         py36=py36, pyi=pyi, skip_string_normalization=skip_string_normalization
281     )
282     report = Report(check=check, quiet=quiet, verbose=verbose)
283     sources: Set[Path] = set()
284     try:
285         include_regex = re.compile(include)
286     except re.error:
287         err(f"Invalid regular expression for include given: {include!r}")
288         ctx.exit(2)
289     try:
290         exclude_regex = re.compile(exclude)
291     except re.error:
292         err(f"Invalid regular expression for exclude given: {exclude!r}")
293         ctx.exit(2)
294     root = find_project_root(src)
295     for s in src:
296         p = Path(s)
297         if p.is_dir():
298             sources.update(
299                 gen_python_files_in_dir(p, root, include_regex, exclude_regex, report)
300             )
301         elif p.is_file() or s == "-":
302             # if a file was explicitly given, we don't care about its extension
303             sources.add(p)
304         else:
305             err(f"invalid path: {s}")
306     if len(sources) == 0:
307         if verbose or not quiet:
308             out("No paths given. Nothing to do 😴")
309         ctx.exit(0)
310         return
311
312     elif len(sources) == 1:
313         reformat_one(
314             src=sources.pop(),
315             line_length=line_length,
316             fast=fast,
317             write_back=write_back,
318             mode=mode,
319             report=report,
320         )
321     else:
322         loop = asyncio.get_event_loop()
323         executor = ProcessPoolExecutor(max_workers=os.cpu_count())
324         try:
325             loop.run_until_complete(
326                 schedule_formatting(
327                     sources=sources,
328                     line_length=line_length,
329                     fast=fast,
330                     write_back=write_back,
331                     mode=mode,
332                     report=report,
333                     loop=loop,
334                     executor=executor,
335                 )
336             )
337         finally:
338             shutdown(loop)
339     if verbose or not quiet:
340         out("All done! ✨ 🍰 ✨")
341         click.echo(str(report))
342     ctx.exit(report.return_code)
343
344
345 def reformat_one(
346     src: Path,
347     line_length: int,
348     fast: bool,
349     write_back: WriteBack,
350     mode: FileMode,
351     report: "Report",
352 ) -> None:
353     """Reformat a single file under `src` without spawning child processes.
354
355     If `quiet` is True, non-error messages are not output. `line_length`,
356     `write_back`, `fast` and `pyi` options are passed to
357     :func:`format_file_in_place` or :func:`format_stdin_to_stdout`.
358     """
359     try:
360         changed = Changed.NO
361         if not src.is_file() and str(src) == "-":
362             if format_stdin_to_stdout(
363                 line_length=line_length, fast=fast, write_back=write_back, mode=mode
364             ):
365                 changed = Changed.YES
366         else:
367             cache: Cache = {}
368             if write_back != WriteBack.DIFF:
369                 cache = read_cache(line_length, mode)
370                 res_src = src.resolve()
371                 if res_src in cache and cache[res_src] == get_cache_info(res_src):
372                     changed = Changed.CACHED
373             if changed is not Changed.CACHED and format_file_in_place(
374                 src,
375                 line_length=line_length,
376                 fast=fast,
377                 write_back=write_back,
378                 mode=mode,
379             ):
380                 changed = Changed.YES
381             if write_back == WriteBack.YES and changed is not Changed.NO:
382                 write_cache(cache, [src], line_length, mode)
383         report.done(src, changed)
384     except Exception as exc:
385         report.failed(src, str(exc))
386
387
388 async def schedule_formatting(
389     sources: Set[Path],
390     line_length: int,
391     fast: bool,
392     write_back: WriteBack,
393     mode: FileMode,
394     report: "Report",
395     loop: BaseEventLoop,
396     executor: Executor,
397 ) -> None:
398     """Run formatting of `sources` in parallel using the provided `executor`.
399
400     (Use ProcessPoolExecutors for actual parallelism.)
401
402     `line_length`, `write_back`, `fast`, and `pyi` options are passed to
403     :func:`format_file_in_place`.
404     """
405     cache: Cache = {}
406     if write_back != WriteBack.DIFF:
407         cache = read_cache(line_length, mode)
408         sources, cached = filter_cached(cache, sources)
409         for src in sorted(cached):
410             report.done(src, Changed.CACHED)
411     cancelled = []
412     formatted = []
413     if sources:
414         lock = None
415         if write_back == WriteBack.DIFF:
416             # For diff output, we need locks to ensure we don't interleave output
417             # from different processes.
418             manager = Manager()
419             lock = manager.Lock()
420         tasks = {
421             loop.run_in_executor(
422                 executor,
423                 format_file_in_place,
424                 src,
425                 line_length,
426                 fast,
427                 write_back,
428                 mode,
429                 lock,
430             ): src
431             for src in sorted(sources)
432         }
433         pending: Iterable[asyncio.Task] = tasks.keys()
434         try:
435             loop.add_signal_handler(signal.SIGINT, cancel, pending)
436             loop.add_signal_handler(signal.SIGTERM, cancel, pending)
437         except NotImplementedError:
438             # There are no good alternatives for these on Windows
439             pass
440         while pending:
441             done, _ = await asyncio.wait(pending, return_when=asyncio.FIRST_COMPLETED)
442             for task in done:
443                 src = tasks.pop(task)
444                 if task.cancelled():
445                     cancelled.append(task)
446                 elif task.exception():
447                     report.failed(src, str(task.exception()))
448                 else:
449                     formatted.append(src)
450                     report.done(src, Changed.YES if task.result() else Changed.NO)
451     if cancelled:
452         await asyncio.gather(*cancelled, loop=loop, return_exceptions=True)
453     if write_back == WriteBack.YES and formatted:
454         write_cache(cache, formatted, line_length, mode)
455
456
457 def format_file_in_place(
458     src: Path,
459     line_length: int,
460     fast: bool,
461     write_back: WriteBack = WriteBack.NO,
462     mode: FileMode = FileMode.AUTO_DETECT,
463     lock: Any = None,  # multiprocessing.Manager().Lock() is some crazy proxy
464 ) -> bool:
465     """Format file under `src` path. Return True if changed.
466
467     If `write_back` is True, write reformatted code back to stdout.
468     `line_length` and `fast` options are passed to :func:`format_file_contents`.
469     """
470     if src.suffix == ".pyi":
471         mode |= FileMode.PYI
472
473     then = datetime.utcfromtimestamp(src.stat().st_mtime)
474     with open(src, "rb") as buf:
475         src_contents, encoding, newline = decode_bytes(buf.read())
476     try:
477         dst_contents = format_file_contents(
478             src_contents, line_length=line_length, fast=fast, mode=mode
479         )
480     except NothingChanged:
481         return False
482
483     if write_back == write_back.YES:
484         with open(src, "w", encoding=encoding, newline=newline) as f:
485             f.write(dst_contents)
486     elif write_back == write_back.DIFF:
487         now = datetime.utcnow()
488         src_name = f"{src}\t{then} +0000"
489         dst_name = f"{src}\t{now} +0000"
490         diff_contents = diff(src_contents, dst_contents, src_name, dst_name)
491         if lock:
492             lock.acquire()
493         try:
494             f = io.TextIOWrapper(
495                 sys.stdout.buffer,
496                 encoding=encoding,
497                 newline=newline,
498                 write_through=True,
499             )
500             f.write(diff_contents)
501             f.detach()
502         finally:
503             if lock:
504                 lock.release()
505     return True
506
507
508 def format_stdin_to_stdout(
509     line_length: int,
510     fast: bool,
511     write_back: WriteBack = WriteBack.NO,
512     mode: FileMode = FileMode.AUTO_DETECT,
513 ) -> bool:
514     """Format file on stdin. Return True if changed.
515
516     If `write_back` is True, write reformatted code back to stdout.
517     `line_length`, `fast`, `is_pyi`, and `force_py36` arguments are passed to
518     :func:`format_file_contents`.
519     """
520     then = datetime.utcnow()
521     src, encoding, newline = decode_bytes(sys.stdin.buffer.read())
522     dst = src
523     try:
524         dst = format_file_contents(src, line_length=line_length, fast=fast, mode=mode)
525         return True
526
527     except NothingChanged:
528         return False
529
530     finally:
531         f = io.TextIOWrapper(
532             sys.stdout.buffer, encoding=encoding, newline=newline, write_through=True
533         )
534         if write_back == WriteBack.YES:
535             f.write(dst)
536         elif write_back == WriteBack.DIFF:
537             now = datetime.utcnow()
538             src_name = f"STDIN\t{then} +0000"
539             dst_name = f"STDOUT\t{now} +0000"
540             f.write(diff(src, dst, src_name, dst_name))
541         f.detach()
542
543
544 def format_file_contents(
545     src_contents: str,
546     *,
547     line_length: int,
548     fast: bool,
549     mode: FileMode = FileMode.AUTO_DETECT,
550 ) -> FileContent:
551     """Reformat contents a file and return new contents.
552
553     If `fast` is False, additionally confirm that the reformatted code is
554     valid by calling :func:`assert_equivalent` and :func:`assert_stable` on it.
555     `line_length` is passed to :func:`format_str`.
556     """
557     if src_contents.strip() == "":
558         raise NothingChanged
559
560     dst_contents = format_str(src_contents, line_length=line_length, mode=mode)
561     if src_contents == dst_contents:
562         raise NothingChanged
563
564     if not fast:
565         assert_equivalent(src_contents, dst_contents)
566         assert_stable(src_contents, dst_contents, line_length=line_length, mode=mode)
567     return dst_contents
568
569
570 def format_str(
571     src_contents: str, line_length: int, *, mode: FileMode = FileMode.AUTO_DETECT
572 ) -> FileContent:
573     """Reformat a string and return new contents.
574
575     `line_length` determines how many characters per line are allowed.
576     """
577     src_node = lib2to3_parse(src_contents)
578     dst_contents = ""
579     future_imports = get_future_imports(src_node)
580     is_pyi = bool(mode & FileMode.PYI)
581     py36 = bool(mode & FileMode.PYTHON36) or is_python36(src_node)
582     normalize_strings = not bool(mode & FileMode.NO_STRING_NORMALIZATION)
583     lines = LineGenerator(
584         remove_u_prefix=py36 or "unicode_literals" in future_imports,
585         is_pyi=is_pyi,
586         normalize_strings=normalize_strings,
587     )
588     elt = EmptyLineTracker(is_pyi=is_pyi)
589     empty_line = Line()
590     after = 0
591     for current_line in lines.visit(src_node):
592         for _ in range(after):
593             dst_contents += str(empty_line)
594         before, after = elt.maybe_empty_lines(current_line)
595         for _ in range(before):
596             dst_contents += str(empty_line)
597         for line in split_line(current_line, line_length=line_length, py36=py36):
598             dst_contents += str(line)
599     return dst_contents
600
601
602 def decode_bytes(src: bytes) -> Tuple[FileContent, Encoding, NewLine]:
603     """Return a tuple of (decoded_contents, encoding, newline).
604
605     `newline` is either CRLF or LF but `decoded_contents` is decoded with
606     universal newlines (i.e. only contains LF).
607     """
608     srcbuf = io.BytesIO(src)
609     encoding, lines = tokenize.detect_encoding(srcbuf.readline)
610     if not lines:
611         return "", encoding, "\n"
612
613     newline = "\r\n" if b"\r\n" == lines[0][-2:] else "\n"
614     srcbuf.seek(0)
615     with io.TextIOWrapper(srcbuf, encoding) as tiow:
616         return tiow.read(), encoding, newline
617
618
619 GRAMMARS = [
620     pygram.python_grammar_no_print_statement_no_exec_statement,
621     pygram.python_grammar_no_print_statement,
622     pygram.python_grammar,
623 ]
624
625
626 def lib2to3_parse(src_txt: str) -> Node:
627     """Given a string with source, return the lib2to3 Node."""
628     grammar = pygram.python_grammar_no_print_statement
629     if src_txt[-1:] != "\n":
630         src_txt += "\n"
631     for grammar in GRAMMARS:
632         drv = driver.Driver(grammar, pytree.convert)
633         try:
634             result = drv.parse_string(src_txt, True)
635             break
636
637         except ParseError as pe:
638             lineno, column = pe.context[1]
639             lines = src_txt.splitlines()
640             try:
641                 faulty_line = lines[lineno - 1]
642             except IndexError:
643                 faulty_line = "<line number missing in source>"
644             exc = ValueError(f"Cannot parse: {lineno}:{column}: {faulty_line}")
645     else:
646         raise exc from None
647
648     if isinstance(result, Leaf):
649         result = Node(syms.file_input, [result])
650     return result
651
652
653 def lib2to3_unparse(node: Node) -> str:
654     """Given a lib2to3 node, return its string representation."""
655     code = str(node)
656     return code
657
658
659 T = TypeVar("T")
660
661
662 class Visitor(Generic[T]):
663     """Basic lib2to3 visitor that yields things of type `T` on `visit()`."""
664
665     def visit(self, node: LN) -> Iterator[T]:
666         """Main method to visit `node` and its children.
667
668         It tries to find a `visit_*()` method for the given `node.type`, like
669         `visit_simple_stmt` for Node objects or `visit_INDENT` for Leaf objects.
670         If no dedicated `visit_*()` method is found, chooses `visit_default()`
671         instead.
672
673         Then yields objects of type `T` from the selected visitor.
674         """
675         if node.type < 256:
676             name = token.tok_name[node.type]
677         else:
678             name = type_repr(node.type)
679         yield from getattr(self, f"visit_{name}", self.visit_default)(node)
680
681     def visit_default(self, node: LN) -> Iterator[T]:
682         """Default `visit_*()` implementation. Recurses to children of `node`."""
683         if isinstance(node, Node):
684             for child in node.children:
685                 yield from self.visit(child)
686
687
688 @dataclass
689 class DebugVisitor(Visitor[T]):
690     tree_depth: int = 0
691
692     def visit_default(self, node: LN) -> Iterator[T]:
693         indent = " " * (2 * self.tree_depth)
694         if isinstance(node, Node):
695             _type = type_repr(node.type)
696             out(f"{indent}{_type}", fg="yellow")
697             self.tree_depth += 1
698             for child in node.children:
699                 yield from self.visit(child)
700
701             self.tree_depth -= 1
702             out(f"{indent}/{_type}", fg="yellow", bold=False)
703         else:
704             _type = token.tok_name.get(node.type, str(node.type))
705             out(f"{indent}{_type}", fg="blue", nl=False)
706             if node.prefix:
707                 # We don't have to handle prefixes for `Node` objects since
708                 # that delegates to the first child anyway.
709                 out(f" {node.prefix!r}", fg="green", bold=False, nl=False)
710             out(f" {node.value!r}", fg="blue", bold=False)
711
712     @classmethod
713     def show(cls, code: str) -> None:
714         """Pretty-print the lib2to3 AST of a given string of `code`.
715
716         Convenience method for debugging.
717         """
718         v: DebugVisitor[None] = DebugVisitor()
719         list(v.visit(lib2to3_parse(code)))
720
721
722 KEYWORDS = set(keyword.kwlist)
723 WHITESPACE = {token.DEDENT, token.INDENT, token.NEWLINE}
724 FLOW_CONTROL = {"return", "raise", "break", "continue"}
725 STATEMENT = {
726     syms.if_stmt,
727     syms.while_stmt,
728     syms.for_stmt,
729     syms.try_stmt,
730     syms.except_clause,
731     syms.with_stmt,
732     syms.funcdef,
733     syms.classdef,
734 }
735 STANDALONE_COMMENT = 153
736 LOGIC_OPERATORS = {"and", "or"}
737 COMPARATORS = {
738     token.LESS,
739     token.GREATER,
740     token.EQEQUAL,
741     token.NOTEQUAL,
742     token.LESSEQUAL,
743     token.GREATEREQUAL,
744 }
745 MATH_OPERATORS = {
746     token.VBAR,
747     token.CIRCUMFLEX,
748     token.AMPER,
749     token.LEFTSHIFT,
750     token.RIGHTSHIFT,
751     token.PLUS,
752     token.MINUS,
753     token.STAR,
754     token.SLASH,
755     token.DOUBLESLASH,
756     token.PERCENT,
757     token.AT,
758     token.TILDE,
759     token.DOUBLESTAR,
760 }
761 STARS = {token.STAR, token.DOUBLESTAR}
762 VARARGS_PARENTS = {
763     syms.arglist,
764     syms.argument,  # double star in arglist
765     syms.trailer,  # single argument to call
766     syms.typedargslist,
767     syms.varargslist,  # lambdas
768 }
769 UNPACKING_PARENTS = {
770     syms.atom,  # single element of a list or set literal
771     syms.dictsetmaker,
772     syms.listmaker,
773     syms.testlist_gexp,
774     syms.testlist_star_expr,
775 }
776 TEST_DESCENDANTS = {
777     syms.test,
778     syms.lambdef,
779     syms.or_test,
780     syms.and_test,
781     syms.not_test,
782     syms.comparison,
783     syms.star_expr,
784     syms.expr,
785     syms.xor_expr,
786     syms.and_expr,
787     syms.shift_expr,
788     syms.arith_expr,
789     syms.trailer,
790     syms.term,
791     syms.power,
792 }
793 ASSIGNMENTS = {
794     "=",
795     "+=",
796     "-=",
797     "*=",
798     "@=",
799     "/=",
800     "%=",
801     "&=",
802     "|=",
803     "^=",
804     "<<=",
805     ">>=",
806     "**=",
807     "//=",
808 }
809 COMPREHENSION_PRIORITY = 20
810 COMMA_PRIORITY = 18
811 TERNARY_PRIORITY = 16
812 LOGIC_PRIORITY = 14
813 STRING_PRIORITY = 12
814 COMPARATOR_PRIORITY = 10
815 MATH_PRIORITIES = {
816     token.VBAR: 9,
817     token.CIRCUMFLEX: 8,
818     token.AMPER: 7,
819     token.LEFTSHIFT: 6,
820     token.RIGHTSHIFT: 6,
821     token.PLUS: 5,
822     token.MINUS: 5,
823     token.STAR: 4,
824     token.SLASH: 4,
825     token.DOUBLESLASH: 4,
826     token.PERCENT: 4,
827     token.AT: 4,
828     token.TILDE: 3,
829     token.DOUBLESTAR: 2,
830 }
831 DOT_PRIORITY = 1
832
833
834 @dataclass
835 class BracketTracker:
836     """Keeps track of brackets on a line."""
837
838     depth: int = 0
839     bracket_match: Dict[Tuple[Depth, NodeType], Leaf] = Factory(dict)
840     delimiters: Dict[LeafID, Priority] = Factory(dict)
841     previous: Optional[Leaf] = None
842     _for_loop_variable: int = 0
843     _lambda_arguments: int = 0
844
845     def mark(self, leaf: Leaf) -> None:
846         """Mark `leaf` with bracket-related metadata. Keep track of delimiters.
847
848         All leaves receive an int `bracket_depth` field that stores how deep
849         within brackets a given leaf is. 0 means there are no enclosing brackets
850         that started on this line.
851
852         If a leaf is itself a closing bracket, it receives an `opening_bracket`
853         field that it forms a pair with. This is a one-directional link to
854         avoid reference cycles.
855
856         If a leaf is a delimiter (a token on which Black can split the line if
857         needed) and it's on depth 0, its `id()` is stored in the tracker's
858         `delimiters` field.
859         """
860         if leaf.type == token.COMMENT:
861             return
862
863         self.maybe_decrement_after_for_loop_variable(leaf)
864         self.maybe_decrement_after_lambda_arguments(leaf)
865         if leaf.type in CLOSING_BRACKETS:
866             self.depth -= 1
867             opening_bracket = self.bracket_match.pop((self.depth, leaf.type))
868             leaf.opening_bracket = opening_bracket
869         leaf.bracket_depth = self.depth
870         if self.depth == 0:
871             delim = is_split_before_delimiter(leaf, self.previous)
872             if delim and self.previous is not None:
873                 self.delimiters[id(self.previous)] = delim
874             else:
875                 delim = is_split_after_delimiter(leaf, self.previous)
876                 if delim:
877                     self.delimiters[id(leaf)] = delim
878         if leaf.type in OPENING_BRACKETS:
879             self.bracket_match[self.depth, BRACKET[leaf.type]] = leaf
880             self.depth += 1
881         self.previous = leaf
882         self.maybe_increment_lambda_arguments(leaf)
883         self.maybe_increment_for_loop_variable(leaf)
884
885     def any_open_brackets(self) -> bool:
886         """Return True if there is an yet unmatched open bracket on the line."""
887         return bool(self.bracket_match)
888
889     def max_delimiter_priority(self, exclude: Iterable[LeafID] = ()) -> int:
890         """Return the highest priority of a delimiter found on the line.
891
892         Values are consistent with what `is_split_*_delimiter()` return.
893         Raises ValueError on no delimiters.
894         """
895         return max(v for k, v in self.delimiters.items() if k not in exclude)
896
897     def delimiter_count_with_priority(self, priority: int = 0) -> int:
898         """Return the number of delimiters with the given `priority`.
899
900         If no `priority` is passed, defaults to max priority on the line.
901         """
902         if not self.delimiters:
903             return 0
904
905         priority = priority or self.max_delimiter_priority()
906         return sum(1 for p in self.delimiters.values() if p == priority)
907
908     def maybe_increment_for_loop_variable(self, leaf: Leaf) -> bool:
909         """In a for loop, or comprehension, the variables are often unpacks.
910
911         To avoid splitting on the comma in this situation, increase the depth of
912         tokens between `for` and `in`.
913         """
914         if leaf.type == token.NAME and leaf.value == "for":
915             self.depth += 1
916             self._for_loop_variable += 1
917             return True
918
919         return False
920
921     def maybe_decrement_after_for_loop_variable(self, leaf: Leaf) -> bool:
922         """See `maybe_increment_for_loop_variable` above for explanation."""
923         if self._for_loop_variable and leaf.type == token.NAME and leaf.value == "in":
924             self.depth -= 1
925             self._for_loop_variable -= 1
926             return True
927
928         return False
929
930     def maybe_increment_lambda_arguments(self, leaf: Leaf) -> bool:
931         """In a lambda expression, there might be more than one argument.
932
933         To avoid splitting on the comma in this situation, increase the depth of
934         tokens between `lambda` and `:`.
935         """
936         if leaf.type == token.NAME and leaf.value == "lambda":
937             self.depth += 1
938             self._lambda_arguments += 1
939             return True
940
941         return False
942
943     def maybe_decrement_after_lambda_arguments(self, leaf: Leaf) -> bool:
944         """See `maybe_increment_lambda_arguments` above for explanation."""
945         if self._lambda_arguments and leaf.type == token.COLON:
946             self.depth -= 1
947             self._lambda_arguments -= 1
948             return True
949
950         return False
951
952     def get_open_lsqb(self) -> Optional[Leaf]:
953         """Return the most recent opening square bracket (if any)."""
954         return self.bracket_match.get((self.depth - 1, token.RSQB))
955
956
957 @dataclass
958 class Line:
959     """Holds leaves and comments. Can be printed with `str(line)`."""
960
961     depth: int = 0
962     leaves: List[Leaf] = Factory(list)
963     comments: List[Tuple[Index, Leaf]] = Factory(list)
964     bracket_tracker: BracketTracker = Factory(BracketTracker)
965     inside_brackets: bool = False
966     should_explode: bool = False
967
968     def append(self, leaf: Leaf, preformatted: bool = False) -> None:
969         """Add a new `leaf` to the end of the line.
970
971         Unless `preformatted` is True, the `leaf` will receive a new consistent
972         whitespace prefix and metadata applied by :class:`BracketTracker`.
973         Trailing commas are maybe removed, unpacked for loop variables are
974         demoted from being delimiters.
975
976         Inline comments are put aside.
977         """
978         has_value = leaf.type in BRACKETS or bool(leaf.value.strip())
979         if not has_value:
980             return
981
982         if token.COLON == leaf.type and self.is_class_paren_empty:
983             del self.leaves[-2:]
984         if self.leaves and not preformatted:
985             # Note: at this point leaf.prefix should be empty except for
986             # imports, for which we only preserve newlines.
987             leaf.prefix += whitespace(
988                 leaf, complex_subscript=self.is_complex_subscript(leaf)
989             )
990         if self.inside_brackets or not preformatted:
991             self.bracket_tracker.mark(leaf)
992             self.maybe_remove_trailing_comma(leaf)
993         if not self.append_comment(leaf):
994             self.leaves.append(leaf)
995
996     def append_safe(self, leaf: Leaf, preformatted: bool = False) -> None:
997         """Like :func:`append()` but disallow invalid standalone comment structure.
998
999         Raises ValueError when any `leaf` is appended after a standalone comment
1000         or when a standalone comment is not the first leaf on the line.
1001         """
1002         if self.bracket_tracker.depth == 0:
1003             if self.is_comment:
1004                 raise ValueError("cannot append to standalone comments")
1005
1006             if self.leaves and leaf.type == STANDALONE_COMMENT:
1007                 raise ValueError(
1008                     "cannot append standalone comments to a populated line"
1009                 )
1010
1011         self.append(leaf, preformatted=preformatted)
1012
1013     @property
1014     def is_comment(self) -> bool:
1015         """Is this line a standalone comment?"""
1016         return len(self.leaves) == 1 and self.leaves[0].type == STANDALONE_COMMENT
1017
1018     @property
1019     def is_decorator(self) -> bool:
1020         """Is this line a decorator?"""
1021         return bool(self) and self.leaves[0].type == token.AT
1022
1023     @property
1024     def is_import(self) -> bool:
1025         """Is this an import line?"""
1026         return bool(self) and is_import(self.leaves[0])
1027
1028     @property
1029     def is_class(self) -> bool:
1030         """Is this line a class definition?"""
1031         return (
1032             bool(self)
1033             and self.leaves[0].type == token.NAME
1034             and self.leaves[0].value == "class"
1035         )
1036
1037     @property
1038     def is_stub_class(self) -> bool:
1039         """Is this line a class definition with a body consisting only of "..."?"""
1040         return self.is_class and self.leaves[-3:] == [
1041             Leaf(token.DOT, ".") for _ in range(3)
1042         ]
1043
1044     @property
1045     def is_def(self) -> bool:
1046         """Is this a function definition? (Also returns True for async defs.)"""
1047         try:
1048             first_leaf = self.leaves[0]
1049         except IndexError:
1050             return False
1051
1052         try:
1053             second_leaf: Optional[Leaf] = self.leaves[1]
1054         except IndexError:
1055             second_leaf = None
1056         return (first_leaf.type == token.NAME and first_leaf.value == "def") or (
1057             first_leaf.type == token.ASYNC
1058             and second_leaf is not None
1059             and second_leaf.type == token.NAME
1060             and second_leaf.value == "def"
1061         )
1062
1063     @property
1064     def is_class_paren_empty(self) -> bool:
1065         """Is this a class with no base classes but using parentheses?
1066
1067         Those are unnecessary and should be removed.
1068         """
1069         return (
1070             bool(self)
1071             and len(self.leaves) == 4
1072             and self.is_class
1073             and self.leaves[2].type == token.LPAR
1074             and self.leaves[2].value == "("
1075             and self.leaves[3].type == token.RPAR
1076             and self.leaves[3].value == ")"
1077         )
1078
1079     @property
1080     def is_triple_quoted_string(self) -> bool:
1081         """Is the line a triple quoted string?"""
1082         return (
1083             bool(self)
1084             and self.leaves[0].type == token.STRING
1085             and self.leaves[0].value.startswith(('"""', "'''"))
1086         )
1087
1088     def contains_standalone_comments(self, depth_limit: int = sys.maxsize) -> bool:
1089         """If so, needs to be split before emitting."""
1090         for leaf in self.leaves:
1091             if leaf.type == STANDALONE_COMMENT:
1092                 if leaf.bracket_depth <= depth_limit:
1093                     return True
1094
1095         return False
1096
1097     def maybe_remove_trailing_comma(self, closing: Leaf) -> bool:
1098         """Remove trailing comma if there is one and it's safe."""
1099         if not (
1100             self.leaves
1101             and self.leaves[-1].type == token.COMMA
1102             and closing.type in CLOSING_BRACKETS
1103         ):
1104             return False
1105
1106         if closing.type == token.RBRACE:
1107             self.remove_trailing_comma()
1108             return True
1109
1110         if closing.type == token.RSQB:
1111             comma = self.leaves[-1]
1112             if comma.parent and comma.parent.type == syms.listmaker:
1113                 self.remove_trailing_comma()
1114                 return True
1115
1116         # For parens let's check if it's safe to remove the comma.
1117         # Imports are always safe.
1118         if self.is_import:
1119             self.remove_trailing_comma()
1120             return True
1121
1122         # Otheriwsse, if the trailing one is the only one, we might mistakenly
1123         # change a tuple into a different type by removing the comma.
1124         depth = closing.bracket_depth + 1
1125         commas = 0
1126         opening = closing.opening_bracket
1127         for _opening_index, leaf in enumerate(self.leaves):
1128             if leaf is opening:
1129                 break
1130
1131         else:
1132             return False
1133
1134         for leaf in self.leaves[_opening_index + 1 :]:
1135             if leaf is closing:
1136                 break
1137
1138             bracket_depth = leaf.bracket_depth
1139             if bracket_depth == depth and leaf.type == token.COMMA:
1140                 commas += 1
1141                 if leaf.parent and leaf.parent.type == syms.arglist:
1142                     commas += 1
1143                     break
1144
1145         if commas > 1:
1146             self.remove_trailing_comma()
1147             return True
1148
1149         return False
1150
1151     def append_comment(self, comment: Leaf) -> bool:
1152         """Add an inline or standalone comment to the line."""
1153         if (
1154             comment.type == STANDALONE_COMMENT
1155             and self.bracket_tracker.any_open_brackets()
1156         ):
1157             comment.prefix = ""
1158             return False
1159
1160         if comment.type != token.COMMENT:
1161             return False
1162
1163         after = len(self.leaves) - 1
1164         if after == -1:
1165             comment.type = STANDALONE_COMMENT
1166             comment.prefix = ""
1167             return False
1168
1169         else:
1170             self.comments.append((after, comment))
1171             return True
1172
1173     def comments_after(self, leaf: Leaf, _index: int = -1) -> Iterator[Leaf]:
1174         """Generate comments that should appear directly after `leaf`.
1175
1176         Provide a non-negative leaf `_index` to speed up the function.
1177         """
1178         if _index == -1:
1179             for _index, _leaf in enumerate(self.leaves):
1180                 if leaf is _leaf:
1181                     break
1182
1183             else:
1184                 return
1185
1186         for index, comment_after in self.comments:
1187             if _index == index:
1188                 yield comment_after
1189
1190     def remove_trailing_comma(self) -> None:
1191         """Remove the trailing comma and moves the comments attached to it."""
1192         comma_index = len(self.leaves) - 1
1193         for i in range(len(self.comments)):
1194             comment_index, comment = self.comments[i]
1195             if comment_index == comma_index:
1196                 self.comments[i] = (comma_index - 1, comment)
1197         self.leaves.pop()
1198
1199     def is_complex_subscript(self, leaf: Leaf) -> bool:
1200         """Return True iff `leaf` is part of a slice with non-trivial exprs."""
1201         open_lsqb = (
1202             leaf if leaf.type == token.LSQB else self.bracket_tracker.get_open_lsqb()
1203         )
1204         if open_lsqb is None:
1205             return False
1206
1207         subscript_start = open_lsqb.next_sibling
1208         if (
1209             isinstance(subscript_start, Node)
1210             and subscript_start.type == syms.subscriptlist
1211         ):
1212             subscript_start = child_towards(subscript_start, leaf)
1213         return subscript_start is not None and any(
1214             n.type in TEST_DESCENDANTS for n in subscript_start.pre_order()
1215         )
1216
1217     def __str__(self) -> str:
1218         """Render the line."""
1219         if not self:
1220             return "\n"
1221
1222         indent = "    " * self.depth
1223         leaves = iter(self.leaves)
1224         first = next(leaves)
1225         res = f"{first.prefix}{indent}{first.value}"
1226         for leaf in leaves:
1227             res += str(leaf)
1228         for _, comment in self.comments:
1229             res += str(comment)
1230         return res + "\n"
1231
1232     def __bool__(self) -> bool:
1233         """Return True if the line has leaves or comments."""
1234         return bool(self.leaves or self.comments)
1235
1236
1237 class UnformattedLines(Line):
1238     """Just like :class:`Line` but stores lines which aren't reformatted."""
1239
1240     def append(self, leaf: Leaf, preformatted: bool = True) -> None:
1241         """Just add a new `leaf` to the end of the lines.
1242
1243         The `preformatted` argument is ignored.
1244
1245         Keeps track of indentation `depth`, which is useful when the user
1246         says `# fmt: on`. Otherwise, doesn't do anything with the `leaf`.
1247         """
1248         try:
1249             list(generate_comments(leaf))
1250         except FormatOn as f_on:
1251             self.leaves.append(f_on.leaf_from_consumed(leaf))
1252             raise
1253
1254         self.leaves.append(leaf)
1255         if leaf.type == token.INDENT:
1256             self.depth += 1
1257         elif leaf.type == token.DEDENT:
1258             self.depth -= 1
1259
1260     def __str__(self) -> str:
1261         """Render unformatted lines from leaves which were added with `append()`.
1262
1263         `depth` is not used for indentation in this case.
1264         """
1265         if not self:
1266             return "\n"
1267
1268         res = ""
1269         for leaf in self.leaves:
1270             res += str(leaf)
1271         return res
1272
1273     def append_comment(self, comment: Leaf) -> bool:
1274         """Not implemented in this class. Raises `NotImplementedError`."""
1275         raise NotImplementedError("Unformatted lines don't store comments separately.")
1276
1277     def maybe_remove_trailing_comma(self, closing: Leaf) -> bool:
1278         """Does nothing and returns False."""
1279         return False
1280
1281     def maybe_increment_for_loop_variable(self, leaf: Leaf) -> bool:
1282         """Does nothing and returns False."""
1283         return False
1284
1285
1286 @dataclass
1287 class EmptyLineTracker:
1288     """Provides a stateful method that returns the number of potential extra
1289     empty lines needed before and after the currently processed line.
1290
1291     Note: this tracker works on lines that haven't been split yet.  It assumes
1292     the prefix of the first leaf consists of optional newlines.  Those newlines
1293     are consumed by `maybe_empty_lines()` and included in the computation.
1294     """
1295
1296     is_pyi: bool = False
1297     previous_line: Optional[Line] = None
1298     previous_after: int = 0
1299     previous_defs: List[int] = Factory(list)
1300
1301     def maybe_empty_lines(self, current_line: Line) -> Tuple[int, int]:
1302         """Return the number of extra empty lines before and after the `current_line`.
1303
1304         This is for separating `def`, `async def` and `class` with extra empty
1305         lines (two on module-level).
1306         """
1307         if isinstance(current_line, UnformattedLines):
1308             return 0, 0
1309
1310         before, after = self._maybe_empty_lines(current_line)
1311         before -= self.previous_after
1312         self.previous_after = after
1313         self.previous_line = current_line
1314         return before, after
1315
1316     def _maybe_empty_lines(self, current_line: Line) -> Tuple[int, int]:
1317         max_allowed = 1
1318         if current_line.depth == 0:
1319             max_allowed = 1 if self.is_pyi else 2
1320         if current_line.leaves:
1321             # Consume the first leaf's extra newlines.
1322             first_leaf = current_line.leaves[0]
1323             before = first_leaf.prefix.count("\n")
1324             before = min(before, max_allowed)
1325             first_leaf.prefix = ""
1326         else:
1327             before = 0
1328         depth = current_line.depth
1329         while self.previous_defs and self.previous_defs[-1] >= depth:
1330             self.previous_defs.pop()
1331             if self.is_pyi:
1332                 before = 0 if depth else 1
1333             else:
1334                 before = 1 if depth else 2
1335         is_decorator = current_line.is_decorator
1336         if is_decorator or current_line.is_def or current_line.is_class:
1337             if not is_decorator:
1338                 self.previous_defs.append(depth)
1339             if self.previous_line is None:
1340                 # Don't insert empty lines before the first line in the file.
1341                 return 0, 0
1342
1343             if self.previous_line.is_decorator:
1344                 return 0, 0
1345
1346             if self.previous_line.depth < current_line.depth and (
1347                 self.previous_line.is_class or self.previous_line.is_def
1348             ):
1349                 return 0, 0
1350
1351             if (
1352                 self.previous_line.is_comment
1353                 and self.previous_line.depth == current_line.depth
1354                 and before == 0
1355             ):
1356                 return 0, 0
1357
1358             if self.is_pyi:
1359                 if self.previous_line.depth > current_line.depth:
1360                     newlines = 1
1361                 elif current_line.is_class or self.previous_line.is_class:
1362                     if current_line.is_stub_class and self.previous_line.is_stub_class:
1363                         newlines = 0
1364                     else:
1365                         newlines = 1
1366                 else:
1367                     newlines = 0
1368             else:
1369                 newlines = 2
1370             if current_line.depth and newlines:
1371                 newlines -= 1
1372             return newlines, 0
1373
1374         if (
1375             self.previous_line
1376             and self.previous_line.is_import
1377             and not current_line.is_import
1378             and depth == self.previous_line.depth
1379         ):
1380             return (before or 1), 0
1381
1382         if (
1383             self.previous_line
1384             and self.previous_line.is_class
1385             and current_line.is_triple_quoted_string
1386         ):
1387             return before, 1
1388
1389         return before, 0
1390
1391
1392 @dataclass
1393 class LineGenerator(Visitor[Line]):
1394     """Generates reformatted Line objects.  Empty lines are not emitted.
1395
1396     Note: destroys the tree it's visiting by mutating prefixes of its leaves
1397     in ways that will no longer stringify to valid Python code on the tree.
1398     """
1399
1400     is_pyi: bool = False
1401     normalize_strings: bool = True
1402     current_line: Line = Factory(Line)
1403     remove_u_prefix: bool = False
1404
1405     def line(self, indent: int = 0, type: Type[Line] = Line) -> Iterator[Line]:
1406         """Generate a line.
1407
1408         If the line is empty, only emit if it makes sense.
1409         If the line is too long, split it first and then generate.
1410
1411         If any lines were generated, set up a new current_line.
1412         """
1413         if not self.current_line:
1414             if self.current_line.__class__ == type:
1415                 self.current_line.depth += indent
1416             else:
1417                 self.current_line = type(depth=self.current_line.depth + indent)
1418             return  # Line is empty, don't emit. Creating a new one unnecessary.
1419
1420         complete_line = self.current_line
1421         self.current_line = type(depth=complete_line.depth + indent)
1422         yield complete_line
1423
1424     def visit(self, node: LN) -> Iterator[Line]:
1425         """Main method to visit `node` and its children.
1426
1427         Yields :class:`Line` objects.
1428         """
1429         if isinstance(self.current_line, UnformattedLines):
1430             # File contained `# fmt: off`
1431             yield from self.visit_unformatted(node)
1432
1433         else:
1434             yield from super().visit(node)
1435
1436     def visit_default(self, node: LN) -> Iterator[Line]:
1437         """Default `visit_*()` implementation. Recurses to children of `node`."""
1438         if isinstance(node, Leaf):
1439             any_open_brackets = self.current_line.bracket_tracker.any_open_brackets()
1440             try:
1441                 for comment in generate_comments(node):
1442                     if any_open_brackets:
1443                         # any comment within brackets is subject to splitting
1444                         self.current_line.append(comment)
1445                     elif comment.type == token.COMMENT:
1446                         # regular trailing comment
1447                         self.current_line.append(comment)
1448                         yield from self.line()
1449
1450                     else:
1451                         # regular standalone comment
1452                         yield from self.line()
1453
1454                         self.current_line.append(comment)
1455                         yield from self.line()
1456
1457             except FormatOff as f_off:
1458                 f_off.trim_prefix(node)
1459                 yield from self.line(type=UnformattedLines)
1460                 yield from self.visit(node)
1461
1462             except FormatOn as f_on:
1463                 # This only happens here if somebody says "fmt: on" multiple
1464                 # times in a row.
1465                 f_on.trim_prefix(node)
1466                 yield from self.visit_default(node)
1467
1468             else:
1469                 normalize_prefix(node, inside_brackets=any_open_brackets)
1470                 if self.normalize_strings and node.type == token.STRING:
1471                     normalize_string_prefix(node, remove_u_prefix=self.remove_u_prefix)
1472                     normalize_string_quotes(node)
1473                 if node.type not in WHITESPACE:
1474                     self.current_line.append(node)
1475         yield from super().visit_default(node)
1476
1477     def visit_INDENT(self, node: Node) -> Iterator[Line]:
1478         """Increase indentation level, maybe yield a line."""
1479         # In blib2to3 INDENT never holds comments.
1480         yield from self.line(+1)
1481         yield from self.visit_default(node)
1482
1483     def visit_DEDENT(self, node: Node) -> Iterator[Line]:
1484         """Decrease indentation level, maybe yield a line."""
1485         # The current line might still wait for trailing comments.  At DEDENT time
1486         # there won't be any (they would be prefixes on the preceding NEWLINE).
1487         # Emit the line then.
1488         yield from self.line()
1489
1490         # While DEDENT has no value, its prefix may contain standalone comments
1491         # that belong to the current indentation level.  Get 'em.
1492         yield from self.visit_default(node)
1493
1494         # Finally, emit the dedent.
1495         yield from self.line(-1)
1496
1497     def visit_stmt(
1498         self, node: Node, keywords: Set[str], parens: Set[str]
1499     ) -> Iterator[Line]:
1500         """Visit a statement.
1501
1502         This implementation is shared for `if`, `while`, `for`, `try`, `except`,
1503         `def`, `with`, `class`, `assert` and assignments.
1504
1505         The relevant Python language `keywords` for a given statement will be
1506         NAME leaves within it. This methods puts those on a separate line.
1507
1508         `parens` holds a set of string leaf values immediately after which
1509         invisible parens should be put.
1510         """
1511         normalize_invisible_parens(node, parens_after=parens)
1512         for child in node.children:
1513             if child.type == token.NAME and child.value in keywords:  # type: ignore
1514                 yield from self.line()
1515
1516             yield from self.visit(child)
1517
1518     def visit_suite(self, node: Node) -> Iterator[Line]:
1519         """Visit a suite."""
1520         if self.is_pyi and is_stub_suite(node):
1521             yield from self.visit(node.children[2])
1522         else:
1523             yield from self.visit_default(node)
1524
1525     def visit_simple_stmt(self, node: Node) -> Iterator[Line]:
1526         """Visit a statement without nested statements."""
1527         is_suite_like = node.parent and node.parent.type in STATEMENT
1528         if is_suite_like:
1529             if self.is_pyi and is_stub_body(node):
1530                 yield from self.visit_default(node)
1531             else:
1532                 yield from self.line(+1)
1533                 yield from self.visit_default(node)
1534                 yield from self.line(-1)
1535
1536         else:
1537             if not self.is_pyi or not node.parent or not is_stub_suite(node.parent):
1538                 yield from self.line()
1539             yield from self.visit_default(node)
1540
1541     def visit_async_stmt(self, node: Node) -> Iterator[Line]:
1542         """Visit `async def`, `async for`, `async with`."""
1543         yield from self.line()
1544
1545         children = iter(node.children)
1546         for child in children:
1547             yield from self.visit(child)
1548
1549             if child.type == token.ASYNC:
1550                 break
1551
1552         internal_stmt = next(children)
1553         for child in internal_stmt.children:
1554             yield from self.visit(child)
1555
1556     def visit_decorators(self, node: Node) -> Iterator[Line]:
1557         """Visit decorators."""
1558         for child in node.children:
1559             yield from self.line()
1560             yield from self.visit(child)
1561
1562     def visit_SEMI(self, leaf: Leaf) -> Iterator[Line]:
1563         """Remove a semicolon and put the other statement on a separate line."""
1564         yield from self.line()
1565
1566     def visit_ENDMARKER(self, leaf: Leaf) -> Iterator[Line]:
1567         """End of file. Process outstanding comments and end with a newline."""
1568         yield from self.visit_default(leaf)
1569         yield from self.line()
1570
1571     def visit_unformatted(self, node: LN) -> Iterator[Line]:
1572         """Used when file contained a `# fmt: off`."""
1573         if isinstance(node, Node):
1574             for child in node.children:
1575                 yield from self.visit(child)
1576
1577         else:
1578             try:
1579                 self.current_line.append(node)
1580             except FormatOn as f_on:
1581                 f_on.trim_prefix(node)
1582                 yield from self.line()
1583                 yield from self.visit(node)
1584
1585             if node.type == token.ENDMARKER:
1586                 # somebody decided not to put a final `# fmt: on`
1587                 yield from self.line()
1588
1589     def __attrs_post_init__(self) -> None:
1590         """You are in a twisty little maze of passages."""
1591         v = self.visit_stmt
1592         Ø: Set[str] = set()
1593         self.visit_assert_stmt = partial(v, keywords={"assert"}, parens={"assert", ","})
1594         self.visit_if_stmt = partial(
1595             v, keywords={"if", "else", "elif"}, parens={"if", "elif"}
1596         )
1597         self.visit_while_stmt = partial(v, keywords={"while", "else"}, parens={"while"})
1598         self.visit_for_stmt = partial(v, keywords={"for", "else"}, parens={"for", "in"})
1599         self.visit_try_stmt = partial(
1600             v, keywords={"try", "except", "else", "finally"}, parens=Ø
1601         )
1602         self.visit_except_clause = partial(v, keywords={"except"}, parens=Ø)
1603         self.visit_with_stmt = partial(v, keywords={"with"}, parens=Ø)
1604         self.visit_funcdef = partial(v, keywords={"def"}, parens=Ø)
1605         self.visit_classdef = partial(v, keywords={"class"}, parens=Ø)
1606         self.visit_expr_stmt = partial(v, keywords=Ø, parens=ASSIGNMENTS)
1607         self.visit_return_stmt = partial(v, keywords={"return"}, parens={"return"})
1608         self.visit_import_from = partial(v, keywords=Ø, parens={"import"})
1609         self.visit_async_funcdef = self.visit_async_stmt
1610         self.visit_decorated = self.visit_decorators
1611
1612
1613 IMPLICIT_TUPLE = {syms.testlist, syms.testlist_star_expr, syms.exprlist}
1614 BRACKET = {token.LPAR: token.RPAR, token.LSQB: token.RSQB, token.LBRACE: token.RBRACE}
1615 OPENING_BRACKETS = set(BRACKET.keys())
1616 CLOSING_BRACKETS = set(BRACKET.values())
1617 BRACKETS = OPENING_BRACKETS | CLOSING_BRACKETS
1618 ALWAYS_NO_SPACE = CLOSING_BRACKETS | {token.COMMA, STANDALONE_COMMENT}
1619
1620
1621 def whitespace(leaf: Leaf, *, complex_subscript: bool) -> str:  # noqa C901
1622     """Return whitespace prefix if needed for the given `leaf`.
1623
1624     `complex_subscript` signals whether the given leaf is part of a subscription
1625     which has non-trivial arguments, like arithmetic expressions or function calls.
1626     """
1627     NO = ""
1628     SPACE = " "
1629     DOUBLESPACE = "  "
1630     t = leaf.type
1631     p = leaf.parent
1632     v = leaf.value
1633     if t in ALWAYS_NO_SPACE:
1634         return NO
1635
1636     if t == token.COMMENT:
1637         return DOUBLESPACE
1638
1639     assert p is not None, f"INTERNAL ERROR: hand-made leaf without parent: {leaf!r}"
1640     if t == token.COLON and p.type not in {
1641         syms.subscript,
1642         syms.subscriptlist,
1643         syms.sliceop,
1644     }:
1645         return NO
1646
1647     prev = leaf.prev_sibling
1648     if not prev:
1649         prevp = preceding_leaf(p)
1650         if not prevp or prevp.type in OPENING_BRACKETS:
1651             return NO
1652
1653         if t == token.COLON:
1654             if prevp.type == token.COLON:
1655                 return NO
1656
1657             elif prevp.type != token.COMMA and not complex_subscript:
1658                 return NO
1659
1660             return SPACE
1661
1662         if prevp.type == token.EQUAL:
1663             if prevp.parent:
1664                 if prevp.parent.type in {
1665                     syms.arglist,
1666                     syms.argument,
1667                     syms.parameters,
1668                     syms.varargslist,
1669                 }:
1670                     return NO
1671
1672                 elif prevp.parent.type == syms.typedargslist:
1673                     # A bit hacky: if the equal sign has whitespace, it means we
1674                     # previously found it's a typed argument.  So, we're using
1675                     # that, too.
1676                     return prevp.prefix
1677
1678         elif prevp.type in STARS:
1679             if is_vararg(prevp, within=VARARGS_PARENTS | UNPACKING_PARENTS):
1680                 return NO
1681
1682         elif prevp.type == token.COLON:
1683             if prevp.parent and prevp.parent.type in {syms.subscript, syms.sliceop}:
1684                 return SPACE if complex_subscript else NO
1685
1686         elif (
1687             prevp.parent
1688             and prevp.parent.type == syms.factor
1689             and prevp.type in MATH_OPERATORS
1690         ):
1691             return NO
1692
1693         elif (
1694             prevp.type == token.RIGHTSHIFT
1695             and prevp.parent
1696             and prevp.parent.type == syms.shift_expr
1697             and prevp.prev_sibling
1698             and prevp.prev_sibling.type == token.NAME
1699             and prevp.prev_sibling.value == "print"  # type: ignore
1700         ):
1701             # Python 2 print chevron
1702             return NO
1703
1704     elif prev.type in OPENING_BRACKETS:
1705         return NO
1706
1707     if p.type in {syms.parameters, syms.arglist}:
1708         # untyped function signatures or calls
1709         if not prev or prev.type != token.COMMA:
1710             return NO
1711
1712     elif p.type == syms.varargslist:
1713         # lambdas
1714         if prev and prev.type != token.COMMA:
1715             return NO
1716
1717     elif p.type == syms.typedargslist:
1718         # typed function signatures
1719         if not prev:
1720             return NO
1721
1722         if t == token.EQUAL:
1723             if prev.type != syms.tname:
1724                 return NO
1725
1726         elif prev.type == token.EQUAL:
1727             # A bit hacky: if the equal sign has whitespace, it means we
1728             # previously found it's a typed argument.  So, we're using that, too.
1729             return prev.prefix
1730
1731         elif prev.type != token.COMMA:
1732             return NO
1733
1734     elif p.type == syms.tname:
1735         # type names
1736         if not prev:
1737             prevp = preceding_leaf(p)
1738             if not prevp or prevp.type != token.COMMA:
1739                 return NO
1740
1741     elif p.type == syms.trailer:
1742         # attributes and calls
1743         if t == token.LPAR or t == token.RPAR:
1744             return NO
1745
1746         if not prev:
1747             if t == token.DOT:
1748                 prevp = preceding_leaf(p)
1749                 if not prevp or prevp.type != token.NUMBER:
1750                     return NO
1751
1752             elif t == token.LSQB:
1753                 return NO
1754
1755         elif prev.type != token.COMMA:
1756             return NO
1757
1758     elif p.type == syms.argument:
1759         # single argument
1760         if t == token.EQUAL:
1761             return NO
1762
1763         if not prev:
1764             prevp = preceding_leaf(p)
1765             if not prevp or prevp.type == token.LPAR:
1766                 return NO
1767
1768         elif prev.type in {token.EQUAL} | STARS:
1769             return NO
1770
1771     elif p.type == syms.decorator:
1772         # decorators
1773         return NO
1774
1775     elif p.type == syms.dotted_name:
1776         if prev:
1777             return NO
1778
1779         prevp = preceding_leaf(p)
1780         if not prevp or prevp.type == token.AT or prevp.type == token.DOT:
1781             return NO
1782
1783     elif p.type == syms.classdef:
1784         if t == token.LPAR:
1785             return NO
1786
1787         if prev and prev.type == token.LPAR:
1788             return NO
1789
1790     elif p.type in {syms.subscript, syms.sliceop}:
1791         # indexing
1792         if not prev:
1793             assert p.parent is not None, "subscripts are always parented"
1794             if p.parent.type == syms.subscriptlist:
1795                 return SPACE
1796
1797             return NO
1798
1799         elif not complex_subscript:
1800             return NO
1801
1802     elif p.type == syms.atom:
1803         if prev and t == token.DOT:
1804             # dots, but not the first one.
1805             return NO
1806
1807     elif p.type == syms.dictsetmaker:
1808         # dict unpacking
1809         if prev and prev.type == token.DOUBLESTAR:
1810             return NO
1811
1812     elif p.type in {syms.factor, syms.star_expr}:
1813         # unary ops
1814         if not prev:
1815             prevp = preceding_leaf(p)
1816             if not prevp or prevp.type in OPENING_BRACKETS:
1817                 return NO
1818
1819             prevp_parent = prevp.parent
1820             assert prevp_parent is not None
1821             if prevp.type == token.COLON and prevp_parent.type in {
1822                 syms.subscript,
1823                 syms.sliceop,
1824             }:
1825                 return NO
1826
1827             elif prevp.type == token.EQUAL and prevp_parent.type == syms.argument:
1828                 return NO
1829
1830         elif t == token.NAME or t == token.NUMBER:
1831             return NO
1832
1833     elif p.type == syms.import_from:
1834         if t == token.DOT:
1835             if prev and prev.type == token.DOT:
1836                 return NO
1837
1838         elif t == token.NAME:
1839             if v == "import":
1840                 return SPACE
1841
1842             if prev and prev.type == token.DOT:
1843                 return NO
1844
1845     elif p.type == syms.sliceop:
1846         return NO
1847
1848     return SPACE
1849
1850
1851 def preceding_leaf(node: Optional[LN]) -> Optional[Leaf]:
1852     """Return the first leaf that precedes `node`, if any."""
1853     while node:
1854         res = node.prev_sibling
1855         if res:
1856             if isinstance(res, Leaf):
1857                 return res
1858
1859             try:
1860                 return list(res.leaves())[-1]
1861
1862             except IndexError:
1863                 return None
1864
1865         node = node.parent
1866     return None
1867
1868
1869 def child_towards(ancestor: Node, descendant: LN) -> Optional[LN]:
1870     """Return the child of `ancestor` that contains `descendant`."""
1871     node: Optional[LN] = descendant
1872     while node and node.parent != ancestor:
1873         node = node.parent
1874     return node
1875
1876
1877 def is_split_after_delimiter(leaf: Leaf, previous: Leaf = None) -> int:
1878     """Return the priority of the `leaf` delimiter, given a line break after it.
1879
1880     The delimiter priorities returned here are from those delimiters that would
1881     cause a line break after themselves.
1882
1883     Higher numbers are higher priority.
1884     """
1885     if leaf.type == token.COMMA:
1886         return COMMA_PRIORITY
1887
1888     return 0
1889
1890
1891 def is_split_before_delimiter(leaf: Leaf, previous: Leaf = None) -> int:
1892     """Return the priority of the `leaf` delimiter, given a line before after it.
1893
1894     The delimiter priorities returned here are from those delimiters that would
1895     cause a line break before themselves.
1896
1897     Higher numbers are higher priority.
1898     """
1899     if is_vararg(leaf, within=VARARGS_PARENTS | UNPACKING_PARENTS):
1900         # * and ** might also be MATH_OPERATORS but in this case they are not.
1901         # Don't treat them as a delimiter.
1902         return 0
1903
1904     if (
1905         leaf.type == token.DOT
1906         and leaf.parent
1907         and leaf.parent.type not in {syms.import_from, syms.dotted_name}
1908         and (previous is None or previous.type in CLOSING_BRACKETS)
1909     ):
1910         return DOT_PRIORITY
1911
1912     if (
1913         leaf.type in MATH_OPERATORS
1914         and leaf.parent
1915         and leaf.parent.type not in {syms.factor, syms.star_expr}
1916     ):
1917         return MATH_PRIORITIES[leaf.type]
1918
1919     if leaf.type in COMPARATORS:
1920         return COMPARATOR_PRIORITY
1921
1922     if (
1923         leaf.type == token.STRING
1924         and previous is not None
1925         and previous.type == token.STRING
1926     ):
1927         return STRING_PRIORITY
1928
1929     if leaf.type != token.NAME:
1930         return 0
1931
1932     if (
1933         leaf.value == "for"
1934         and leaf.parent
1935         and leaf.parent.type in {syms.comp_for, syms.old_comp_for}
1936     ):
1937         return COMPREHENSION_PRIORITY
1938
1939     if (
1940         leaf.value == "if"
1941         and leaf.parent
1942         and leaf.parent.type in {syms.comp_if, syms.old_comp_if}
1943     ):
1944         return COMPREHENSION_PRIORITY
1945
1946     if leaf.value in {"if", "else"} and leaf.parent and leaf.parent.type == syms.test:
1947         return TERNARY_PRIORITY
1948
1949     if leaf.value == "is":
1950         return COMPARATOR_PRIORITY
1951
1952     if (
1953         leaf.value == "in"
1954         and leaf.parent
1955         and leaf.parent.type in {syms.comp_op, syms.comparison}
1956         and not (
1957             previous is not None
1958             and previous.type == token.NAME
1959             and previous.value == "not"
1960         )
1961     ):
1962         return COMPARATOR_PRIORITY
1963
1964     if (
1965         leaf.value == "not"
1966         and leaf.parent
1967         and leaf.parent.type == syms.comp_op
1968         and not (
1969             previous is not None
1970             and previous.type == token.NAME
1971             and previous.value == "is"
1972         )
1973     ):
1974         return COMPARATOR_PRIORITY
1975
1976     if leaf.value in LOGIC_OPERATORS and leaf.parent:
1977         return LOGIC_PRIORITY
1978
1979     return 0
1980
1981
1982 def generate_comments(leaf: LN) -> Iterator[Leaf]:
1983     """Clean the prefix of the `leaf` and generate comments from it, if any.
1984
1985     Comments in lib2to3 are shoved into the whitespace prefix.  This happens
1986     in `pgen2/driver.py:Driver.parse_tokens()`.  This was a brilliant implementation
1987     move because it does away with modifying the grammar to include all the
1988     possible places in which comments can be placed.
1989
1990     The sad consequence for us though is that comments don't "belong" anywhere.
1991     This is why this function generates simple parentless Leaf objects for
1992     comments.  We simply don't know what the correct parent should be.
1993
1994     No matter though, we can live without this.  We really only need to
1995     differentiate between inline and standalone comments.  The latter don't
1996     share the line with any code.
1997
1998     Inline comments are emitted as regular token.COMMENT leaves.  Standalone
1999     are emitted with a fake STANDALONE_COMMENT token identifier.
2000     """
2001     p = leaf.prefix
2002     if not p:
2003         return
2004
2005     if "#" not in p:
2006         return
2007
2008     consumed = 0
2009     nlines = 0
2010     for index, line in enumerate(p.split("\n")):
2011         consumed += len(line) + 1  # adding the length of the split '\n'
2012         line = line.lstrip()
2013         if not line:
2014             nlines += 1
2015         if not line.startswith("#"):
2016             continue
2017
2018         if index == 0 and leaf.type != token.ENDMARKER:
2019             comment_type = token.COMMENT  # simple trailing comment
2020         else:
2021             comment_type = STANDALONE_COMMENT
2022         comment = make_comment(line)
2023         yield Leaf(comment_type, comment, prefix="\n" * nlines)
2024
2025         if comment in {"# fmt: on", "# yapf: enable"}:
2026             raise FormatOn(consumed)
2027
2028         if comment in {"# fmt: off", "# yapf: disable"}:
2029             if comment_type == STANDALONE_COMMENT:
2030                 raise FormatOff(consumed)
2031
2032             prev = preceding_leaf(leaf)
2033             if not prev or prev.type in WHITESPACE:  # standalone comment in disguise
2034                 raise FormatOff(consumed)
2035
2036         nlines = 0
2037
2038
2039 def make_comment(content: str) -> str:
2040     """Return a consistently formatted comment from the given `content` string.
2041
2042     All comments (except for "##", "#!", "#:") should have a single space between
2043     the hash sign and the content.
2044
2045     If `content` didn't start with a hash sign, one is provided.
2046     """
2047     content = content.rstrip()
2048     if not content:
2049         return "#"
2050
2051     if content[0] == "#":
2052         content = content[1:]
2053     if content and content[0] not in " !:#":
2054         content = " " + content
2055     return "#" + content
2056
2057
2058 def split_line(
2059     line: Line, line_length: int, inner: bool = False, py36: bool = False
2060 ) -> Iterator[Line]:
2061     """Split a `line` into potentially many lines.
2062
2063     They should fit in the allotted `line_length` but might not be able to.
2064     `inner` signifies that there were a pair of brackets somewhere around the
2065     current `line`, possibly transitively. This means we can fallback to splitting
2066     by delimiters if the LHS/RHS don't yield any results.
2067
2068     If `py36` is True, splitting may generate syntax that is only compatible
2069     with Python 3.6 and later.
2070     """
2071     if isinstance(line, UnformattedLines) or line.is_comment:
2072         yield line
2073         return
2074
2075     line_str = str(line).strip("\n")
2076     if not line.should_explode and is_line_short_enough(
2077         line, line_length=line_length, line_str=line_str
2078     ):
2079         yield line
2080         return
2081
2082     split_funcs: List[SplitFunc]
2083     if line.is_def:
2084         split_funcs = [left_hand_split]
2085     else:
2086
2087         def rhs(line: Line, py36: bool = False) -> Iterator[Line]:
2088             for omit in generate_trailers_to_omit(line, line_length):
2089                 lines = list(right_hand_split(line, line_length, py36, omit=omit))
2090                 if is_line_short_enough(lines[0], line_length=line_length):
2091                     yield from lines
2092                     return
2093
2094             # All splits failed, best effort split with no omits.
2095             # This mostly happens to multiline strings that are by definition
2096             # reported as not fitting a single line.
2097             yield from right_hand_split(line, py36)
2098
2099         if line.inside_brackets:
2100             split_funcs = [delimiter_split, standalone_comment_split, rhs]
2101         else:
2102             split_funcs = [rhs]
2103     for split_func in split_funcs:
2104         # We are accumulating lines in `result` because we might want to abort
2105         # mission and return the original line in the end, or attempt a different
2106         # split altogether.
2107         result: List[Line] = []
2108         try:
2109             for l in split_func(line, py36):
2110                 if str(l).strip("\n") == line_str:
2111                     raise CannotSplit("Split function returned an unchanged result")
2112
2113                 result.extend(
2114                     split_line(l, line_length=line_length, inner=True, py36=py36)
2115                 )
2116         except CannotSplit as cs:
2117             continue
2118
2119         else:
2120             yield from result
2121             break
2122
2123     else:
2124         yield line
2125
2126
2127 def left_hand_split(line: Line, py36: bool = False) -> Iterator[Line]:
2128     """Split line into many lines, starting with the first matching bracket pair.
2129
2130     Note: this usually looks weird, only use this for function definitions.
2131     Prefer RHS otherwise.  This is why this function is not symmetrical with
2132     :func:`right_hand_split` which also handles optional parentheses.
2133     """
2134     head = Line(depth=line.depth)
2135     body = Line(depth=line.depth + 1, inside_brackets=True)
2136     tail = Line(depth=line.depth)
2137     tail_leaves: List[Leaf] = []
2138     body_leaves: List[Leaf] = []
2139     head_leaves: List[Leaf] = []
2140     current_leaves = head_leaves
2141     matching_bracket = None
2142     for leaf in line.leaves:
2143         if (
2144             current_leaves is body_leaves
2145             and leaf.type in CLOSING_BRACKETS
2146             and leaf.opening_bracket is matching_bracket
2147         ):
2148             current_leaves = tail_leaves if body_leaves else head_leaves
2149         current_leaves.append(leaf)
2150         if current_leaves is head_leaves:
2151             if leaf.type in OPENING_BRACKETS:
2152                 matching_bracket = leaf
2153                 current_leaves = body_leaves
2154     # Since body is a new indent level, remove spurious leading whitespace.
2155     if body_leaves:
2156         normalize_prefix(body_leaves[0], inside_brackets=True)
2157     # Build the new lines.
2158     for result, leaves in (head, head_leaves), (body, body_leaves), (tail, tail_leaves):
2159         for leaf in leaves:
2160             result.append(leaf, preformatted=True)
2161             for comment_after in line.comments_after(leaf):
2162                 result.append(comment_after, preformatted=True)
2163     bracket_split_succeeded_or_raise(head, body, tail)
2164     for result in (head, body, tail):
2165         if result:
2166             yield result
2167
2168
2169 def right_hand_split(
2170     line: Line, line_length: int, py36: bool = False, omit: Collection[LeafID] = ()
2171 ) -> Iterator[Line]:
2172     """Split line into many lines, starting with the last matching bracket pair.
2173
2174     If the split was by optional parentheses, attempt splitting without them, too.
2175     `omit` is a collection of closing bracket IDs that shouldn't be considered for
2176     this split.
2177
2178     Note: running this function modifies `bracket_depth` on the leaves of `line`.
2179     """
2180     head = Line(depth=line.depth)
2181     body = Line(depth=line.depth + 1, inside_brackets=True)
2182     tail = Line(depth=line.depth)
2183     tail_leaves: List[Leaf] = []
2184     body_leaves: List[Leaf] = []
2185     head_leaves: List[Leaf] = []
2186     current_leaves = tail_leaves
2187     opening_bracket = None
2188     closing_bracket = None
2189     for leaf in reversed(line.leaves):
2190         if current_leaves is body_leaves:
2191             if leaf is opening_bracket:
2192                 current_leaves = head_leaves if body_leaves else tail_leaves
2193         current_leaves.append(leaf)
2194         if current_leaves is tail_leaves:
2195             if leaf.type in CLOSING_BRACKETS and id(leaf) not in omit:
2196                 opening_bracket = leaf.opening_bracket
2197                 closing_bracket = leaf
2198                 current_leaves = body_leaves
2199     tail_leaves.reverse()
2200     body_leaves.reverse()
2201     head_leaves.reverse()
2202     # Since body is a new indent level, remove spurious leading whitespace.
2203     if body_leaves:
2204         normalize_prefix(body_leaves[0], inside_brackets=True)
2205     if not head_leaves:
2206         # No `head` means the split failed. Either `tail` has all content or
2207         # the matching `opening_bracket` wasn't available on `line` anymore.
2208         raise CannotSplit("No brackets found")
2209
2210     # Build the new lines.
2211     for result, leaves in (head, head_leaves), (body, body_leaves), (tail, tail_leaves):
2212         for leaf in leaves:
2213             result.append(leaf, preformatted=True)
2214             for comment_after in line.comments_after(leaf):
2215                 result.append(comment_after, preformatted=True)
2216     assert opening_bracket and closing_bracket
2217     body.should_explode = should_explode(body, opening_bracket)
2218     bracket_split_succeeded_or_raise(head, body, tail)
2219     if (
2220         # the body shouldn't be exploded
2221         not body.should_explode
2222         # the opening bracket is an optional paren
2223         and opening_bracket.type == token.LPAR
2224         and not opening_bracket.value
2225         # the closing bracket is an optional paren
2226         and closing_bracket.type == token.RPAR
2227         and not closing_bracket.value
2228         # there are no standalone comments in the body
2229         and not line.contains_standalone_comments(0)
2230         # and it's not an import (optional parens are the only thing we can split
2231         # on in this case; attempting a split without them is a waste of time)
2232         and not line.is_import
2233     ):
2234         omit = {id(closing_bracket), *omit}
2235         if can_omit_invisible_parens(body, line_length):
2236             try:
2237                 yield from right_hand_split(line, line_length, py36=py36, omit=omit)
2238                 return
2239             except CannotSplit:
2240                 if len(body.leaves) == 1 and not is_line_short_enough(
2241                     body, line_length=line_length
2242                 ):
2243                     raise CannotSplit(
2244                         "Splitting failed, body is still too long and can't be split."
2245                     )
2246
2247     ensure_visible(opening_bracket)
2248     ensure_visible(closing_bracket)
2249     for result in (head, body, tail):
2250         if result:
2251             yield result
2252
2253
2254 def bracket_split_succeeded_or_raise(head: Line, body: Line, tail: Line) -> None:
2255     """Raise :exc:`CannotSplit` if the last left- or right-hand split failed.
2256
2257     Do nothing otherwise.
2258
2259     A left- or right-hand split is based on a pair of brackets. Content before
2260     (and including) the opening bracket is left on one line, content inside the
2261     brackets is put on a separate line, and finally content starting with and
2262     following the closing bracket is put on a separate line.
2263
2264     Those are called `head`, `body`, and `tail`, respectively. If the split
2265     produced the same line (all content in `head`) or ended up with an empty `body`
2266     and the `tail` is just the closing bracket, then it's considered failed.
2267     """
2268     tail_len = len(str(tail).strip())
2269     if not body:
2270         if tail_len == 0:
2271             raise CannotSplit("Splitting brackets produced the same line")
2272
2273         elif tail_len < 3:
2274             raise CannotSplit(
2275                 f"Splitting brackets on an empty body to save "
2276                 f"{tail_len} characters is not worth it"
2277             )
2278
2279
2280 def dont_increase_indentation(split_func: SplitFunc) -> SplitFunc:
2281     """Normalize prefix of the first leaf in every line returned by `split_func`.
2282
2283     This is a decorator over relevant split functions.
2284     """
2285
2286     @wraps(split_func)
2287     def split_wrapper(line: Line, py36: bool = False) -> Iterator[Line]:
2288         for l in split_func(line, py36):
2289             normalize_prefix(l.leaves[0], inside_brackets=True)
2290             yield l
2291
2292     return split_wrapper
2293
2294
2295 @dont_increase_indentation
2296 def delimiter_split(line: Line, py36: bool = False) -> Iterator[Line]:
2297     """Split according to delimiters of the highest priority.
2298
2299     If `py36` is True, the split will add trailing commas also in function
2300     signatures that contain `*` and `**`.
2301     """
2302     try:
2303         last_leaf = line.leaves[-1]
2304     except IndexError:
2305         raise CannotSplit("Line empty")
2306
2307     bt = line.bracket_tracker
2308     try:
2309         delimiter_priority = bt.max_delimiter_priority(exclude={id(last_leaf)})
2310     except ValueError:
2311         raise CannotSplit("No delimiters found")
2312
2313     if delimiter_priority == DOT_PRIORITY:
2314         if bt.delimiter_count_with_priority(delimiter_priority) == 1:
2315             raise CannotSplit("Splitting a single attribute from its owner looks wrong")
2316
2317     current_line = Line(depth=line.depth, inside_brackets=line.inside_brackets)
2318     lowest_depth = sys.maxsize
2319     trailing_comma_safe = True
2320
2321     def append_to_line(leaf: Leaf) -> Iterator[Line]:
2322         """Append `leaf` to current line or to new line if appending impossible."""
2323         nonlocal current_line
2324         try:
2325             current_line.append_safe(leaf, preformatted=True)
2326         except ValueError as ve:
2327             yield current_line
2328
2329             current_line = Line(depth=line.depth, inside_brackets=line.inside_brackets)
2330             current_line.append(leaf)
2331
2332     for index, leaf in enumerate(line.leaves):
2333         yield from append_to_line(leaf)
2334
2335         for comment_after in line.comments_after(leaf, index):
2336             yield from append_to_line(comment_after)
2337
2338         lowest_depth = min(lowest_depth, leaf.bracket_depth)
2339         if leaf.bracket_depth == lowest_depth and is_vararg(
2340             leaf, within=VARARGS_PARENTS
2341         ):
2342             trailing_comma_safe = trailing_comma_safe and py36
2343         leaf_priority = bt.delimiters.get(id(leaf))
2344         if leaf_priority == delimiter_priority:
2345             yield current_line
2346
2347             current_line = Line(depth=line.depth, inside_brackets=line.inside_brackets)
2348     if current_line:
2349         if (
2350             trailing_comma_safe
2351             and delimiter_priority == COMMA_PRIORITY
2352             and current_line.leaves[-1].type != token.COMMA
2353             and current_line.leaves[-1].type != STANDALONE_COMMENT
2354         ):
2355             current_line.append(Leaf(token.COMMA, ","))
2356         yield current_line
2357
2358
2359 @dont_increase_indentation
2360 def standalone_comment_split(line: Line, py36: bool = False) -> Iterator[Line]:
2361     """Split standalone comments from the rest of the line."""
2362     if not line.contains_standalone_comments(0):
2363         raise CannotSplit("Line does not have any standalone comments")
2364
2365     current_line = Line(depth=line.depth, inside_brackets=line.inside_brackets)
2366
2367     def append_to_line(leaf: Leaf) -> Iterator[Line]:
2368         """Append `leaf` to current line or to new line if appending impossible."""
2369         nonlocal current_line
2370         try:
2371             current_line.append_safe(leaf, preformatted=True)
2372         except ValueError as ve:
2373             yield current_line
2374
2375             current_line = Line(depth=line.depth, inside_brackets=line.inside_brackets)
2376             current_line.append(leaf)
2377
2378     for index, leaf in enumerate(line.leaves):
2379         yield from append_to_line(leaf)
2380
2381         for comment_after in line.comments_after(leaf, index):
2382             yield from append_to_line(comment_after)
2383
2384     if current_line:
2385         yield current_line
2386
2387
2388 def is_import(leaf: Leaf) -> bool:
2389     """Return True if the given leaf starts an import statement."""
2390     p = leaf.parent
2391     t = leaf.type
2392     v = leaf.value
2393     return bool(
2394         t == token.NAME
2395         and (
2396             (v == "import" and p and p.type == syms.import_name)
2397             or (v == "from" and p and p.type == syms.import_from)
2398         )
2399     )
2400
2401
2402 def normalize_prefix(leaf: Leaf, *, inside_brackets: bool) -> None:
2403     """Leave existing extra newlines if not `inside_brackets`. Remove everything
2404     else.
2405
2406     Note: don't use backslashes for formatting or you'll lose your voting rights.
2407     """
2408     if not inside_brackets:
2409         spl = leaf.prefix.split("#")
2410         if "\\" not in spl[0]:
2411             nl_count = spl[-1].count("\n")
2412             if len(spl) > 1:
2413                 nl_count -= 1
2414             leaf.prefix = "\n" * nl_count
2415             return
2416
2417     leaf.prefix = ""
2418
2419
2420 def normalize_string_prefix(leaf: Leaf, remove_u_prefix: bool = False) -> None:
2421     """Make all string prefixes lowercase.
2422
2423     If remove_u_prefix is given, also removes any u prefix from the string.
2424
2425     Note: Mutates its argument.
2426     """
2427     match = re.match(r"^([furbFURB]*)(.*)$", leaf.value, re.DOTALL)
2428     assert match is not None, f"failed to match string {leaf.value!r}"
2429     orig_prefix = match.group(1)
2430     new_prefix = orig_prefix.lower()
2431     if remove_u_prefix:
2432         new_prefix = new_prefix.replace("u", "")
2433     leaf.value = f"{new_prefix}{match.group(2)}"
2434
2435
2436 def normalize_string_quotes(leaf: Leaf) -> None:
2437     """Prefer double quotes but only if it doesn't cause more escaping.
2438
2439     Adds or removes backslashes as appropriate. Doesn't parse and fix
2440     strings nested in f-strings (yet).
2441
2442     Note: Mutates its argument.
2443     """
2444     value = leaf.value.lstrip("furbFURB")
2445     if value[:3] == '"""':
2446         return
2447
2448     elif value[:3] == "'''":
2449         orig_quote = "'''"
2450         new_quote = '"""'
2451     elif value[0] == '"':
2452         orig_quote = '"'
2453         new_quote = "'"
2454     else:
2455         orig_quote = "'"
2456         new_quote = '"'
2457     first_quote_pos = leaf.value.find(orig_quote)
2458     if first_quote_pos == -1:
2459         return  # There's an internal error
2460
2461     prefix = leaf.value[:first_quote_pos]
2462     unescaped_new_quote = re.compile(rf"(([^\\]|^)(\\\\)*){new_quote}")
2463     escaped_new_quote = re.compile(rf"([^\\]|^)\\(\\\\)*{new_quote}")
2464     escaped_orig_quote = re.compile(rf"([^\\]|^)\\(\\\\)*{orig_quote}")
2465     body = leaf.value[first_quote_pos + len(orig_quote) : -len(orig_quote)]
2466     if "r" in prefix.casefold():
2467         if unescaped_new_quote.search(body):
2468             # There's at least one unescaped new_quote in this raw string
2469             # so converting is impossible
2470             return
2471
2472         # Do not introduce or remove backslashes in raw strings
2473         new_body = body
2474     else:
2475         # remove unnecessary quotes
2476         new_body = sub_twice(escaped_new_quote, rf"\1\2{new_quote}", body)
2477         if body != new_body:
2478             # Consider the string without unnecessary quotes as the original
2479             body = new_body
2480             leaf.value = f"{prefix}{orig_quote}{body}{orig_quote}"
2481         new_body = sub_twice(escaped_orig_quote, rf"\1\2{orig_quote}", new_body)
2482         new_body = sub_twice(unescaped_new_quote, rf"\1\\{new_quote}", new_body)
2483     if new_quote == '"""' and new_body[-1] == '"':
2484         # edge case:
2485         new_body = new_body[:-1] + '\\"'
2486     orig_escape_count = body.count("\\")
2487     new_escape_count = new_body.count("\\")
2488     if new_escape_count > orig_escape_count:
2489         return  # Do not introduce more escaping
2490
2491     if new_escape_count == orig_escape_count and orig_quote == '"':
2492         return  # Prefer double quotes
2493
2494     leaf.value = f"{prefix}{new_quote}{new_body}{new_quote}"
2495
2496
2497 def normalize_invisible_parens(node: Node, parens_after: Set[str]) -> None:
2498     """Make existing optional parentheses invisible or create new ones.
2499
2500     `parens_after` is a set of string leaf values immeditely after which parens
2501     should be put.
2502
2503     Standardizes on visible parentheses for single-element tuples, and keeps
2504     existing visible parentheses for other tuples and generator expressions.
2505     """
2506     try:
2507         list(generate_comments(node))
2508     except FormatOff:
2509         return  # This `node` has a prefix with `# fmt: off`, don't mess with parens.
2510
2511     check_lpar = False
2512     for index, child in enumerate(list(node.children)):
2513         if check_lpar:
2514             if child.type == syms.atom:
2515                 maybe_make_parens_invisible_in_atom(child)
2516             elif is_one_tuple(child):
2517                 # wrap child in visible parentheses
2518                 lpar = Leaf(token.LPAR, "(")
2519                 rpar = Leaf(token.RPAR, ")")
2520                 child.remove()
2521                 node.insert_child(index, Node(syms.atom, [lpar, child, rpar]))
2522             elif node.type == syms.import_from:
2523                 # "import from" nodes store parentheses directly as part of
2524                 # the statement
2525                 if child.type == token.LPAR:
2526                     # make parentheses invisible
2527                     child.value = ""  # type: ignore
2528                     node.children[-1].value = ""  # type: ignore
2529                 elif child.type != token.STAR:
2530                     # insert invisible parentheses
2531                     node.insert_child(index, Leaf(token.LPAR, ""))
2532                     node.append_child(Leaf(token.RPAR, ""))
2533                 break
2534
2535             elif not (isinstance(child, Leaf) and is_multiline_string(child)):
2536                 # wrap child in invisible parentheses
2537                 lpar = Leaf(token.LPAR, "")
2538                 rpar = Leaf(token.RPAR, "")
2539                 index = child.remove() or 0
2540                 node.insert_child(index, Node(syms.atom, [lpar, child, rpar]))
2541
2542         check_lpar = isinstance(child, Leaf) and child.value in parens_after
2543
2544
2545 def maybe_make_parens_invisible_in_atom(node: LN) -> bool:
2546     """If it's safe, make the parens in the atom `node` invisible, recusively."""
2547     if (
2548         node.type != syms.atom
2549         or is_empty_tuple(node)
2550         or is_one_tuple(node)
2551         or is_yield(node)
2552         or max_delimiter_priority_in_atom(node) >= COMMA_PRIORITY
2553     ):
2554         return False
2555
2556     first = node.children[0]
2557     last = node.children[-1]
2558     if first.type == token.LPAR and last.type == token.RPAR:
2559         # make parentheses invisible
2560         first.value = ""  # type: ignore
2561         last.value = ""  # type: ignore
2562         if len(node.children) > 1:
2563             maybe_make_parens_invisible_in_atom(node.children[1])
2564         return True
2565
2566     return False
2567
2568
2569 def is_empty_tuple(node: LN) -> bool:
2570     """Return True if `node` holds an empty tuple."""
2571     return (
2572         node.type == syms.atom
2573         and len(node.children) == 2
2574         and node.children[0].type == token.LPAR
2575         and node.children[1].type == token.RPAR
2576     )
2577
2578
2579 def is_one_tuple(node: LN) -> bool:
2580     """Return True if `node` holds a tuple with one element, with or without parens."""
2581     if node.type == syms.atom:
2582         if len(node.children) != 3:
2583             return False
2584
2585         lpar, gexp, rpar = node.children
2586         if not (
2587             lpar.type == token.LPAR
2588             and gexp.type == syms.testlist_gexp
2589             and rpar.type == token.RPAR
2590         ):
2591             return False
2592
2593         return len(gexp.children) == 2 and gexp.children[1].type == token.COMMA
2594
2595     return (
2596         node.type in IMPLICIT_TUPLE
2597         and len(node.children) == 2
2598         and node.children[1].type == token.COMMA
2599     )
2600
2601
2602 def is_yield(node: LN) -> bool:
2603     """Return True if `node` holds a `yield` or `yield from` expression."""
2604     if node.type == syms.yield_expr:
2605         return True
2606
2607     if node.type == token.NAME and node.value == "yield":  # type: ignore
2608         return True
2609
2610     if node.type != syms.atom:
2611         return False
2612
2613     if len(node.children) != 3:
2614         return False
2615
2616     lpar, expr, rpar = node.children
2617     if lpar.type == token.LPAR and rpar.type == token.RPAR:
2618         return is_yield(expr)
2619
2620     return False
2621
2622
2623 def is_vararg(leaf: Leaf, within: Set[NodeType]) -> bool:
2624     """Return True if `leaf` is a star or double star in a vararg or kwarg.
2625
2626     If `within` includes VARARGS_PARENTS, this applies to function signatures.
2627     If `within` includes UNPACKING_PARENTS, it applies to right hand-side
2628     extended iterable unpacking (PEP 3132) and additional unpacking
2629     generalizations (PEP 448).
2630     """
2631     if leaf.type not in STARS or not leaf.parent:
2632         return False
2633
2634     p = leaf.parent
2635     if p.type == syms.star_expr:
2636         # Star expressions are also used as assignment targets in extended
2637         # iterable unpacking (PEP 3132).  See what its parent is instead.
2638         if not p.parent:
2639             return False
2640
2641         p = p.parent
2642
2643     return p.type in within
2644
2645
2646 def is_multiline_string(leaf: Leaf) -> bool:
2647     """Return True if `leaf` is a multiline string that actually spans many lines."""
2648     value = leaf.value.lstrip("furbFURB")
2649     return value[:3] in {'"""', "'''"} and "\n" in value
2650
2651
2652 def is_stub_suite(node: Node) -> bool:
2653     """Return True if `node` is a suite with a stub body."""
2654     if (
2655         len(node.children) != 4
2656         or node.children[0].type != token.NEWLINE
2657         or node.children[1].type != token.INDENT
2658         or node.children[3].type != token.DEDENT
2659     ):
2660         return False
2661
2662     return is_stub_body(node.children[2])
2663
2664
2665 def is_stub_body(node: LN) -> bool:
2666     """Return True if `node` is a simple statement containing an ellipsis."""
2667     if not isinstance(node, Node) or node.type != syms.simple_stmt:
2668         return False
2669
2670     if len(node.children) != 2:
2671         return False
2672
2673     child = node.children[0]
2674     return (
2675         child.type == syms.atom
2676         and len(child.children) == 3
2677         and all(leaf == Leaf(token.DOT, ".") for leaf in child.children)
2678     )
2679
2680
2681 def max_delimiter_priority_in_atom(node: LN) -> int:
2682     """Return maximum delimiter priority inside `node`.
2683
2684     This is specific to atoms with contents contained in a pair of parentheses.
2685     If `node` isn't an atom or there are no enclosing parentheses, returns 0.
2686     """
2687     if node.type != syms.atom:
2688         return 0
2689
2690     first = node.children[0]
2691     last = node.children[-1]
2692     if not (first.type == token.LPAR and last.type == token.RPAR):
2693         return 0
2694
2695     bt = BracketTracker()
2696     for c in node.children[1:-1]:
2697         if isinstance(c, Leaf):
2698             bt.mark(c)
2699         else:
2700             for leaf in c.leaves():
2701                 bt.mark(leaf)
2702     try:
2703         return bt.max_delimiter_priority()
2704
2705     except ValueError:
2706         return 0
2707
2708
2709 def ensure_visible(leaf: Leaf) -> None:
2710     """Make sure parentheses are visible.
2711
2712     They could be invisible as part of some statements (see
2713     :func:`normalize_invible_parens` and :func:`visit_import_from`).
2714     """
2715     if leaf.type == token.LPAR:
2716         leaf.value = "("
2717     elif leaf.type == token.RPAR:
2718         leaf.value = ")"
2719
2720
2721 def should_explode(line: Line, opening_bracket: Leaf) -> bool:
2722     """Should `line` immediately be split with `delimiter_split()` after RHS?"""
2723     if not (
2724         opening_bracket.parent
2725         and opening_bracket.parent.type in {syms.atom, syms.import_from}
2726         and opening_bracket.value in "[{("
2727     ):
2728         return False
2729
2730     try:
2731         last_leaf = line.leaves[-1]
2732         exclude = {id(last_leaf)} if last_leaf.type == token.COMMA else set()
2733         max_priority = line.bracket_tracker.max_delimiter_priority(exclude=exclude)
2734     except (IndexError, ValueError):
2735         return False
2736
2737     return max_priority == COMMA_PRIORITY
2738
2739
2740 def is_python36(node: Node) -> bool:
2741     """Return True if the current file is using Python 3.6+ features.
2742
2743     Currently looking for:
2744     - f-strings; and
2745     - trailing commas after * or ** in function signatures and calls.
2746     """
2747     for n in node.pre_order():
2748         if n.type == token.STRING:
2749             value_head = n.value[:2]  # type: ignore
2750             if value_head in {'f"', 'F"', "f'", "F'", "rf", "fr", "RF", "FR"}:
2751                 return True
2752
2753         elif (
2754             n.type in {syms.typedargslist, syms.arglist}
2755             and n.children
2756             and n.children[-1].type == token.COMMA
2757         ):
2758             for ch in n.children:
2759                 if ch.type in STARS:
2760                     return True
2761
2762                 if ch.type == syms.argument:
2763                     for argch in ch.children:
2764                         if argch.type in STARS:
2765                             return True
2766
2767     return False
2768
2769
2770 def generate_trailers_to_omit(line: Line, line_length: int) -> Iterator[Set[LeafID]]:
2771     """Generate sets of closing bracket IDs that should be omitted in a RHS.
2772
2773     Brackets can be omitted if the entire trailer up to and including
2774     a preceding closing bracket fits in one line.
2775
2776     Yielded sets are cumulative (contain results of previous yields, too).  First
2777     set is empty.
2778     """
2779
2780     omit: Set[LeafID] = set()
2781     yield omit
2782
2783     length = 4 * line.depth
2784     opening_bracket = None
2785     closing_bracket = None
2786     optional_brackets: Set[LeafID] = set()
2787     inner_brackets: Set[LeafID] = set()
2788     for index, leaf, leaf_length in enumerate_with_length(line, reversed=True):
2789         length += leaf_length
2790         if length > line_length:
2791             break
2792
2793         has_inline_comment = leaf_length > len(leaf.value) + len(leaf.prefix)
2794         if leaf.type == STANDALONE_COMMENT or has_inline_comment:
2795             break
2796
2797         optional_brackets.discard(id(leaf))
2798         if opening_bracket:
2799             if leaf is opening_bracket:
2800                 opening_bracket = None
2801             elif leaf.type in CLOSING_BRACKETS:
2802                 inner_brackets.add(id(leaf))
2803         elif leaf.type in CLOSING_BRACKETS:
2804             if not leaf.value:
2805                 optional_brackets.add(id(opening_bracket))
2806                 continue
2807
2808             if index > 0 and line.leaves[index - 1].type in OPENING_BRACKETS:
2809                 # Empty brackets would fail a split so treat them as "inner"
2810                 # brackets (e.g. only add them to the `omit` set if another
2811                 # pair of brackets was good enough.
2812                 inner_brackets.add(id(leaf))
2813                 continue
2814
2815             opening_bracket = leaf.opening_bracket
2816             if closing_bracket:
2817                 omit.add(id(closing_bracket))
2818                 omit.update(inner_brackets)
2819                 inner_brackets.clear()
2820                 yield omit
2821             closing_bracket = leaf
2822
2823
2824 def get_future_imports(node: Node) -> Set[str]:
2825     """Return a set of __future__ imports in the file."""
2826     imports = set()
2827     for child in node.children:
2828         if child.type != syms.simple_stmt:
2829             break
2830         first_child = child.children[0]
2831         if isinstance(first_child, Leaf):
2832             # Continue looking if we see a docstring; otherwise stop.
2833             if (
2834                 len(child.children) == 2
2835                 and first_child.type == token.STRING
2836                 and child.children[1].type == token.NEWLINE
2837             ):
2838                 continue
2839             else:
2840                 break
2841         elif first_child.type == syms.import_from:
2842             module_name = first_child.children[1]
2843             if not isinstance(module_name, Leaf) or module_name.value != "__future__":
2844                 break
2845             for import_from_child in first_child.children[3:]:
2846                 if isinstance(import_from_child, Leaf):
2847                     if import_from_child.type == token.NAME:
2848                         imports.add(import_from_child.value)
2849                 else:
2850                     assert import_from_child.type == syms.import_as_names
2851                     for leaf in import_from_child.children:
2852                         if isinstance(leaf, Leaf) and leaf.type == token.NAME:
2853                             imports.add(leaf.value)
2854         else:
2855             break
2856     return imports
2857
2858
2859 def gen_python_files_in_dir(
2860     path: Path,
2861     root: Path,
2862     include: Pattern[str],
2863     exclude: Pattern[str],
2864     report: "Report",
2865 ) -> Iterator[Path]:
2866     """Generate all files under `path` whose paths are not excluded by the
2867     `exclude` regex, but are included by the `include` regex.
2868
2869     `report` is where output about exclusions goes.
2870     """
2871     assert root.is_absolute(), f"INTERNAL ERROR: `root` must be absolute but is {root}"
2872     for child in path.iterdir():
2873         normalized_path = "/" + child.resolve().relative_to(root).as_posix()
2874         if child.is_dir():
2875             normalized_path += "/"
2876         exclude_match = exclude.search(normalized_path)
2877         if exclude_match and exclude_match.group(0):
2878             report.path_ignored(child, f"matches --exclude={exclude.pattern}")
2879             continue
2880
2881         if child.is_dir():
2882             yield from gen_python_files_in_dir(child, root, include, exclude, report)
2883
2884         elif child.is_file():
2885             include_match = include.search(normalized_path)
2886             if include_match:
2887                 yield child
2888
2889
2890 def find_project_root(srcs: List[str]) -> Path:
2891     """Return a directory containing .git, .hg, or pyproject.toml.
2892
2893     That directory can be one of the directories passed in `srcs` or their
2894     common parent.
2895
2896     If no directory in the tree contains a marker that would specify it's the
2897     project root, the root of the file system is returned.
2898     """
2899     if not srcs:
2900         return Path("/").resolve()
2901
2902     common_base = min(Path(src).resolve() for src in srcs)
2903     if common_base.is_dir():
2904         # Append a fake file so `parents` below returns `common_base_dir`, too.
2905         common_base /= "fake-file"
2906     for directory in common_base.parents:
2907         if (directory / ".git").is_dir():
2908             return directory
2909
2910         if (directory / ".hg").is_dir():
2911             return directory
2912
2913         if (directory / "pyproject.toml").is_file():
2914             return directory
2915
2916     return directory
2917
2918
2919 @dataclass
2920 class Report:
2921     """Provides a reformatting counter. Can be rendered with `str(report)`."""
2922
2923     check: bool = False
2924     quiet: bool = False
2925     verbose: bool = False
2926     change_count: int = 0
2927     same_count: int = 0
2928     failure_count: int = 0
2929
2930     def done(self, src: Path, changed: Changed) -> None:
2931         """Increment the counter for successful reformatting. Write out a message."""
2932         if changed is Changed.YES:
2933             reformatted = "would reformat" if self.check else "reformatted"
2934             if self.verbose or not self.quiet:
2935                 out(f"{reformatted} {src}")
2936             self.change_count += 1
2937         else:
2938             if self.verbose:
2939                 if changed is Changed.NO:
2940                     msg = f"{src} already well formatted, good job."
2941                 else:
2942                     msg = f"{src} wasn't modified on disk since last run."
2943                 out(msg, bold=False)
2944             self.same_count += 1
2945
2946     def failed(self, src: Path, message: str) -> None:
2947         """Increment the counter for failed reformatting. Write out a message."""
2948         err(f"error: cannot format {src}: {message}")
2949         self.failure_count += 1
2950
2951     def path_ignored(self, path: Path, message: str) -> None:
2952         if self.verbose:
2953             out(f"{path} ignored: {message}", bold=False)
2954
2955     @property
2956     def return_code(self) -> int:
2957         """Return the exit code that the app should use.
2958
2959         This considers the current state of changed files and failures:
2960         - if there were any failures, return 123;
2961         - if any files were changed and --check is being used, return 1;
2962         - otherwise return 0.
2963         """
2964         # According to http://tldp.org/LDP/abs/html/exitcodes.html starting with
2965         # 126 we have special returncodes reserved by the shell.
2966         if self.failure_count:
2967             return 123
2968
2969         elif self.change_count and self.check:
2970             return 1
2971
2972         return 0
2973
2974     def __str__(self) -> str:
2975         """Render a color report of the current state.
2976
2977         Use `click.unstyle` to remove colors.
2978         """
2979         if self.check:
2980             reformatted = "would be reformatted"
2981             unchanged = "would be left unchanged"
2982             failed = "would fail to reformat"
2983         else:
2984             reformatted = "reformatted"
2985             unchanged = "left unchanged"
2986             failed = "failed to reformat"
2987         report = []
2988         if self.change_count:
2989             s = "s" if self.change_count > 1 else ""
2990             report.append(
2991                 click.style(f"{self.change_count} file{s} {reformatted}", bold=True)
2992             )
2993         if self.same_count:
2994             s = "s" if self.same_count > 1 else ""
2995             report.append(f"{self.same_count} file{s} {unchanged}")
2996         if self.failure_count:
2997             s = "s" if self.failure_count > 1 else ""
2998             report.append(
2999                 click.style(f"{self.failure_count} file{s} {failed}", fg="red")
3000             )
3001         return ", ".join(report) + "."
3002
3003
3004 def assert_equivalent(src: str, dst: str) -> None:
3005     """Raise AssertionError if `src` and `dst` aren't equivalent."""
3006
3007     import ast
3008     import traceback
3009
3010     def _v(node: ast.AST, depth: int = 0) -> Iterator[str]:
3011         """Simple visitor generating strings to compare ASTs by content."""
3012         yield f"{'  ' * depth}{node.__class__.__name__}("
3013
3014         for field in sorted(node._fields):
3015             try:
3016                 value = getattr(node, field)
3017             except AttributeError:
3018                 continue
3019
3020             yield f"{'  ' * (depth+1)}{field}="
3021
3022             if isinstance(value, list):
3023                 for item in value:
3024                     if isinstance(item, ast.AST):
3025                         yield from _v(item, depth + 2)
3026
3027             elif isinstance(value, ast.AST):
3028                 yield from _v(value, depth + 2)
3029
3030             else:
3031                 yield f"{'  ' * (depth+2)}{value!r},  # {value.__class__.__name__}"
3032
3033         yield f"{'  ' * depth})  # /{node.__class__.__name__}"
3034
3035     try:
3036         src_ast = ast.parse(src)
3037     except Exception as exc:
3038         major, minor = sys.version_info[:2]
3039         raise AssertionError(
3040             f"cannot use --safe with this file; failed to parse source file "
3041             f"with Python {major}.{minor}'s builtin AST. Re-run with --fast "
3042             f"or stop using deprecated Python 2 syntax. AST error message: {exc}"
3043         )
3044
3045     try:
3046         dst_ast = ast.parse(dst)
3047     except Exception as exc:
3048         log = dump_to_file("".join(traceback.format_tb(exc.__traceback__)), dst)
3049         raise AssertionError(
3050             f"INTERNAL ERROR: Black produced invalid code: {exc}. "
3051             f"Please report a bug on https://github.com/ambv/black/issues.  "
3052             f"This invalid output might be helpful: {log}"
3053         ) from None
3054
3055     src_ast_str = "\n".join(_v(src_ast))
3056     dst_ast_str = "\n".join(_v(dst_ast))
3057     if src_ast_str != dst_ast_str:
3058         log = dump_to_file(diff(src_ast_str, dst_ast_str, "src", "dst"))
3059         raise AssertionError(
3060             f"INTERNAL ERROR: Black produced code that is not equivalent to "
3061             f"the source.  "
3062             f"Please report a bug on https://github.com/ambv/black/issues.  "
3063             f"This diff might be helpful: {log}"
3064         ) from None
3065
3066
3067 def assert_stable(
3068     src: str, dst: str, line_length: int, mode: FileMode = FileMode.AUTO_DETECT
3069 ) -> None:
3070     """Raise AssertionError if `dst` reformats differently the second time."""
3071     newdst = format_str(dst, line_length=line_length, mode=mode)
3072     if dst != newdst:
3073         log = dump_to_file(
3074             diff(src, dst, "source", "first pass"),
3075             diff(dst, newdst, "first pass", "second pass"),
3076         )
3077         raise AssertionError(
3078             f"INTERNAL ERROR: Black produced different code on the second pass "
3079             f"of the formatter.  "
3080             f"Please report a bug on https://github.com/ambv/black/issues.  "
3081             f"This diff might be helpful: {log}"
3082         ) from None
3083
3084
3085 def dump_to_file(*output: str) -> str:
3086     """Dump `output` to a temporary file. Return path to the file."""
3087     import tempfile
3088
3089     with tempfile.NamedTemporaryFile(
3090         mode="w", prefix="blk_", suffix=".log", delete=False, encoding="utf8"
3091     ) as f:
3092         for lines in output:
3093             f.write(lines)
3094             if lines and lines[-1] != "\n":
3095                 f.write("\n")
3096     return f.name
3097
3098
3099 def diff(a: str, b: str, a_name: str, b_name: str) -> str:
3100     """Return a unified diff string between strings `a` and `b`."""
3101     import difflib
3102
3103     a_lines = [line + "\n" for line in a.split("\n")]
3104     b_lines = [line + "\n" for line in b.split("\n")]
3105     return "".join(
3106         difflib.unified_diff(a_lines, b_lines, fromfile=a_name, tofile=b_name, n=5)
3107     )
3108
3109
3110 def cancel(tasks: Iterable[asyncio.Task]) -> None:
3111     """asyncio signal handler that cancels all `tasks` and reports to stderr."""
3112     err("Aborted!")
3113     for task in tasks:
3114         task.cancel()
3115
3116
3117 def shutdown(loop: BaseEventLoop) -> None:
3118     """Cancel all pending tasks on `loop`, wait for them, and close the loop."""
3119     try:
3120         # This part is borrowed from asyncio/runners.py in Python 3.7b2.
3121         to_cancel = [task for task in asyncio.Task.all_tasks(loop) if not task.done()]
3122         if not to_cancel:
3123             return
3124
3125         for task in to_cancel:
3126             task.cancel()
3127         loop.run_until_complete(
3128             asyncio.gather(*to_cancel, loop=loop, return_exceptions=True)
3129         )
3130     finally:
3131         # `concurrent.futures.Future` objects cannot be cancelled once they
3132         # are already running. There might be some when the `shutdown()` happened.
3133         # Silence their logger's spew about the event loop being closed.
3134         cf_logger = logging.getLogger("concurrent.futures")
3135         cf_logger.setLevel(logging.CRITICAL)
3136         loop.close()
3137
3138
3139 def sub_twice(regex: Pattern[str], replacement: str, original: str) -> str:
3140     """Replace `regex` with `replacement` twice on `original`.
3141
3142     This is used by string normalization to perform replaces on
3143     overlapping matches.
3144     """
3145     return regex.sub(replacement, regex.sub(replacement, original))
3146
3147
3148 def enumerate_reversed(sequence: Sequence[T]) -> Iterator[Tuple[Index, T]]:
3149     """Like `reversed(enumerate(sequence))` if that were possible."""
3150     index = len(sequence) - 1
3151     for element in reversed(sequence):
3152         yield (index, element)
3153         index -= 1
3154
3155
3156 def enumerate_with_length(
3157     line: Line, reversed: bool = False
3158 ) -> Iterator[Tuple[Index, Leaf, int]]:
3159     """Return an enumeration of leaves with their length.
3160
3161     Stops prematurely on multiline strings and standalone comments.
3162     """
3163     op = cast(
3164         Callable[[Sequence[Leaf]], Iterator[Tuple[Index, Leaf]]],
3165         enumerate_reversed if reversed else enumerate,
3166     )
3167     for index, leaf in op(line.leaves):
3168         length = len(leaf.prefix) + len(leaf.value)
3169         if "\n" in leaf.value:
3170             return  # Multiline strings, we can't continue.
3171
3172         comment: Optional[Leaf]
3173         for comment in line.comments_after(leaf, index):
3174             length += len(comment.value)
3175
3176         yield index, leaf, length
3177
3178
3179 def is_line_short_enough(line: Line, *, line_length: int, line_str: str = "") -> bool:
3180     """Return True if `line` is no longer than `line_length`.
3181
3182     Uses the provided `line_str` rendering, if any, otherwise computes a new one.
3183     """
3184     if not line_str:
3185         line_str = str(line).strip("\n")
3186     return (
3187         len(line_str) <= line_length
3188         and "\n" not in line_str  # multiline strings
3189         and not line.contains_standalone_comments()
3190     )
3191
3192
3193 def can_omit_invisible_parens(line: Line, line_length: int) -> bool:
3194     """Does `line` have a shape safe to reformat without optional parens around it?
3195
3196     Returns True for only a subset of potentially nice looking formattings but
3197     the point is to not return false positives that end up producing lines that
3198     are too long.
3199     """
3200     bt = line.bracket_tracker
3201     if not bt.delimiters:
3202         # Without delimiters the optional parentheses are useless.
3203         return True
3204
3205     max_priority = bt.max_delimiter_priority()
3206     if bt.delimiter_count_with_priority(max_priority) > 1:
3207         # With more than one delimiter of a kind the optional parentheses read better.
3208         return False
3209
3210     if max_priority == DOT_PRIORITY:
3211         # A single stranded method call doesn't require optional parentheses.
3212         return True
3213
3214     assert len(line.leaves) >= 2, "Stranded delimiter"
3215
3216     first = line.leaves[0]
3217     second = line.leaves[1]
3218     penultimate = line.leaves[-2]
3219     last = line.leaves[-1]
3220
3221     # With a single delimiter, omit if the expression starts or ends with
3222     # a bracket.
3223     if first.type in OPENING_BRACKETS and second.type not in CLOSING_BRACKETS:
3224         remainder = False
3225         length = 4 * line.depth
3226         for _index, leaf, leaf_length in enumerate_with_length(line):
3227             if leaf.type in CLOSING_BRACKETS and leaf.opening_bracket is first:
3228                 remainder = True
3229             if remainder:
3230                 length += leaf_length
3231                 if length > line_length:
3232                     break
3233
3234                 if leaf.type in OPENING_BRACKETS:
3235                     # There are brackets we can further split on.
3236                     remainder = False
3237
3238         else:
3239             # checked the entire string and line length wasn't exceeded
3240             if len(line.leaves) == _index + 1:
3241                 return True
3242
3243         # Note: we are not returning False here because a line might have *both*
3244         # a leading opening bracket and a trailing closing bracket.  If the
3245         # opening bracket doesn't match our rule, maybe the closing will.
3246
3247     if (
3248         last.type == token.RPAR
3249         or last.type == token.RBRACE
3250         or (
3251             # don't use indexing for omitting optional parentheses;
3252             # it looks weird
3253             last.type == token.RSQB
3254             and last.parent
3255             and last.parent.type != syms.trailer
3256         )
3257     ):
3258         if penultimate.type in OPENING_BRACKETS:
3259             # Empty brackets don't help.
3260             return False
3261
3262         if is_multiline_string(first):
3263             # Additional wrapping of a multiline string in this situation is
3264             # unnecessary.
3265             return True
3266
3267         length = 4 * line.depth
3268         seen_other_brackets = False
3269         for _index, leaf, leaf_length in enumerate_with_length(line):
3270             length += leaf_length
3271             if leaf is last.opening_bracket:
3272                 if seen_other_brackets or length <= line_length:
3273                     return True
3274
3275             elif leaf.type in OPENING_BRACKETS:
3276                 # There are brackets we can further split on.
3277                 seen_other_brackets = True
3278
3279     return False
3280
3281
3282 def get_cache_file(line_length: int, mode: FileMode) -> Path:
3283     pyi = bool(mode & FileMode.PYI)
3284     py36 = bool(mode & FileMode.PYTHON36)
3285     return (
3286         CACHE_DIR
3287         / f"cache.{line_length}{'.pyi' if pyi else ''}{'.py36' if py36 else ''}.pickle"
3288     )
3289
3290
3291 def read_cache(line_length: int, mode: FileMode) -> Cache:
3292     """Read the cache if it exists and is well formed.
3293
3294     If it is not well formed, the call to write_cache later should resolve the issue.
3295     """
3296     cache_file = get_cache_file(line_length, mode)
3297     if not cache_file.exists():
3298         return {}
3299
3300     with cache_file.open("rb") as fobj:
3301         try:
3302             cache: Cache = pickle.load(fobj)
3303         except pickle.UnpicklingError:
3304             return {}
3305
3306     return cache
3307
3308
3309 def get_cache_info(path: Path) -> CacheInfo:
3310     """Return the information used to check if a file is already formatted or not."""
3311     stat = path.stat()
3312     return stat.st_mtime, stat.st_size
3313
3314
3315 def filter_cached(cache: Cache, sources: Iterable[Path]) -> Tuple[Set[Path], Set[Path]]:
3316     """Split an iterable of paths in `sources` into two sets.
3317
3318     The first contains paths of files that modified on disk or are not in the
3319     cache. The other contains paths to non-modified files.
3320     """
3321     todo, done = set(), set()
3322     for src in sources:
3323         src = src.resolve()
3324         if cache.get(src) != get_cache_info(src):
3325             todo.add(src)
3326         else:
3327             done.add(src)
3328     return todo, done
3329
3330
3331 def write_cache(
3332     cache: Cache, sources: Iterable[Path], line_length: int, mode: FileMode
3333 ) -> None:
3334     """Update the cache file."""
3335     cache_file = get_cache_file(line_length, mode)
3336     try:
3337         if not CACHE_DIR.exists():
3338             CACHE_DIR.mkdir(parents=True)
3339         new_cache = {**cache, **{src.resolve(): get_cache_info(src) for src in sources}}
3340         with cache_file.open("wb") as fobj:
3341             pickle.dump(new_cache, fobj, protocol=pickle.HIGHEST_PROTOCOL)
3342     except OSError:
3343         pass
3344
3345
3346 if __name__ == "__main__":
3347     main()