From 22796a5e8ebfc5bacd3c78cd958543dbdd927c4b Mon Sep 17 00:00:00 2001 From: cobalt <61329810+cobaltt7@users.noreply.github.com> Date: Fri, 21 Nov 2025 17:03:14 -0600 Subject: [PATCH 1/8] Fix `fmt: skip` skipping the line after instead of the line it's on (#3364, #4366) Signed-off-by: cobalt <61329810+cobaltt7@users.noreply.github.com> --- CHANGES.md | 1 + src/black/comments.py | 4 ++++ tests/data/cases/fmtskip11.py | 23 +++++++++++++++++++++++ 3 files changed, 28 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index 7664570425e..4fbe8a01a8f 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -17,6 +17,7 @@ - Fix bug where comments preceding `# fmt: off`/`# fmt: on` blocks were incorrectly removed, particularly affecting Jupytext's `# %% [markdown]` comments (#4845) +- Fix `fmt: skip` skipping the line after instead of the line it's on (#4821) ### Preview style diff --git a/src/black/comments.py b/src/black/comments.py index 13c9926d03b..1767116ae9e 100644 --- a/src/black/comments.py +++ b/src/black/comments.py @@ -605,6 +605,10 @@ def _generate_ignored_nodes_from_fmt_skip( comments = list_comments(leaf.prefix, is_endmarker=False, mode=mode) if not comments or comment.value != comments[0].value: return + + if not prev_sibling and parent and parent.prev_sibling: + prev_sibling = parent.prev_sibling + if prev_sibling is not None: leaf.prefix = leaf.prefix[comment.consumed :] diff --git a/tests/data/cases/fmtskip11.py b/tests/data/cases/fmtskip11.py index 5d3f7874e55..134664b5791 100644 --- a/tests/data/cases/fmtskip11.py +++ b/tests/data/cases/fmtskip11.py @@ -4,3 +4,26 @@ def foo(): # comment 1 # fmt: skip # comment 2 + +v = ( + foo_dict # fmt: skip + .setdefault("a", {}) + .setdefault("b", {}) + .setdefault("c", {}) + .setdefault("d", {}) + .setdefault("e", {}) +) + +t = ( + {"foo": "very long string", "bar": "another very long string", "baz": "we should run out of space by now"}, # fmt: skip + {"foo": "bar"}, +) + +t = ( + { + "foo": "very long string", + "bar": "another very long string", + "baz": "we should run out of space by now", + }, # fmt: skip + {"foo": "bar"}, +) From 11a1d31965f7c3e198e894fc8e697eade5811ff5 Mon Sep 17 00:00:00 2001 From: cobalt <61329810+cobaltt7@users.noreply.github.com> Date: Fri, 21 Nov 2025 17:11:22 -0600 Subject: [PATCH 2/8] Apply suggestion from @cobaltt7 --- CHANGES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index 4fbe8a01a8f..ebabb202a08 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -17,7 +17,7 @@ - Fix bug where comments preceding `# fmt: off`/`# fmt: on` blocks were incorrectly removed, particularly affecting Jupytext's `# %% [markdown]` comments (#4845) -- Fix `fmt: skip` skipping the line after instead of the line it's on (#4821) +- Fix `fmt: skip` skipping the line after instead of the line it's on (#4855) ### Preview style From dae380e69ceffd7d4da1be53e0d34efbce0a7fe4 Mon Sep 17 00:00:00 2001 From: cobalt <61329810+cobaltt7@users.noreply.github.com> Date: Fri, 21 Nov 2025 22:03:07 -0600 Subject: [PATCH 3/8] Add tests Signed-off-by: cobalt <61329810+cobaltt7@users.noreply.github.com> --- tests/data/cases/fmtskip10.py | 9 +++++ tests/data/cases/fmtskip11.py | 14 -------- tests/data/cases/fmtskip12.py | 62 +++++++++++++++++++++++++++++++++++ 3 files changed, 71 insertions(+), 14 deletions(-) create mode 100644 tests/data/cases/fmtskip12.py diff --git a/tests/data/cases/fmtskip10.py b/tests/data/cases/fmtskip10.py index ed7ffacd07c..2f3318a17a9 100644 --- a/tests/data/cases/fmtskip10.py +++ b/tests/data/cases/fmtskip10.py @@ -10,3 +10,12 @@ def foo(): return "mock" # fmt: skip while j < 10: j += 1 # fmt: skip b = [c for c in "A very long string that would normally generate some kind of collapse, since it is this long"] # fmt: skip + +t = ( + { + "foo":"very long string", + "bar":"another very long string", + "baz":"we should run out of space by now", + }, # fmt: skip + {"foo": "bar"}, +) diff --git a/tests/data/cases/fmtskip11.py b/tests/data/cases/fmtskip11.py index 134664b5791..a8a0e217e60 100644 --- a/tests/data/cases/fmtskip11.py +++ b/tests/data/cases/fmtskip11.py @@ -13,17 +13,3 @@ def foo(): .setdefault("d", {}) .setdefault("e", {}) ) - -t = ( - {"foo": "very long string", "bar": "another very long string", "baz": "we should run out of space by now"}, # fmt: skip - {"foo": "bar"}, -) - -t = ( - { - "foo": "very long string", - "bar": "another very long string", - "baz": "we should run out of space by now", - }, # fmt: skip - {"foo": "bar"}, -) diff --git a/tests/data/cases/fmtskip12.py b/tests/data/cases/fmtskip12.py new file mode 100644 index 00000000000..1f2d53437cb --- /dev/null +++ b/tests/data/cases/fmtskip12.py @@ -0,0 +1,62 @@ +t = ( + {"foo": "very long string", "bar": "another very long string", "baz": "we should run out of space by now"}, # fmt: skip + {"foo": "bar"}, +) + +t = ( + { + "foo": "very long string", + "bar": "another very long string", + "baz": "we should run out of space by now", + }, # fmt: skip + {"foo": "bar"}, +) + + +t = ( + {"foo": "very long string", "bar": "another very long string", "baz": "we should run out of space by now"}, # fmt: skip + {"foo": "bar",}, +) + +t = ( + { + "foo": "very long string", + "bar": "another very long string", + "baz": "we should run out of space by now", + }, # fmt: skip + {"foo": "bar",}, +) + +# output +t = ( + {"foo": "very long string", "bar": "another very long string", "baz": "we should run out of space by now"}, # fmt: skip + {"foo": "bar"}, +) + +t = ( + { + "foo": "very long string", + "bar": "another very long string", + "baz": "we should run out of space by now", + }, # fmt: skip + {"foo": "bar"}, +) + + +t = ( + {"foo": "very long string", "bar": "another very long string", "baz": "we should run out of space by now"}, # fmt: skip + { + "foo": "bar", + }, +) + +t = ( + { + "foo": "very long string", + "bar": "another very long string", + "baz": "we should run out of space by now", + }, # fmt: skip + { + "foo": "bar", + }, +) From 334073eafbd2909643b74815113906009c625d4d Mon Sep 17 00:00:00 2001 From: cobalt <61329810+cobaltt7@users.noreply.github.com> Date: Fri, 21 Nov 2025 22:27:41 -0600 Subject: [PATCH 4/8] Fix error on preview when only the closing bracket was ignored Signed-off-by: cobalt <61329810+cobaltt7@users.noreply.github.com> --- src/black/comments.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/black/comments.py b/src/black/comments.py index 1767116ae9e..2de130dca14 100644 --- a/src/black/comments.py +++ b/src/black/comments.py @@ -6,6 +6,7 @@ from black.mode import Mode, Preview from black.nodes import ( + BRACKETS, CLOSING_BRACKETS, STANDALONE_COMMENT, STATEMENT, @@ -650,6 +651,13 @@ def _generate_ignored_nodes_from_fmt_skip( leaf_nodes = list(current_node.prev_sibling.leaves()) current_node = leaf_nodes[-1] if leaf_nodes else current_node + if ( + current_node.type in BRACKETS + and current_node.parent + and current_node.parent.type == syms.atom + ): + current_node = current_node.parent + if current_node.type in (token.NEWLINE, token.INDENT): current_node.prefix = "" break @@ -658,6 +666,7 @@ def _generate_ignored_nodes_from_fmt_skip( 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): body_node = _find_compound_statement_context(parent) From 68a08923dd16acb252a4f4f546e3aaf459eaff8a Mon Sep 17 00:00:00 2001 From: cobalt <61329810+cobaltt7@users.noreply.github.com> Date: Fri, 21 Nov 2025 22:29:47 -0600 Subject: [PATCH 5/8] Fix merge conflict Signed-off-by: cobalt <61329810+cobaltt7@users.noreply.github.com> --- tests/data/cases/{fmtskip12.py => fmtskip13.py} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename tests/data/cases/{fmtskip12.py => fmtskip13.py} (100%) diff --git a/tests/data/cases/fmtskip12.py b/tests/data/cases/fmtskip13.py similarity index 100% rename from tests/data/cases/fmtskip12.py rename to tests/data/cases/fmtskip13.py From 68b137385d4218b8dbccb786f4b7a83fd815e2f5 Mon Sep 17 00:00:00 2001 From: cobalt <61329810+cobaltt7@users.noreply.github.com> Date: Thu, 27 Nov 2025 19:30:22 -0600 Subject: [PATCH 6/8] If i fully gate it under fix_fmt_skip_in_one_liners it works Signed-off-by: cobalt <61329810+cobaltt7@users.noreply.github.com> --- CHANGES.md | 2 +- src/black/comments.py | 5 ++--- tests/data/cases/fmtskip10.py | 14 +++++++------- tests/data/cases/fmtskip11.py | 9 --------- tests/data/cases/fmtskip13.py | 2 ++ 5 files changed, 12 insertions(+), 20 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index ebabb202a08..c016d3c2ff6 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -17,11 +17,11 @@ - Fix bug where comments preceding `# fmt: off`/`# fmt: on` blocks were incorrectly removed, particularly affecting Jupytext's `# %% [markdown]` comments (#4845) -- Fix `fmt: skip` skipping the line after instead of the line it's on (#4855) ### Preview style +- Fix `fmt: skip` skipping the line after instead of the line it's on (#4855) ### Configuration diff --git a/src/black/comments.py b/src/black/comments.py index 2de130dca14..5cfd36adcec 100644 --- a/src/black/comments.py +++ b/src/black/comments.py @@ -6,7 +6,6 @@ from black.mode import Mode, Preview from black.nodes import ( - BRACKETS, CLOSING_BRACKETS, STANDALONE_COMMENT, STATEMENT, @@ -607,7 +606,7 @@ def _generate_ignored_nodes_from_fmt_skip( if not comments or comment.value != comments[0].value: return - if not prev_sibling and parent and parent.prev_sibling: + if Preview.fix_fmt_skip_in_one_liners in mode and not prev_sibling and parent and parent.prev_sibling: prev_sibling = parent.prev_sibling if prev_sibling is not None: @@ -652,7 +651,7 @@ def _generate_ignored_nodes_from_fmt_skip( current_node = leaf_nodes[-1] if leaf_nodes else current_node if ( - current_node.type in BRACKETS + current_node.type in CLOSING_BRACKETS and current_node.parent and current_node.parent.type == syms.atom ): diff --git a/tests/data/cases/fmtskip10.py b/tests/data/cases/fmtskip10.py index 2f3318a17a9..46f29000ca1 100644 --- a/tests/data/cases/fmtskip10.py +++ b/tests/data/cases/fmtskip10.py @@ -11,11 +11,11 @@ def foo(): return "mock" # fmt: skip b = [c for c in "A very long string that would normally generate some kind of collapse, since it is this long"] # fmt: skip -t = ( - { - "foo":"very long string", - "bar":"another very long string", - "baz":"we should run out of space by now", - }, # fmt: skip - {"foo": "bar"}, +v = ( + foo_dict # fmt: skip + .setdefault("a", {}) + .setdefault("b", {}) + .setdefault("c", {}) + .setdefault("d", {}) + .setdefault("e", {}) ) diff --git a/tests/data/cases/fmtskip11.py b/tests/data/cases/fmtskip11.py index a8a0e217e60..5d3f7874e55 100644 --- a/tests/data/cases/fmtskip11.py +++ b/tests/data/cases/fmtskip11.py @@ -4,12 +4,3 @@ def foo(): # comment 1 # fmt: skip # comment 2 - -v = ( - foo_dict # fmt: skip - .setdefault("a", {}) - .setdefault("b", {}) - .setdefault("c", {}) - .setdefault("d", {}) - .setdefault("e", {}) -) diff --git a/tests/data/cases/fmtskip13.py b/tests/data/cases/fmtskip13.py index 1f2d53437cb..f3abcba9219 100644 --- a/tests/data/cases/fmtskip13.py +++ b/tests/data/cases/fmtskip13.py @@ -1,3 +1,5 @@ +# flags: --preview + t = ( {"foo": "very long string", "bar": "another very long string", "baz": "we should run out of space by now"}, # fmt: skip {"foo": "bar"}, From df59033a27f3d02a02c763a0c09364ba0ab0fb6c Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 28 Nov 2025 01:30:56 +0000 Subject: [PATCH 7/8] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- CHANGES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES.md b/CHANGES.md index c016d3c2ff6..adb02b4097a 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -21,6 +21,7 @@ ### Preview style + - Fix `fmt: skip` skipping the line after instead of the line it's on (#4855) ### Configuration From b17182c1b366433f72ffd1461a862a40417fb211 Mon Sep 17 00:00:00 2001 From: cobalt <61329810+cobaltt7@users.noreply.github.com> Date: Thu, 27 Nov 2025 19:53:49 -0600 Subject: [PATCH 8/8] Fix should-be final issues Signed-off-by: cobalt <61329810+cobaltt7@users.noreply.github.com> --- src/black/comments.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/black/comments.py b/src/black/comments.py index ad0783db5c9..ff83a0079c4 100644 --- a/src/black/comments.py +++ b/src/black/comments.py @@ -606,7 +606,7 @@ def _generate_ignored_nodes_from_fmt_skip( if not comments or comment.value != comments[0].value: return - if Preview.fix_fmt_skip_in_one_liners in mode and not prev_sibling and parent and parent.prev_sibling: + if Preview.fix_fmt_skip_in_one_liners in mode and not prev_sibling and parent: prev_sibling = parent.prev_sibling if prev_sibling is not None: @@ -661,6 +661,9 @@ def _generate_ignored_nodes_from_fmt_skip( current_node.prefix = "" break + if current_node.type == token.DEDENT: + break + # Special case for with expressions # Without this, we can stuck inside the asexpr_test's children's children if (