def maybe_make_parens_invisible_in_atom( node: LN, parent: LN, remove_brackets_around_comma: 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. """ 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 ( # This condition tries to prevent removing non-optional brackets # around a tuple, however, can be a bit overzealous so we provide # and option to skip this check for `for` and `with` statements. not remove_brackets_around_comma and max_delimiter_priority_in_atom(node) >= COMMA_PRIORITY ) ): return False if is_walrus_assignment(node): if parent.type in [ syms.annassign, syms.expr_stmt, syms.assert_stmt, syms.return_stmt, # these ones aren't useful to end users, but they do please fuzzers syms.for_stmt, syms.del_stmt, ]: return False first = node.children[0] last = node.children[-1] if is_lpar_token(first) and is_rpar_token(last): middle = node.children[1] # make parentheses invisible first.value = "" last.value = "" maybe_make_parens_invisible_in_atom( middle, parent=parent, remove_brackets_around_comma=remove_brackets_around_comma, ) if is_atom_with_invisible_parens(middle): # Strip the invisible parens from `middle` by replacing # it with the child in-between the invisible parens middle.replace(middle.children[1]) return False return True
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. """ if (preview and parent.type == syms.for_stmt and isinstance(node.prev_sibling, Leaf) and node.prev_sibling.type == token.NAME and node.prev_sibling.value == "for"): for_stmt_check = False else: for_stmt_check = 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 for_stmt_check)): return False if is_walrus_assignment(node): if parent.type in [ syms.annassign, syms.expr_stmt, syms.assert_stmt, syms.return_stmt, # these ones aren't useful to end users, but they do please fuzzers syms.for_stmt, syms.del_stmt, ]: return False first = node.children[0] last = node.children[-1] if is_lpar_token(first) and is_rpar_token(last): middle = node.children[1] # make parentheses invisible first.value = "" last.value = "" maybe_make_parens_invisible_in_atom(middle, parent=parent, preview=preview) if is_atom_with_invisible_parens(middle): # Strip the invisible parens from `middle` by replacing # it with the child in-between the invisible parens middle.replace(middle.children[1]) return False return True
def maybe_make_parens_invisible_in_atom(node: LN, parent: LN) -> 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. """ 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 ): return False if is_walrus_assignment(node): if parent.type in [ syms.annassign, syms.expr_stmt, syms.assert_stmt, syms.return_stmt, # these ones aren't useful to end users, but they do please fuzzers syms.for_stmt, syms.del_stmt, ]: return False first = node.children[0] last = node.children[-1] if first.type == token.LPAR and last.type == token.RPAR: middle = node.children[1] # make parentheses invisible first.value = "" # type: ignore last.value = "" # type: ignore maybe_make_parens_invisible_in_atom(middle, parent=parent) if is_atom_with_invisible_parens(middle): # Strip the invisible parens from `middle` by replacing # it with the child in-between the invisible parens middle.replace(middle.children[1]) return False return True