From eece597b370e2ab1678b70a1b7a4724d83f91055 Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Tue, 21 Nov 2023 06:27:06 -0800 Subject: [PATCH 1/5] Do not treat "... # comment" as a dummy implementation Fixes #4063 --- CHANGES.md | 1 + src/black/nodes.py | 4 ++++ tests/data/cases/preview_dummy_implementations.py | 7 +++++++ 3 files changed, 12 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index 18bab5131e6..975de8a131f 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -16,6 +16,7 @@ - Additional cases of immediately nested tuples, lists, and dictionaries are now indented less (#4012) +- Keep suites consisting of an ellipsis followed by a comment on their own lines (#4066) ### Configuration diff --git a/src/black/nodes.py b/src/black/nodes.py index de53f8e36a3..fcfd6c9bae3 100644 --- a/src/black/nodes.py +++ b/src/black/nodes.py @@ -765,6 +765,10 @@ def is_stub_body(node: LN) -> bool: if len(node.children) != 2: return False + # If there is a comment after the ..., don't treat this suite as a stub body. + if node.children[1].prefix.strip(): + return False + child = node.children[0] return ( not child.prefix.strip() diff --git a/tests/data/cases/preview_dummy_implementations.py b/tests/data/cases/preview_dummy_implementations.py index 98b69bf87b2..38087def4cf 100644 --- a/tests/data/cases/preview_dummy_implementations.py +++ b/tests/data/cases/preview_dummy_implementations.py @@ -48,6 +48,9 @@ def b(arg: Union[int, str, object]) -> Union[int, str]: raise TypeError return arg +def has_comment(): + ... # not a dummy + # output from typing import NoReturn, Protocol, Union, overload @@ -98,3 +101,7 @@ def b(arg: Union[int, str, object]) -> Union[int, str]: if not isinstance(arg, (int, str)): raise TypeError return arg + + +def has_comment(): + ... # not a dummy From 0240924f740ef74188980d643eb252fce15333c2 Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Tue, 21 Nov 2023 07:34:27 -0800 Subject: [PATCH 2/5] Also exclude non-function/class suites, fix tests --- src/black/linegen.py | 4 ++-- src/black/nodes.py | 5 ++++- .../cases/funcdef_return_type_trailing_comma.py | 3 ++- tests/data/cases/ignore_pyi.py | 3 ++- .../data/cases/preview_dummy_implementations.py | 16 ++++++++++++++-- 5 files changed, 24 insertions(+), 7 deletions(-) diff --git a/src/black/linegen.py b/src/black/linegen.py index 7fbbe290d7e..6efaf19eb59 100644 --- a/src/black/linegen.py +++ b/src/black/linegen.py @@ -286,7 +286,7 @@ def visit_suite(self, node: Node) -> Iterator[Line]: """Visit a suite.""" if ( self.mode.is_pyi or Preview.dummy_implementations in self.mode - ) and is_stub_suite(node): + ) and is_stub_suite(node, self.mode): yield from self.visit(node.children[2]) else: yield from self.visit_default(node) @@ -314,7 +314,7 @@ def visit_simple_stmt(self, node: Node) -> Iterator[Line]: if ( not (self.mode.is_pyi or Preview.dummy_implementations in self.mode) or not node.parent - or not is_stub_suite(node.parent) + or not is_stub_suite(node.parent, self.mode) ): yield from self.line() yield from self.visit_default(node) diff --git a/src/black/nodes.py b/src/black/nodes.py index fcfd6c9bae3..b2e388ab9b5 100644 --- a/src/black/nodes.py +++ b/src/black/nodes.py @@ -736,8 +736,11 @@ def is_funcdef(node: Node) -> bool: return node.type == syms.funcdef -def is_stub_suite(node: Node) -> bool: +def is_stub_suite(node: Node, mode: Mode) -> bool: """Return True if `node` is a suite with a stub body.""" + if node.parent is not None: + if Preview.dummy_implementations in mode and node.parent.type not in (syms.funcdef, syms.async_funcdef, syms.classdef, ): + return False # If there is a comment, we want to keep it. if node.prefix.strip(): diff --git a/tests/data/cases/funcdef_return_type_trailing_comma.py b/tests/data/cases/funcdef_return_type_trailing_comma.py index 9b9b9c673de..7811c8fe920 100644 --- a/tests/data/cases/funcdef_return_type_trailing_comma.py +++ b/tests/data/cases/funcdef_return_type_trailing_comma.py @@ -253,7 +253,8 @@ def foo( def foo( a, b: list[Bad], -): ... # type: ignore +): + ... # type: ignore # don't lose any comments (no magic) diff --git a/tests/data/cases/ignore_pyi.py b/tests/data/cases/ignore_pyi.py index 4fae7530eb9..bde607af91f 100644 --- a/tests/data/cases/ignore_pyi.py +++ b/tests/data/cases/ignore_pyi.py @@ -28,7 +28,8 @@ def f(): # type: ignore class x: # some comment ... -class y: ... # comment +class y: + ... # comment # whitespace doesn't matter (note the next line has a trailing space and tab) class z: ... diff --git a/tests/data/cases/preview_dummy_implementations.py b/tests/data/cases/preview_dummy_implementations.py index 38087def4cf..f2a2fbbfd49 100644 --- a/tests/data/cases/preview_dummy_implementations.py +++ b/tests/data/cases/preview_dummy_implementations.py @@ -1,9 +1,11 @@ # flags: --preview from typing import NoReturn, Protocol, Union, overload +class Empty: + ... def dummy(a): ... -def other(b): ... +async def other(b): ... @overload @@ -51,13 +53,19 @@ def b(arg: Union[int, str, object]) -> Union[int, str]: def has_comment(): ... # not a dummy +if some_condition: + ... + # output from typing import NoReturn, Protocol, Union, overload +class Empty: ... + + def dummy(a): ... -def other(b): ... +async def other(b): ... @overload @@ -105,3 +113,7 @@ def b(arg: Union[int, str, object]) -> Union[int, str]: def has_comment(): ... # not a dummy + + +if some_condition: + ... From c47dceac2a87b8e68df86ca05932f4d04a71c962 Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Sat, 9 Dec 2023 17:33:30 -0800 Subject: [PATCH 3/5] Forget about comments, but only do it to functions --- src/black/nodes.py | 4 ---- tests/data/cases/funcdef_return_type_trailing_comma.py | 3 +-- tests/data/cases/ignore_pyi.py | 3 +-- tests/data/cases/preview_dummy_implementations.py | 5 ++--- 4 files changed, 4 insertions(+), 11 deletions(-) diff --git a/src/black/nodes.py b/src/black/nodes.py index b2e388ab9b5..22c10c7e845 100644 --- a/src/black/nodes.py +++ b/src/black/nodes.py @@ -768,10 +768,6 @@ def is_stub_body(node: LN) -> bool: if len(node.children) != 2: return False - # If there is a comment after the ..., don't treat this suite as a stub body. - if node.children[1].prefix.strip(): - return False - child = node.children[0] return ( not child.prefix.strip() diff --git a/tests/data/cases/funcdef_return_type_trailing_comma.py b/tests/data/cases/funcdef_return_type_trailing_comma.py index 7811c8fe920..9b9b9c673de 100644 --- a/tests/data/cases/funcdef_return_type_trailing_comma.py +++ b/tests/data/cases/funcdef_return_type_trailing_comma.py @@ -253,8 +253,7 @@ def foo( def foo( a, b: list[Bad], -): - ... # type: ignore +): ... # type: ignore # don't lose any comments (no magic) diff --git a/tests/data/cases/ignore_pyi.py b/tests/data/cases/ignore_pyi.py index bde607af91f..4fae7530eb9 100644 --- a/tests/data/cases/ignore_pyi.py +++ b/tests/data/cases/ignore_pyi.py @@ -28,8 +28,7 @@ def f(): # type: ignore class x: # some comment ... -class y: - ... # comment +class y: ... # comment # whitespace doesn't matter (note the next line has a trailing space and tab) class z: ... diff --git a/tests/data/cases/preview_dummy_implementations.py b/tests/data/cases/preview_dummy_implementations.py index f2a2fbbfd49..113ac36cdc5 100644 --- a/tests/data/cases/preview_dummy_implementations.py +++ b/tests/data/cases/preview_dummy_implementations.py @@ -51,7 +51,7 @@ def b(arg: Union[int, str, object]) -> Union[int, str]: return arg def has_comment(): - ... # not a dummy + ... # still a dummy if some_condition: ... @@ -111,8 +111,7 @@ def b(arg: Union[int, str, object]) -> Union[int, str]: return arg -def has_comment(): - ... # not a dummy +def has_comment(): ... # still a dummy if some_condition: From c3ba18bab63606137d7a4c4fb55ecf35f3c40136 Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Sat, 9 Dec 2023 17:34:43 -0800 Subject: [PATCH 4/5] Update changelog --- CHANGES.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index da987c60b10..58ee54471c7 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -18,7 +18,8 @@ - Additional cases of immediately nested tuples, lists, and dictionaries are now indented less (#4012) - Fix crash in preview mode when using a short `--line-length` (#4086) -- Keep suites consisting of an ellipsis followed by a comment on their own lines (#4066) +- Keep suites consisting of only an ellipsis on their own lines if they are not + functions or class definitions (#4066) ### Configuration From fb7774dcbc6f1f6e363b256be22a1316f56718f0 Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Sat, 9 Dec 2023 17:35:09 -0800 Subject: [PATCH 5/5] format self --- src/black/nodes.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/black/nodes.py b/src/black/nodes.py index 22c10c7e845..9b8d9a97835 100644 --- a/src/black/nodes.py +++ b/src/black/nodes.py @@ -739,7 +739,11 @@ def is_funcdef(node: Node) -> bool: def is_stub_suite(node: Node, mode: Mode) -> bool: """Return True if `node` is a suite with a stub body.""" if node.parent is not None: - if Preview.dummy_implementations in mode and node.parent.type not in (syms.funcdef, syms.async_funcdef, syms.classdef, ): + if Preview.dummy_implementations in mode and node.parent.type not in ( + syms.funcdef, + syms.async_funcdef, + syms.classdef, + ): return False # If there is a comment, we want to keep it.