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.
   4 from dataclasses import dataclass, field
 
  18 from black.brackets import DOT_PRIORITY, BracketTracker
 
  19 from black.mode import Mode, Preview
 
  20 from black.nodes import (
 
  29     is_one_sequence_between,
 
  35 from blib2to3.pgen2 import token
 
  36 from blib2to3.pytree import Leaf, Node
 
  42 LN = Union[Leaf, Node]
 
  47     """Holds leaves and comments. Can be printed with `str(line)`."""
 
  51     leaves: List[Leaf] = field(default_factory=list)
 
  52     # keys ordered like `leaves`
 
  53     comments: Dict[LeafID, List[Leaf]] = field(default_factory=dict)
 
  54     bracket_tracker: BracketTracker = field(default_factory=BracketTracker)
 
  55     inside_brackets: bool = False
 
  56     should_split_rhs: bool = False
 
  57     magic_trailing_comma: Optional[Leaf] = None
 
  60         self, leaf: Leaf, preformatted: bool = False, track_bracket: bool = False
 
  62         """Add a new `leaf` to the end of the line.
 
  64         Unless `preformatted` is True, the `leaf` will receive a new consistent
 
  65         whitespace prefix and metadata applied by :class:`BracketTracker`.
 
  66         Trailing commas are maybe removed, unpacked for loop variables are
 
  67         demoted from being delimiters.
 
  69         Inline comments are put aside.
 
  71         has_value = leaf.type in BRACKETS or bool(leaf.value.strip())
 
  75         if token.COLON == leaf.type and self.is_class_paren_empty:
 
  77         if self.leaves and not preformatted:
 
  78             # Note: at this point leaf.prefix should be empty except for
 
  79             # imports, for which we only preserve newlines.
 
  80             leaf.prefix += whitespace(
 
  81                 leaf, complex_subscript=self.is_complex_subscript(leaf)
 
  83         if self.inside_brackets or not preformatted or track_bracket:
 
  84             self.bracket_tracker.mark(leaf)
 
  85             if self.mode.magic_trailing_comma:
 
  86                 if self.has_magic_trailing_comma(leaf):
 
  87                     self.magic_trailing_comma = leaf
 
  88             elif self.has_magic_trailing_comma(leaf, ensure_removable=True):
 
  89                 self.remove_trailing_comma()
 
  90         if not self.append_comment(leaf):
 
  91             self.leaves.append(leaf)
 
  93     def append_safe(self, leaf: Leaf, preformatted: bool = False) -> None:
 
  94         """Like :func:`append()` but disallow invalid standalone comment structure.
 
  96         Raises ValueError when any `leaf` is appended after a standalone comment
 
  97         or when a standalone comment is not the first leaf on the line.
 
  99         if self.bracket_tracker.depth == 0:
 
 101                 raise ValueError("cannot append to standalone comments")
 
 103             if self.leaves and leaf.type == STANDALONE_COMMENT:
 
 105                     "cannot append standalone comments to a populated line"
 
 108         self.append(leaf, preformatted=preformatted)
 
 111     def is_comment(self) -> bool:
 
 112         """Is this line a standalone comment?"""
 
 113         return len(self.leaves) == 1 and self.leaves[0].type == STANDALONE_COMMENT
 
 116     def is_decorator(self) -> bool:
 
 117         """Is this line a decorator?"""
 
 118         return bool(self) and self.leaves[0].type == token.AT
 
 121     def is_import(self) -> bool:
 
 122         """Is this an import line?"""
 
 123         return bool(self) and is_import(self.leaves[0])
 
 126     def is_class(self) -> bool:
 
 127         """Is this line a class definition?"""
 
 130             and self.leaves[0].type == token.NAME
 
 131             and self.leaves[0].value == "class"
 
 135     def is_stub_class(self) -> bool:
 
 136         """Is this line a class definition with a body consisting only of "..."?"""
 
 137         return self.is_class and self.leaves[-3:] == [
 
 138             Leaf(token.DOT, ".") for _ in range(3)
 
 142     def is_def(self) -> bool:
 
 143         """Is this a function definition? (Also returns True for async defs.)"""
 
 145             first_leaf = self.leaves[0]
 
 150             second_leaf: Optional[Leaf] = self.leaves[1]
 
 153         return (first_leaf.type == token.NAME and first_leaf.value == "def") or (
 
 154             first_leaf.type == token.ASYNC
 
 155             and second_leaf is not None
 
 156             and second_leaf.type == token.NAME
 
 157             and second_leaf.value == "def"
 
 161     def is_class_paren_empty(self) -> bool:
 
 162         """Is this a class with no base classes but using parentheses?
 
 164         Those are unnecessary and should be removed.
 
 168             and len(self.leaves) == 4
 
 170             and self.leaves[2].type == token.LPAR
 
 171             and self.leaves[2].value == "("
 
 172             and self.leaves[3].type == token.RPAR
 
 173             and self.leaves[3].value == ")"
 
 177     def is_triple_quoted_string(self) -> bool:
 
 178         """Is the line a triple quoted string?"""
 
 181             and self.leaves[0].type == token.STRING
 
 182             and self.leaves[0].value.startswith(('"""', "'''"))
 
 186     def opens_block(self) -> bool:
 
 187         """Does this line open a new level of indentation."""
 
 188         if len(self.leaves) == 0:
 
 190         return self.leaves[-1].type == token.COLON
 
 192     def contains_standalone_comments(self, depth_limit: int = sys.maxsize) -> bool:
 
 193         """If so, needs to be split before emitting."""
 
 194         for leaf in self.leaves:
 
 195             if leaf.type == STANDALONE_COMMENT and leaf.bracket_depth <= depth_limit:
 
 200     def contains_uncollapsable_type_comments(self) -> bool:
 
 203             last_leaf = self.leaves[-1]
 
 204             ignored_ids.add(id(last_leaf))
 
 205             if last_leaf.type == token.COMMA or (
 
 206                 last_leaf.type == token.RPAR and not last_leaf.value
 
 208                 # When trailing commas or optional parens are inserted by Black for
 
 209                 # consistency, comments after the previous last element are not moved
 
 210                 # (they don't have to, rendering will still be correct).  So we ignore
 
 211                 # trailing commas and invisible.
 
 212                 last_leaf = self.leaves[-2]
 
 213                 ignored_ids.add(id(last_leaf))
 
 217         # A type comment is uncollapsable if it is attached to a leaf
 
 218         # that isn't at the end of the line (since that could cause it
 
 219         # to get associated to a different argument) or if there are
 
 220         # comments before it (since that could cause it to get hidden
 
 223         for leaf_id, comments in self.comments.items():
 
 224             for comment in comments:
 
 225                 if is_type_comment(comment):
 
 227                         not is_type_comment(comment, " ignore")
 
 228                         and leaf_id not in ignored_ids
 
 236     def contains_unsplittable_type_ignore(self) -> bool:
 
 240         # If a 'type: ignore' is attached to the end of a line, we
 
 241         # can't split the line, because we can't know which of the
 
 242         # subexpressions the ignore was meant to apply to.
 
 244         # We only want this to apply to actual physical lines from the
 
 245         # original source, though: we don't want the presence of a
 
 246         # 'type: ignore' at the end of a multiline expression to
 
 247         # justify pushing it all onto one line. Thus we
 
 248         # (unfortunately) need to check the actual source lines and
 
 249         # only report an unsplittable 'type: ignore' if this line was
 
 250         # one line in the original code.
 
 252         # Grab the first and last line numbers, skipping generated leaves
 
 253         first_line = next((leaf.lineno for leaf in self.leaves if leaf.lineno != 0), 0)
 
 255             (leaf.lineno for leaf in reversed(self.leaves) if leaf.lineno != 0), 0
 
 258         if first_line == last_line:
 
 259             # We look at the last two leaves since a comma or an
 
 260             # invisible paren could have been added at the end of the
 
 262             for node in self.leaves[-2:]:
 
 263                 for comment in self.comments.get(id(node), []):
 
 264                     if is_type_comment(comment, " ignore"):
 
 269     def contains_multiline_strings(self) -> bool:
 
 270         return any(is_multiline_string(leaf) for leaf in self.leaves)
 
 272     def has_magic_trailing_comma(
 
 273         self, closing: Leaf, ensure_removable: bool = False
 
 275         """Return True if we have a magic trailing comma, that is when:
 
 276         - there's a trailing comma here
 
 277         - it's not a one-tuple
 
 278         - it's not a single-element subscript
 
 279         Additionally, if ensure_removable:
 
 280         - it's not from square bracket indexing
 
 281         (specifically, single-element square bracket indexing)
 
 284             closing.type in CLOSING_BRACKETS
 
 286             and self.leaves[-1].type == token.COMMA
 
 290         if closing.type == token.RBRACE:
 
 293         if closing.type == token.RSQB:
 
 296                 and closing.parent.type == syms.trailer
 
 297                 and closing.opening_bracket
 
 298                 and is_one_sequence_between(
 
 299                     closing.opening_bracket,
 
 302                     brackets=(token.LSQB, token.RSQB),
 
 307             if not ensure_removable:
 
 310             comma = self.leaves[-1]
 
 311             if comma.parent is None:
 
 314                 comma.parent.type != syms.subscriptlist
 
 315                 or closing.opening_bracket is None
 
 316                 or not is_one_sequence_between(
 
 317                     closing.opening_bracket,
 
 320                     brackets=(token.LSQB, token.RSQB),
 
 327         if closing.opening_bracket is not None and not is_one_sequence_between(
 
 328             closing.opening_bracket, closing, self.leaves
 
 334     def append_comment(self, comment: Leaf) -> bool:
 
 335         """Add an inline or standalone comment to the line."""
 
 337             comment.type == STANDALONE_COMMENT
 
 338             and self.bracket_tracker.any_open_brackets()
 
 343         if comment.type != token.COMMENT:
 
 347             comment.type = STANDALONE_COMMENT
 
 351         last_leaf = self.leaves[-1]
 
 353             last_leaf.type == token.RPAR
 
 354             and not last_leaf.value
 
 356             and len(list(last_leaf.parent.leaves())) <= 3
 
 357             and not is_type_comment(comment)
 
 359             # Comments on an optional parens wrapping a single leaf should belong to
 
 360             # the wrapped node except if it's a type comment. Pinning the comment like
 
 361             # this avoids unstable formatting caused by comment migration.
 
 362             if len(self.leaves) < 2:
 
 363                 comment.type = STANDALONE_COMMENT
 
 367             last_leaf = self.leaves[-2]
 
 368         self.comments.setdefault(id(last_leaf), []).append(comment)
 
 371     def comments_after(self, leaf: Leaf) -> List[Leaf]:
 
 372         """Generate comments that should appear directly after `leaf`."""
 
 373         return self.comments.get(id(leaf), [])
 
 375     def remove_trailing_comma(self) -> None:
 
 376         """Remove the trailing comma and moves the comments attached to it."""
 
 377         trailing_comma = self.leaves.pop()
 
 378         trailing_comma_comments = self.comments.pop(id(trailing_comma), [])
 
 379         self.comments.setdefault(id(self.leaves[-1]), []).extend(
 
 380             trailing_comma_comments
 
 383     def is_complex_subscript(self, leaf: Leaf) -> bool:
 
 384         """Return True iff `leaf` is part of a slice with non-trivial exprs."""
 
 385         open_lsqb = self.bracket_tracker.get_open_lsqb()
 
 386         if open_lsqb is None:
 
 389         subscript_start = open_lsqb.next_sibling
 
 391         if isinstance(subscript_start, Node):
 
 392             if subscript_start.type == syms.listmaker:
 
 395             if subscript_start.type == syms.subscriptlist:
 
 396                 subscript_start = child_towards(subscript_start, leaf)
 
 397         return subscript_start is not None and any(
 
 398             n.type in TEST_DESCENDANTS for n in subscript_start.pre_order()
 
 401     def enumerate_with_length(
 
 402         self, reversed: bool = False
 
 403     ) -> Iterator[Tuple[Index, Leaf, int]]:
 
 404         """Return an enumeration of leaves with their length.
 
 406         Stops prematurely on multiline strings and standalone comments.
 
 409             Callable[[Sequence[Leaf]], Iterator[Tuple[Index, Leaf]]],
 
 410             enumerate_reversed if reversed else enumerate,
 
 412         for index, leaf in op(self.leaves):
 
 413             length = len(leaf.prefix) + len(leaf.value)
 
 414             if "\n" in leaf.value:
 
 415                 return  # Multiline strings, we can't continue.
 
 417             for comment in self.comments_after(leaf):
 
 418                 length += len(comment.value)
 
 420             yield index, leaf, length
 
 422     def clone(self) -> "Line":
 
 426             inside_brackets=self.inside_brackets,
 
 427             should_split_rhs=self.should_split_rhs,
 
 428             magic_trailing_comma=self.magic_trailing_comma,
 
 431     def __str__(self) -> str:
 
 432         """Render the line."""
 
 436         indent = "    " * self.depth
 
 437         leaves = iter(self.leaves)
 
 439         res = f"{first.prefix}{indent}{first.value}"
 
 442         for comment in itertools.chain.from_iterable(self.comments.values()):
 
 447     def __bool__(self) -> bool:
 
 448         """Return True if the line has leaves or comments."""
 
 449         return bool(self.leaves or self.comments)
 
 454     """Class that holds information about a block of formatted lines.
 
 456     This is introduced so that the EmptyLineTracker can look behind the standalone
 
 457     comments and adjust their empty lines for class or def lines.
 
 461     previous_block: Optional["LinesBlock"]
 
 464     content_lines: List[str] = field(default_factory=list)
 
 467     def all_lines(self) -> List[str]:
 
 468         empty_line = str(Line(mode=self.mode))
 
 470             [empty_line * self.before] + self.content_lines + [empty_line * self.after]
 
 475 class EmptyLineTracker:
 
 476     """Provides a stateful method that returns the number of potential extra
 
 477     empty lines needed before and after the currently processed line.
 
 479     Note: this tracker works on lines that haven't been split yet.  It assumes
 
 480     the prefix of the first leaf consists of optional newlines.  Those newlines
 
 481     are consumed by `maybe_empty_lines()` and included in the computation.
 
 485     previous_line: Optional[Line] = None
 
 486     previous_block: Optional[LinesBlock] = None
 
 487     previous_defs: List[int] = field(default_factory=list)
 
 488     semantic_leading_comment: Optional[LinesBlock] = None
 
 490     def maybe_empty_lines(self, current_line: Line) -> LinesBlock:
 
 491         """Return the number of extra empty lines before and after the `current_line`.
 
 493         This is for separating `def`, `async def` and `class` with extra empty
 
 494         lines (two on module-level).
 
 496         before, after = self._maybe_empty_lines(current_line)
 
 497         previous_after = self.previous_block.after if self.previous_block else 0
 
 499             # Black should not insert empty lines at the beginning
 
 502             if self.previous_line is None
 
 503             else before - previous_after
 
 507             previous_block=self.previous_block,
 
 508             original_line=current_line,
 
 513         # Maintain the semantic_leading_comment state.
 
 514         if current_line.is_comment:
 
 515             if self.previous_line is None or (
 
 516                 not self.previous_line.is_decorator
 
 517                 # `or before` means this comment already has an empty line before
 
 518                 and (not self.previous_line.is_comment or before)
 
 519                 and (self.semantic_leading_comment is None or before)
 
 521                 self.semantic_leading_comment = block
 
 522         # `or before` means this decorator already has an empty line before
 
 523         elif not current_line.is_decorator or before:
 
 524             self.semantic_leading_comment = None
 
 526         self.previous_line = current_line
 
 527         self.previous_block = block
 
 530     def _maybe_empty_lines(self, current_line: Line) -> Tuple[int, int]:
 
 532         if current_line.depth == 0:
 
 533             max_allowed = 1 if self.mode.is_pyi else 2
 
 534         if current_line.leaves:
 
 535             # Consume the first leaf's extra newlines.
 
 536             first_leaf = current_line.leaves[0]
 
 537             before = first_leaf.prefix.count("\n")
 
 538             before = min(before, max_allowed)
 
 539             first_leaf.prefix = ""
 
 542         depth = current_line.depth
 
 543         while self.previous_defs and self.previous_defs[-1] >= depth:
 
 545                 assert self.previous_line is not None
 
 546                 if depth and not current_line.is_def and self.previous_line.is_def:
 
 547                     # Empty lines between attributes and methods should be preserved.
 
 548                     before = min(1, before)
 
 558                     and self.previous_defs[-1]
 
 559                     and current_line.leaves[-1].type == token.COLON
 
 561                         current_line.leaves[0].value
 
 562                         not in ("with", "try", "for", "while", "if", "match")
 
 565                     # We shouldn't add two newlines between an indented function and
 
 566                     # a dependent non-indented clause. This is to avoid issues with
 
 567                     # conditional function definitions that are technically top-level
 
 568                     # and therefore get two trailing newlines, but look weird and
 
 569                     # inconsistent when they're followed by elif, else, etc. This is
 
 570                     # worse because these functions only get *one* preceding newline
 
 575             self.previous_defs.pop()
 
 576         if current_line.is_decorator or current_line.is_def or current_line.is_class:
 
 577             return self._maybe_empty_lines_for_class_or_def(current_line, before)
 
 581             and self.previous_line.is_import
 
 582             and not current_line.is_import
 
 583             and depth == self.previous_line.depth
 
 585             return (before or 1), 0
 
 589             and self.previous_line.is_class
 
 590             and current_line.is_triple_quoted_string
 
 594         if self.previous_line and self.previous_line.opens_block:
 
 598     def _maybe_empty_lines_for_class_or_def(
 
 599         self, current_line: Line, before: int
 
 600     ) -> Tuple[int, int]:
 
 601         if not current_line.is_decorator:
 
 602             self.previous_defs.append(current_line.depth)
 
 603         if self.previous_line is None:
 
 604             # Don't insert empty lines before the first line in the file.
 
 607         if self.previous_line.is_decorator:
 
 608             if self.mode.is_pyi and current_line.is_stub_class:
 
 609                 # Insert an empty line after a decorated stub class
 
 614         if self.previous_line.depth < current_line.depth and (
 
 615             self.previous_line.is_class or self.previous_line.is_def
 
 619         comment_to_add_newlines: Optional[LinesBlock] = None
 
 621             self.previous_line.is_comment
 
 622             and self.previous_line.depth == current_line.depth
 
 625             slc = self.semantic_leading_comment
 
 628                 and slc.previous_block is not None
 
 629                 and not slc.previous_block.original_line.is_class
 
 630                 and not slc.previous_block.original_line.opens_block
 
 633                 comment_to_add_newlines = slc
 
 638             if current_line.is_class or self.previous_line.is_class:
 
 639                 if self.previous_line.depth < current_line.depth:
 
 641                 elif self.previous_line.depth > current_line.depth:
 
 643                 elif current_line.is_stub_class and self.previous_line.is_stub_class:
 
 644                     # No blank line between classes with an empty body
 
 649                 current_line.is_def or current_line.is_decorator
 
 650             ) and not self.previous_line.is_def:
 
 651                 if current_line.depth:
 
 652                     # In classes empty lines between attributes and methods should
 
 654                     newlines = min(1, before)
 
 656                     # Blank line between a block of functions (maybe with preceding
 
 657                     # decorators) and a block of non-functions
 
 659             elif self.previous_line.depth > current_line.depth:
 
 664             newlines = 1 if current_line.depth else 2
 
 665         if comment_to_add_newlines is not None:
 
 666             previous_block = comment_to_add_newlines.previous_block
 
 667             if previous_block is not None:
 
 668                 comment_to_add_newlines.before = (
 
 669                     max(comment_to_add_newlines.before, newlines) - previous_block.after
 
 675 def enumerate_reversed(sequence: Sequence[T]) -> Iterator[Tuple[Index, T]]:
 
 676     """Like `reversed(enumerate(sequence))` if that were possible."""
 
 677     index = len(sequence) - 1
 
 678     for element in reversed(sequence):
 
 679         yield (index, element)
 
 684     new_line: Line, old_line: Line, leaves: List[Leaf], preformatted: bool = False
 
 687     Append leaves (taken from @old_line) to @new_line, making sure to fix the
 
 688     underlying Node structure where appropriate.
 
 690     All of the leaves in @leaves are duplicated. The duplicates are then
 
 691     appended to @new_line and used to replace their originals in the underlying
 
 692     Node structure. Any comments attached to the old leaves are reattached to
 
 696         set(@leaves) is a subset of set(@old_line.leaves).
 
 698     for old_leaf in leaves:
 
 699         new_leaf = Leaf(old_leaf.type, old_leaf.value)
 
 700         replace_child(old_leaf, new_leaf)
 
 701         new_line.append(new_leaf, preformatted=preformatted)
 
 703         for comment_leaf in old_line.comments_after(old_leaf):
 
 704             new_line.append(comment_leaf, preformatted=True)
 
 707 def is_line_short_enough(  # noqa: C901
 
 708     line: Line, *, mode: Mode, line_str: str = ""
 
 710     """For non-multiline strings, return True if `line` is no longer than `line_length`.
 
 711     For multiline strings, looks at the context around `line` to determine
 
 712     if it should be inlined or split up.
 
 713     Uses the provided `line_str` rendering, if any, otherwise computes a new one.
 
 716         line_str = line_to_string(line)
 
 718     if Preview.multiline_string_handling not in mode:
 
 720             len(line_str) <= mode.line_length
 
 721             and "\n" not in line_str  # multiline strings
 
 722             and not line.contains_standalone_comments()
 
 725     if line.contains_standalone_comments():
 
 727     if "\n" not in line_str:
 
 728         # No multiline strings (MLS) present
 
 729         return len(line_str) <= mode.line_length
 
 731     first, *_, last = line_str.split("\n")
 
 732     if len(first) > mode.line_length or len(last) > mode.line_length:
 
 735     # Traverse the AST to examine the context of the multiline string (MLS),
 
 736     # tracking aspects such as depth and comma existence,
 
 737     # to determine whether to split the MLS or keep it together.
 
 738     # Depth (which is based on the existing bracket_depth concept)
 
 739     # is needed to determine nesting level of the MLS.
 
 740     # Includes special case for trailing commas.
 
 741     commas: List[int] = []  # tracks number of commas per depth level
 
 742     multiline_string: Optional[Leaf] = None
 
 743     # store the leaves that contain parts of the MLS
 
 744     multiline_string_contexts: List[LN] = []
 
 746     max_level_to_update = math.inf  # track the depth of the MLS
 
 747     for i, leaf in enumerate(line.leaves):
 
 748         if max_level_to_update == math.inf:
 
 749             had_comma: Optional[int] = None
 
 750             if leaf.bracket_depth + 1 > len(commas):
 
 752             elif leaf.bracket_depth + 1 < len(commas):
 
 753                 had_comma = commas.pop()
 
 755                 had_comma is not None
 
 756                 and multiline_string is not None
 
 757                 and multiline_string.bracket_depth == leaf.bracket_depth + 1
 
 759                 # Have left the level with the MLS, stop tracking commas
 
 760                 max_level_to_update = leaf.bracket_depth
 
 762                     # MLS was in parens with at least one comma - force split
 
 765         if leaf.bracket_depth <= max_level_to_update and leaf.type == token.COMMA:
 
 766             # Ignore non-nested trailing comma
 
 767             # directly after MLS/MLS-containing expression
 
 768             ignore_ctxs: List[Optional[LN]] = [None]
 
 769             ignore_ctxs += multiline_string_contexts
 
 770             if not (leaf.prev_sibling in ignore_ctxs and i == len(line.leaves) - 1):
 
 771                 commas[leaf.bracket_depth] += 1
 
 772         if max_level_to_update != math.inf:
 
 773             max_level_to_update = min(max_level_to_update, leaf.bracket_depth)
 
 775         if is_multiline_string(leaf):
 
 776             if len(multiline_string_contexts) > 0:
 
 777                 # >1 multiline string cannot fit on a single line - force split
 
 779             multiline_string = leaf
 
 781             # fetch the leaf components of the MLS in the AST
 
 782             while str(ctx) in line_str:
 
 783                 multiline_string_contexts.append(ctx)
 
 784                 if ctx.parent is None:
 
 788     # May not have a triple-quoted multiline string at all,
 
 789     # in case of a regular string with embedded newlines and line continuations
 
 790     if len(multiline_string_contexts) == 0:
 
 793     return all(val == 0 for val in commas)
 
 796 def can_be_split(line: Line) -> bool:
 
 797     """Return False if the line cannot be split *for sure*.
 
 799     This is not an exhaustive search but a cheap heuristic that we can use to
 
 800     avoid some unfortunate formattings (mostly around wrapping unsplittable code
 
 801     in unnecessary parentheses).
 
 807     if leaves[0].type == token.STRING and leaves[1].type == token.DOT:
 
 811         for leaf in leaves[-2::-1]:
 
 812             if leaf.type in OPENING_BRACKETS:
 
 813                 if next.type not in CLOSING_BRACKETS:
 
 817             elif leaf.type == token.DOT:
 
 819             elif leaf.type == token.NAME:
 
 820                 if not (next.type == token.DOT or next.type in OPENING_BRACKETS):
 
 823             elif leaf.type not in CLOSING_BRACKETS:
 
 826             if dot_count > 1 and call_count > 1:
 
 832 def can_omit_invisible_parens(
 
 836     """Does `line` have a shape safe to reformat without optional parens around it?
 
 838     Returns True for only a subset of potentially nice looking formattings but
 
 839     the point is to not return false positives that end up producing lines that
 
 842     bt = line.bracket_tracker
 
 843     if not bt.delimiters:
 
 844         # Without delimiters the optional parentheses are useless.
 
 847     max_priority = bt.max_delimiter_priority()
 
 848     if bt.delimiter_count_with_priority(max_priority) > 1:
 
 849         # With more than one delimiter of a kind the optional parentheses read better.
 
 852     if max_priority == DOT_PRIORITY:
 
 853         # A single stranded method call doesn't require optional parentheses.
 
 856     assert len(line.leaves) >= 2, "Stranded delimiter"
 
 858     # With a single delimiter, omit if the expression starts or ends with
 
 860     first = line.leaves[0]
 
 861     second = line.leaves[1]
 
 862     if first.type in OPENING_BRACKETS and second.type not in CLOSING_BRACKETS:
 
 863         if _can_omit_opening_paren(line, first=first, line_length=line_length):
 
 866         # Note: we are not returning False here because a line might have *both*
 
 867         # a leading opening bracket and a trailing closing bracket.  If the
 
 868         # opening bracket doesn't match our rule, maybe the closing will.
 
 870     penultimate = line.leaves[-2]
 
 871     last = line.leaves[-1]
 
 874         last.type == token.RPAR
 
 875         or last.type == token.RBRACE
 
 877             # don't use indexing for omitting optional parentheses;
 
 879             last.type == token.RSQB
 
 881             and last.parent.type != syms.trailer
 
 884         if penultimate.type in OPENING_BRACKETS:
 
 885             # Empty brackets don't help.
 
 888         if is_multiline_string(first):
 
 889             # Additional wrapping of a multiline string in this situation is
 
 893         if _can_omit_closing_paren(line, last=last, line_length=line_length):
 
 899 def _can_omit_opening_paren(line: Line, *, first: Leaf, line_length: int) -> bool:
 
 900     """See `can_omit_invisible_parens`."""
 
 902     length = 4 * line.depth
 
 904     for _index, leaf, leaf_length in line.enumerate_with_length():
 
 905         if leaf.type in CLOSING_BRACKETS and leaf.opening_bracket is first:
 
 908             length += leaf_length
 
 909             if length > line_length:
 
 912             if leaf.type in OPENING_BRACKETS:
 
 913                 # There are brackets we can further split on.
 
 917         # checked the entire string and line length wasn't exceeded
 
 918         if len(line.leaves) == _index + 1:
 
 924 def _can_omit_closing_paren(line: Line, *, last: Leaf, line_length: int) -> bool:
 
 925     """See `can_omit_invisible_parens`."""
 
 926     length = 4 * line.depth
 
 927     seen_other_brackets = False
 
 928     for _index, leaf, leaf_length in line.enumerate_with_length():
 
 929         length += leaf_length
 
 930         if leaf is last.opening_bracket:
 
 931             if seen_other_brackets or length <= line_length:
 
 934         elif leaf.type in OPENING_BRACKETS:
 
 935             # There are brackets we can further split on.
 
 936             seen_other_brackets = True
 
 941 def line_to_string(line: Line) -> str:
 
 942     """Returns the string representation of @line.
 
 944     WARNING: This is known to be computationally expensive.
 
 946     return str(line).strip("\n")