From 522f1532d128f8c4d33ade0f9e0791d738aa1e31 Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Fri, 27 Oct 2023 22:31:11 -0700 Subject: [PATCH 1/3] Fix crash on await (a ** b) --- CHANGES.md | 2 ++ src/black/linegen.py | 20 ++++++++++++-------- tests/data/cases/remove_await_parens.py | 21 +++++++++++++++++++++ 3 files changed, 35 insertions(+), 8 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 60231468bdf..5bcd623da86 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -10,6 +10,8 @@ +- Fix crash on formatting code like `await (a ** b)` (#3994) + ### Preview style - Multiline dictionaries and lists that are the sole argument to a function are now diff --git a/src/black/linegen.py b/src/black/linegen.py index 5f5a69152d5..c2ca2c75817 100644 --- a/src/black/linegen.py +++ b/src/black/linegen.py @@ -1354,14 +1354,18 @@ def remove_await_parens(node: Node) -> None: if bracket_contents.type != syms.power: ensure_visible(opening_bracket) ensure_visible(closing_bracket) - elif ( - bracket_contents.type == syms.power - and bracket_contents.children[0].type == token.AWAIT - ): - ensure_visible(opening_bracket) - ensure_visible(closing_bracket) - # If we are in a nested await then recurse down. - remove_await_parens(bracket_contents) + elif bracket_contents.type == syms.power: + if bracket_contents.children[0].type == token.AWAIT: + ensure_visible(opening_bracket) + ensure_visible(closing_bracket) + # If we are in a nested await then recurse down. + remove_await_parens(bracket_contents) + elif ( + len(bracket_contents.children) == 3 + and bracket_contents.children[1].type == token.DOUBLESTAR + ): + ensure_visible(opening_bracket) + ensure_visible(closing_bracket) def _maybe_wrap_cms_in_parens( diff --git a/tests/data/cases/remove_await_parens.py b/tests/data/cases/remove_await_parens.py index 8c7223d2f39..1496f6e2de8 100644 --- a/tests/data/cases/remove_await_parens.py +++ b/tests/data/cases/remove_await_parens.py @@ -80,6 +80,15 @@ async def main(): async def main(): await (yield) +async def main(): + await (a ** b) + +async def main(): + await (a + b) + +async def main(): + await (a[b]) + # output import asyncio @@ -174,3 +183,15 @@ async def main(): async def main(): await (yield) + + +async def main(): + await (a**b) + + +async def main(): + await (a + b) + + +async def main(): + await a[b] From c0667002bc7d7df1f69247c287853ebb80ec3f3d Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Sat, 28 Oct 2023 15:45:02 -0700 Subject: [PATCH 2/3] Handle more cases --- src/black/linegen.py | 6 +++--- tests/data/cases/remove_await_parens.py | 18 ++++++++---------- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/src/black/linegen.py b/src/black/linegen.py index c2ca2c75817..8fb668af135 100644 --- a/src/black/linegen.py +++ b/src/black/linegen.py @@ -1360,9 +1360,9 @@ def remove_await_parens(node: Node) -> None: ensure_visible(closing_bracket) # If we are in a nested await then recurse down. remove_await_parens(bracket_contents) - elif ( - len(bracket_contents.children) == 3 - and bracket_contents.children[1].type == token.DOUBLESTAR + elif any( + isinstance(child, Leaf) and child.type == token.DOUBLESTAR + for child in bracket_contents.children ): ensure_visible(opening_bracket) ensure_visible(closing_bracket) diff --git a/tests/data/cases/remove_await_parens.py b/tests/data/cases/remove_await_parens.py index 1496f6e2de8..073150c5f08 100644 --- a/tests/data/cases/remove_await_parens.py +++ b/tests/data/cases/remove_await_parens.py @@ -82,12 +82,12 @@ async def main(): async def main(): await (a ** b) - -async def main(): + await (a[b] ** c) + await (a ** b[c]) + await ((a + b) ** (c + d)) await (a + b) - -async def main(): await (a[b]) + await (a[b ** c]) # output import asyncio @@ -187,11 +187,9 @@ async def main(): async def main(): await (a**b) - - -async def main(): + await (a[b] ** c) + await (a ** b[c]) + await ((a + b) ** (c + d)) await (a + b) - - -async def main(): await a[b] + await a[b**c] From 42a40c7d5ecac9d90d5dda982a8cf605b2adfb8a Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Thu, 2 Nov 2023 20:25:37 -0700 Subject: [PATCH 3/3] simplify --- src/black/linegen.py | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/src/black/linegen.py b/src/black/linegen.py index 8fb668af135..18d85a2c216 100644 --- a/src/black/linegen.py +++ b/src/black/linegen.py @@ -1350,22 +1350,16 @@ def remove_await_parens(node: Node) -> None: opening_bracket = cast(Leaf, node.children[1].children[0]) closing_bracket = cast(Leaf, node.children[1].children[-1]) bracket_contents = node.children[1].children[1] - if isinstance(bracket_contents, Node): - if bracket_contents.type != syms.power: - ensure_visible(opening_bracket) - ensure_visible(closing_bracket) - elif bracket_contents.type == syms.power: - if bracket_contents.children[0].type == token.AWAIT: - ensure_visible(opening_bracket) - ensure_visible(closing_bracket) - # If we are in a nested await then recurse down. - remove_await_parens(bracket_contents) - elif any( - isinstance(child, Leaf) and child.type == token.DOUBLESTAR - for child in bracket_contents.children - ): - ensure_visible(opening_bracket) - ensure_visible(closing_bracket) + if isinstance(bracket_contents, Node) and ( + bracket_contents.type != syms.power + or bracket_contents.children[0].type == token.AWAIT + or any( + isinstance(child, Leaf) and child.type == token.DOUBLESTAR + for child in bracket_contents.children + ) + ): + ensure_visible(opening_bracket) + ensure_visible(closing_bracket) def _maybe_wrap_cms_in_parens(