From 029da1ffbcbd3b5c099454499793c45aa26a60cf Mon Sep 17 00:00:00 2001 From: MeGaGiGaGon <107241144+megagigagon@users.noreply.github.com> Date: Mon, 23 Dec 2024 12:35:14 -0800 Subject: [PATCH 1/4] fix 3678 and add tests --- src/black/linegen.py | 4 ++++ src/black/nodes.py | 20 ++++++++++++++++++ tests/data/cases/remove_with_brackets.py | 26 ++++++++++++++++++++++++ 3 files changed, 50 insertions(+) diff --git a/src/black/linegen.py b/src/black/linegen.py index 7bd018d31af..6bd2e5cf171 100644 --- a/src/black/linegen.py +++ b/src/black/linegen.py @@ -45,6 +45,7 @@ is_atom_with_invisible_parens, is_docstring, is_empty_tuple, + is_generator, is_lpar_token, is_multiline_string, is_name_token, @@ -55,6 +56,7 @@ is_rpar_token, is_stub_body, is_stub_suite, + is_tuple_containing_star, is_tuple_containing_walrus, is_type_ignore_comment_string, is_vararg, @@ -1628,6 +1630,8 @@ def maybe_make_parens_invisible_in_atom( and max_delimiter_priority_in_atom(node) >= COMMA_PRIORITY ) or is_tuple_containing_walrus(node) + or is_tuple_containing_star(node) + or is_generator(node) ): return False diff --git a/src/black/nodes.py b/src/black/nodes.py index 927b9ee60d1..8c4b6f33556 100644 --- a/src/black/nodes.py +++ b/src/black/nodes.py @@ -621,6 +621,26 @@ def is_tuple_containing_walrus(node: LN) -> bool: return any(child.type == syms.namedexpr_test for child in gexp.children) +def is_tuple_containing_star(node: LN) -> bool: + """Return True if `node` holds a tuple that contains a star operator.""" + if node.type != syms.atom: + return False + gexp = unwrap_singleton_parenthesis(node) + if gexp is None or gexp.type != syms.testlist_gexp: + return False + return any(child.type == syms.star_expr for child in gexp.children) + + +def is_generator(node: LN) -> bool: + """Return True if `node` holds a generator.""" + if node.type != syms.atom: + return False + gexp = unwrap_singleton_parenthesis(node) + if gexp is None or gexp.type != syms.testlist_gexp: + return False + return any(child.type == syms.old_comp_for for child in gexp.children) + + def is_one_sequence_between( opening: Leaf, closing: Leaf, diff --git a/tests/data/cases/remove_with_brackets.py b/tests/data/cases/remove_with_brackets.py index ea58ab93a16..f2319e0da84 100644 --- a/tests/data/cases/remove_with_brackets.py +++ b/tests/data/cases/remove_with_brackets.py @@ -53,6 +53,19 @@ with ((((CtxManager1()))) as example1, (((CtxManager2()))) as example2): ... +# regression tests for #3678 +with (a, *b): + pass + +with (a, (b, *c)): + pass + +with (a for b in c): + pass + +with (a, (b for c in d)): + pass + # output with open("bla.txt"): pass @@ -117,3 +130,16 @@ with CtxManager1() as example1, CtxManager2() as example2: ... + +# regression tests for #3678 +with (a, *b): + pass + +with a, (b, *c): + pass + +with (a for b in c): + pass + +with a, (b for c in d): + pass From 5ce8749c17e833b368908ce57f372d13dc07e154 Mon Sep 17 00:00:00 2001 From: MeGaGiGaGon <107241144+megagigagon@users.noreply.github.com> Date: Mon, 23 Dec 2024 12:43:25 -0800 Subject: [PATCH 2/4] add changelog entry --- CHANGES.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index c1e6320740d..bd49b06b4bf 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -13,6 +13,9 @@ - Fix formatting cells in IPython notebooks with magic methods and starting or trailing empty lines (#4484) +- Fix crash when formatting `with` statements containing tuple genetators/unpacking + (#4538) + ### Preview style From 67a6471ff8a7e6aa4cb730eb196f5d0dc8b118d9 Mon Sep 17 00:00:00 2001 From: MeGaGiGaGon <107241144+megagigagon@users.noreply.github.com> Date: Mon, 23 Dec 2024 13:11:59 -0800 Subject: [PATCH 3/4] fix optional newline inconsistency --- src/black/nodes.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/black/nodes.py b/src/black/nodes.py index 8c4b6f33556..f3688cd4f1b 100644 --- a/src/black/nodes.py +++ b/src/black/nodes.py @@ -628,6 +628,7 @@ def is_tuple_containing_star(node: LN) -> bool: gexp = unwrap_singleton_parenthesis(node) if gexp is None or gexp.type != syms.testlist_gexp: return False + return any(child.type == syms.star_expr for child in gexp.children) @@ -638,6 +639,7 @@ def is_generator(node: LN) -> bool: gexp = unwrap_singleton_parenthesis(node) if gexp is None or gexp.type != syms.testlist_gexp: return False + return any(child.type == syms.old_comp_for for child in gexp.children) From 271e0d9d7f4eef2a00bbc322eccfed7c00e1ef64 Mon Sep 17 00:00:00 2001 From: GiGaGon <107241144+MeGaGiGaGon@users.noreply.github.com> Date: Mon, 23 Dec 2024 13:13:51 -0800 Subject: [PATCH 4/4] Fix typo in CHANGES.md --- CHANGES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index bd49b06b4bf..d2955d2df0a 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -13,7 +13,7 @@ - Fix formatting cells in IPython notebooks with magic methods and starting or trailing empty lines (#4484) -- Fix crash when formatting `with` statements containing tuple genetators/unpacking +- Fix crash when formatting `with` statements containing tuple generators/unpacking (#4538) ### Preview style