From d3fc67f96989de6505b52e1180e64d971826b68a Mon Sep 17 00:00:00 2001 From: cobalt <61329810+cobaltt7@users.noreply.github.com> Date: Wed, 5 Nov 2025 18:08:30 -0600 Subject: [PATCH 1/3] Fix `fix_fmt_skip_in_one_liners` crashing on `with` statements Signed-off-by: cobalt <61329810+cobaltt7@users.noreply.github.com> --- CHANGES.md | 2 ++ src/black/comments.py | 16 ++++++++++++++-- tests/data/cases/fmtskip12.py | 21 +++++++++++++++++++++ 3 files changed, 37 insertions(+), 2 deletions(-) create mode 100644 tests/data/cases/fmtskip12.py diff --git a/CHANGES.md b/CHANGES.md index 7664570425e..c9ca2df1350 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -22,6 +22,8 @@ +- Fix `fix_fmt_skip_in_one_liners` crashing on `with` statements (#) + ### Configuration diff --git a/src/black/comments.py b/src/black/comments.py index 13c9926d03b..039f862554b 100644 --- a/src/black/comments.py +++ b/src/black/comments.py @@ -650,10 +650,22 @@ def _generate_ignored_nodes_from_fmt_skip( current_node.prefix = "" break + # Special case for with expressions + # Without this, we can stuck inside the asexpr_test's children's children + parent = current_node.parent + if ( + parent + and parent.type == syms.asexpr_test + and parent.parent + and parent.parent.type == syms.with_stmt + ): + current_node = parent + ignored_nodes.insert(0, current_node) - if current_node.prev_sibling is None and current_node.parent is not None: - current_node = current_node.parent + if current_node.prev_sibling is None and parent is not None: + current_node = parent + # Special handling for compound statements with semicolon-separated bodies if Preview.fix_fmt_skip_in_one_liners in mode and isinstance(parent, Node): body_node = _find_compound_statement_context(parent) diff --git a/tests/data/cases/fmtskip12.py b/tests/data/cases/fmtskip12.py new file mode 100644 index 00000000000..3af6b4443a1 --- /dev/null +++ b/tests/data/cases/fmtskip12.py @@ -0,0 +1,21 @@ +# flags: --preview + +with open("file.txt") as f: content = f.read() # fmt: skip + +# Ideally, only the last line would be ignored +# But ignoring only part of the asexpr_test causes a parse error +# Same with ignoring the asexpr_test without also ignoring the entire with_stmt +with open ( + "file.txt" , +) as f: content = f.read() # fmt: skip + +# output + +with open("file.txt") as f: content = f.read() # fmt: skip + +# Ideally, only the last line would be ignored +# But ignoring only part of the asexpr_test causes a parse error +# Same with ignoring the asexpr_test without also ignoring the entire with_stmt +with open ( + "file.txt" , +) as f: content = f.read() # fmt: skip From 07d8f531ec4729ac8ce1ef2d0229f8d264a90d17 Mon Sep 17 00:00:00 2001 From: cobalt <61329810+cobaltt7@users.noreply.github.com> Date: Fri, 21 Nov 2025 17:10:58 -0600 Subject: [PATCH 2/3] Apply suggestion from @cobaltt7 --- CHANGES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index c9ca2df1350..42158aa5e07 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -22,7 +22,7 @@ -- Fix `fix_fmt_skip_in_one_liners` crashing on `with` statements (#) +- Fix `fix_fmt_skip_in_one_liners` crashing on `with` statements (#4853) ### Configuration From 2116a45781a934dd8dd3eff3a3c75ee2f6659b6d Mon Sep 17 00:00:00 2001 From: cobalt <61329810+cobaltt7@users.noreply.github.com> Date: Fri, 21 Nov 2025 17:23:43 -0600 Subject: [PATCH 3/3] Remove reassignment Signed-off-by: cobalt <61329810+cobaltt7@users.noreply.github.com> --- src/black/comments.py | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/black/comments.py b/src/black/comments.py index 039f862554b..de1831e4d7c 100644 --- a/src/black/comments.py +++ b/src/black/comments.py @@ -652,19 +652,18 @@ def _generate_ignored_nodes_from_fmt_skip( # Special case for with expressions # Without this, we can stuck inside the asexpr_test's children's children - parent = current_node.parent if ( - parent - and parent.type == syms.asexpr_test - and parent.parent - and parent.parent.type == syms.with_stmt + current_node.parent + and current_node.parent.type == syms.asexpr_test + and current_node.parent.parent + and current_node.parent.parent.type == syms.with_stmt ): - current_node = parent + current_node = current_node.parent ignored_nodes.insert(0, current_node) - if current_node.prev_sibling is None and parent is not None: - current_node = parent + if current_node.prev_sibling is None and current_node.parent is not None: + current_node = current_node.parent # Special handling for compound statements with semicolon-separated bodies if Preview.fix_fmt_skip_in_one_liners in mode and isinstance(parent, Node):