Make existing optional parentheses invisible or create new ones. `parens_after` is a set of string leaf values immediately after which parens should be put. Standardizes on visible parentheses for single-element tuples, and keeps existing visible parentheses for other tuples and ge
(
node: Node, parens_after: set[str], *, mode: Mode, features: Collection[Feature]
)
| 1488 | |
| 1489 | |
| 1490 | def normalize_invisible_parens( |
| 1491 | node: Node, parens_after: set[str], *, mode: Mode, features: Collection[Feature] |
| 1492 | ) -> None: |
| 1493 | """Make existing optional parentheses invisible or create new ones. |
| 1494 | |
| 1495 | `parens_after` is a set of string leaf values immediately after which parens |
| 1496 | should be put. |
| 1497 | |
| 1498 | Standardizes on visible parentheses for single-element tuples, and keeps |
| 1499 | existing visible parentheses for other tuples and generator expressions. |
| 1500 | """ |
| 1501 | for pc in list_comments(node.prefix, is_endmarker=False, mode=mode): |
| 1502 | if contains_fmt_directive(pc.value, FMT_OFF): |
| 1503 | # This `node` has a prefix with `# fmt: off`, don't mess with parens. |
| 1504 | return |
| 1505 | |
| 1506 | # The multiple context managers grammar has a different pattern, thus this is |
| 1507 | # separate from the for-loop below. This possibly wraps them in invisible parens, |
| 1508 | # and later will be removed in remove_with_parens when needed. |
| 1509 | if node.type == syms.with_stmt: |
| 1510 | _maybe_wrap_cms_in_parens(node, mode, features) |
| 1511 | |
| 1512 | check_lpar = False |
| 1513 | for index, child in enumerate(list(node.children)): |
| 1514 | # Fixes a bug where invisible parens are not properly stripped from |
| 1515 | # assignment statements that contain type annotations. |
| 1516 | if isinstance(child, Node) and child.type == syms.annassign: |
| 1517 | normalize_invisible_parens( |
| 1518 | child, parens_after=parens_after, mode=mode, features=features |
| 1519 | ) |
| 1520 | |
| 1521 | # Fixes a bug where invisible parens are not properly wrapped around |
| 1522 | # case blocks. |
| 1523 | if isinstance(child, Node) and child.type == syms.case_block: |
| 1524 | normalize_invisible_parens( |
| 1525 | child, parens_after={"case"}, mode=mode, features=features |
| 1526 | ) |
| 1527 | |
| 1528 | # Add parentheses around if guards in case blocks |
| 1529 | if isinstance(child, Node) and child.type == syms.guard: |
| 1530 | normalize_invisible_parens( |
| 1531 | child, parens_after={"if"}, mode=mode, features=features |
| 1532 | ) |
| 1533 | |
| 1534 | # Add parentheses around long tuple unpacking in assignments. |
| 1535 | if ( |
| 1536 | index == 0 |
| 1537 | and isinstance(child, Node) |
| 1538 | and child.type == syms.testlist_star_expr |
| 1539 | ): |
| 1540 | check_lpar = True |
| 1541 | |
| 1542 | if ( |
| 1543 | index == 0 |
| 1544 | and isinstance(child, Node) |
| 1545 | and child.type == syms.atom |
| 1546 | and node.type == syms.expr_stmt |
| 1547 | and not _atom_has_magic_trailing_comma(child, mode) |
no test coverage detected