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

Code before:
                    preview=preview,
                ):
                    wrap_in_parentheses(child, child.children[0], visible=False)
            elif is_one_tuple(child):
                wrap_in_parentheses(node, child, visible=True)
            elif node.type == syms.import_from:
                # "import from" nodes store parentheses directly as part of
                # the statement
                if is_lpar_token(child):
                    assert is_rpar_token(node.children[-1])
                    # make parentheses invisible
                    child.value = ""
                    node.children[-1].value = ""
                elif child.type != token.STAR:
                    # insert invisible parentheses
                    node.insert_child(index, Leaf(token.LPAR, ""))
                    node.append_child(Leaf(token.RPAR, ""))
                break

            elif not (isinstance(child, Leaf) and is_multiline_string(child)):
                wrap_in_parentheses(node, child, visible=False)

        comma_check = child.type == token.COMMA if preview else False

        check_lpar = (
            isinstance(child, Leaf) and child.value in parens_after or comma_check
        )


def maybe_make_parens_invisible_in_atom(
    node: LN,
    parent: LN,
    preview: bool = False,
) -> bool:
    """If it's safe, make the parens in the atom `node` invisible, recursively.
    Additionally, remove repeated, adjacent invisible parens from the atom `node`
    as they are redundant.

    Returns whether the node should itself be wrapped in invisible parentheses.

    `preview` enables the preview feature for removing redundant parentheses.
    """
    with_stmt_check = parent.type != syms.with_stmt if preview else True

    if (
        node.type != syms.atom
        or is_empty_tuple(node)
        or is_one_tuple(node)
        or (is_yield(node) and parent.type != syms.expr_stmt)
        or (max_delimiter_priority_in_atom(node) >= COMMA_PRIORITY and with_stmt_check)
    ):

Review comment (suggestion):
```suggestion
            child.value in parens_after if isinstance(child, Leaf) else comma_check
```

Code after:
                    parent=node,
                    remove_brackets_around_comma=True,
                ):
                    wrap_in_parentheses(node, child, visible=False)
            elif preview and isinstance(child, Node) and node.type == syms.with_stmt:
                remove_with_parens(child, node)
            elif child.type == syms.atom:
                if maybe_make_parens_invisible_in_atom(
                    child,
                    parent=node,
                ):
                    wrap_in_parentheses(node, child, visible=False)
            elif is_one_tuple(child):
                wrap_in_parentheses(node, child, visible=True)
            elif node.type == syms.import_from:
                # "import from" nodes store parentheses directly as part of
                # the statement
                if is_lpar_token(child):
                    assert is_rpar_token(node.children[-1])
                    # make parentheses invisible
                    child.value = ""
                    node.children[-1].value = ""
                elif child.type != token.STAR:
                    # insert invisible parentheses
                    node.insert_child(index, Leaf(token.LPAR, ""))
                    node.append_child(Leaf(token.RPAR, ""))
                break

            elif not (isinstance(child, Leaf) and is_multiline_string(child)):
                wrap_in_parentheses(node, child, visible=False)

        comma_check = child.type == token.COMMA if preview else False

        check_lpar = isinstance(child, Leaf) and (
            child.value in parens_after or comma_check
        )


def remove_with_parens(node: Node, parent: Node) -> None:
    """Recursively hide optional parens in `with` statements."""
    # Removing all unnecessary parentheses in with statements in one pass is a tad
    # complex as different variations of bracketed statements result in pretty
    # different parse trees:
    #
    # with (open("file")) as f:                       # this is an asexpr_test
    #     ...
    #
    # with (open("file") as f):                       # this is an atom containing an
    #     ...                                         # asexpr_test
    #
    # with (open("file")) as f, (open("file")) as f:  # this is asexpr_test, COMMA,