diff --git a/black.py b/black.py index 31859d1a499..2d8f9127a06 100644 --- a/black.py +++ b/black.py @@ -3118,9 +3118,33 @@ def generate_ignored_nodes(leaf: Leaf) -> Iterator[LN]: if is_fmt_on: return - yield container + # fix for fmt: on in children + if contains_fmt_on_at_column(container, leaf.column): + for child in container.children: + if not contains_fmt_on_at_column(child, leaf.column): + yield child + return + else: + yield container + container = container.next_sibling + + +def contains_fmt_on_at_column(container, column): + for child in container.children: + if (isinstance(child, Node) and first_leaf_column(child) == column + or isinstance(child, Leaf) and child.column == column): + for comment in list_comments(child.prefix, is_endmarker=False): + if comment.value in FMT_ON: + return True - container = container.next_sibling + return False + + +def first_leaf_column(node): + for child in node.children: + if isinstance(child, Leaf): + return child.column + return None def maybe_make_parens_invisible_in_atom(node: LN, parent: LN) -> bool: diff --git a/tests/data/fmtonoff4.py b/tests/data/fmtonoff4.py new file mode 100644 index 00000000000..54673c06b2d --- /dev/null +++ b/tests/data/fmtonoff4.py @@ -0,0 +1,31 @@ +# fmt: off +@test([ + 1, 2, + 3, 4, +]) +# fmt: on +def f(): pass + +@test([ + 1, 2, + 3, 4, +]) +def f(): pass + +# output + +# fmt: off +@test([ + 1, 2, + 3, 4, +]) +# fmt: on +def f(): + pass + + +@test( + [1, 2, 3, 4,] +) +def f(): + pass diff --git a/tests/test_black.py b/tests/test_black.py index acbaade0a50..790416c3e3e 100644 --- a/tests/test_black.py +++ b/tests/test_black.py @@ -632,6 +632,14 @@ def test_fmtonoff3(self) -> None: black.assert_equivalent(source, actual) black.assert_stable(source, actual, black.FileMode()) + @patch("black.dump_to_file", dump_to_stderr) + def test_fmtonoff4(self) -> None: + source, expected = read_data("fmtonoff4") + actual = fs(source) + self.assertFormatEqual(expected, actual) + black.assert_equivalent(source, actual) + black.assert_stable(source, actual, black.FileMode()) + @patch("black.dump_to_file", dump_to_stderr) def test_remove_empty_parentheses_after_class(self) -> None: source, expected = read_data("class_blank_parentheses")