Skip to content

Commit a94a78c

Browse files
Fix bug where # fmt: skip is not being respect with one-liner functions (#4535)
1 parent 584d033 commit a94a78c

File tree

3 files changed

+39
-6
lines changed

3 files changed

+39
-6
lines changed

Diff for: CHANGES.md

+3
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@
1616
- Fix crash when formatting `with` statements containing tuple generators/unpacking
1717
(#4538)
1818

19+
- Fix a bug where one-liner functions marked with `# fmt: skip` would still be
20+
formatted (#)
21+
1922
### Preview style
2023

2124
<!-- Changes that affect Black's preview style -->

Diff for: src/black/comments.py

+35-6
Original file line numberDiff line numberDiff line change
@@ -318,26 +318,55 @@ def _generate_ignored_nodes_from_fmt_skip(
318318
"""Generate all leaves that should be ignored by the `# fmt: skip` from `leaf`."""
319319
prev_sibling = leaf.prev_sibling
320320
parent = leaf.parent
321+
ignored_nodes: list[LN] = []
321322
# Need to properly format the leaf prefix to compare it to comment.value,
322323
# which is also formatted
323324
comments = list_comments(leaf.prefix, is_endmarker=False)
324325
if not comments or comment.value != comments[0].value:
325326
return
326327
if prev_sibling is not None:
328+
# Generates the nodes to be ignored by `fmt: skip`.
329+
330+
# Nodes to ignore are those on the same line as the `# fmt: skip` comment,
331+
# excluding the `# fmt: skip` node itself.
332+
333+
# Traversal process (starting at the `# fmt: skip` node):
334+
# 1. Move to the `prev_sibling` of the current node.
335+
# 2. If `prev_sibling` has children, go to its rightmost leaf.
336+
# 3. If there’s no `prev_sibling`, move up to the parent node and repeat.
337+
# 4. Continue until:
338+
# a. You encounter an `INDENT` or `NEWLINE` node (indicates
339+
# start of the line).
340+
# b. You reach the root node.
341+
342+
# Include all visited LEAVES in the ignored list, except INDENT
343+
# or NEWLINE leaves.
344+
327345
leaf.prefix = ""
328-
siblings = [prev_sibling]
329-
while "\n" not in prev_sibling.prefix and prev_sibling.prev_sibling is not None:
330-
prev_sibling = prev_sibling.prev_sibling
331-
siblings.insert(0, prev_sibling)
332-
yield from siblings
346+
current_node = prev_sibling
347+
ignored_nodes = [current_node]
348+
if current_node.prev_sibling is None and current_node.parent is not None:
349+
current_node = current_node.parent
350+
while "\n" not in current_node.prefix and current_node.prev_sibling is not None:
351+
leaf_nodes = list(current_node.prev_sibling.leaves())
352+
current_node = leaf_nodes[-1] if leaf_nodes else current_node
353+
354+
if current_node.type in (token.NEWLINE, token.INDENT):
355+
current_node.prefix = ""
356+
break
357+
358+
ignored_nodes.insert(0, current_node)
359+
360+
if current_node.prev_sibling is None and current_node.parent is not None:
361+
current_node = current_node.parent
362+
yield from ignored_nodes
333363
elif (
334364
parent is not None and parent.type == syms.suite and leaf.type == token.NEWLINE
335365
):
336366
# The `# fmt: skip` is on the colon line of the if/while/def/class/...
337367
# statements. The ignored nodes should be previous siblings of the
338368
# parent suite node.
339369
leaf.prefix = ""
340-
ignored_nodes: list[LN] = []
341370
parent_sibling = parent.prev_sibling
342371
while parent_sibling is not None and parent_sibling.type != syms.suite:
343372
ignored_nodes.insert(0, parent_sibling)

Diff for: tests/data/cases/fmtskip10.py

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
def foo(): return "mock" # fmt: skip

0 commit comments

Comments
 (0)