Repository: psf/black
File: src/black/linegen.py (Python)

Code before:


def bracket_split_succeeded_or_raise(head: Line, body: Line, tail: Line) -> None:
    """Raise :exc:`CannotSplit` if the last left- or right-hand split failed.

    Do nothing otherwise.

    A left- or right-hand split is based on a pair of brackets. Content before
    (and including) the opening bracket is left on one line, content inside the
    brackets is put on a separate line, and finally content starting with and
    following the closing bracket is put on a separate line.

    Those are called `head`, `body`, and `tail`, respectively. If the split
    produced the same line (all content in `head`) or ended up with an empty `body`
    and the `tail` is just the closing bracket, then it's considered failed.
    """
    tail_len = len(str(tail).strip())
    if not body:
        if tail_len == 0:
            raise CannotSplit("Splitting brackets produced the same line")

        elif tail_len < 3:
            raise CannotSplit(
                f"Splitting brackets on an empty body to save {tail_len} characters is"
                " not worth it"
            )


def bracket_split_build_line(
    leaves: List[Leaf],
    original: Line,
    opening_bracket: Leaf,
    *,
    component: _BracketSplitComponent,
) -> Line:
    """Return a new line with given `leaves` and respective comments from `original`.

    If it's the head component, brackets will be tracked so trailing commas are
    respected.

    If it's the body component, the result line is one-indented inside brackets and as
    such has its first leaf's prefix normalized and a trailing comma added when
    expected.
    """
    result = Line(mode=original.mode, depth=original.depth)
    if component is _BracketSplitComponent.body:
        result.inside_brackets = True
        result.depth += 1
        if leaves:
            # Ensure a trailing comma for imports and standalone function arguments, but
            # be careful not to add one after any comments or within type annotations.

Review comment (refactor):
Can we use `is_part_of_annotation` to simplify some of the logic in the next check too? Lines 1092-1099?

Code after:
    component: _BracketSplitComponent,
) -> Line:
    """Return a new line with given `leaves` and respective comments from `original`.

    If it's the head component, brackets will be tracked so trailing commas are
    respected.

    If it's the body component, the result line is one-indented inside brackets and as
    such has its first leaf's prefix normalized and a trailing comma added when
    expected.
    """
    result = Line(mode=original.mode, depth=original.depth)
    if component is _BracketSplitComponent.body:
        result.inside_brackets = True
        result.depth += 1
        if leaves:
            # Ensure a trailing comma for imports and standalone function arguments, but
            # be careful not to add one after any comments or within type annotations.
            no_commas = (
                original.is_def
                and opening_bracket.value == "("
                and not any(
                    leaf.type == token.COMMA
                    and (
                        Preview.typed_params_trailing_comma not in original.mode
                        or not is_part_of_annotation(leaf)
                    )
                    for leaf in leaves
                )
                # In particular, don't add one within a parenthesized return annotation.
                # Unfortunately the indicator we're in a return annotation (RARROW) may
                # be defined directly in the parent node, the parent of the parent ...
                # and so on depending on how complex the return annotation is.
                # This isn't perfect and there's some false negatives but they are in
                # contexts were a comma is actually fine.
                and not any(
                    node.prev_sibling.type == RARROW
                    for node in (
                        leaves[0].parent,
                        getattr(leaves[0].parent, "parent", None),
                    )
                    if isinstance(node, Node) and isinstance(node.prev_sibling, Leaf)
                )
                # Except the false negatives above for PEP 604 unions where we
                # can't add the comma.
                and not (
                    leaves[0].parent
                    and leaves[0].parent.next_sibling
                    and leaves[0].parent.next_sibling.type == token.VBAR
                )
            )