From ed238e0c76aad6093fb4ee1bda41858d01753442 Mon Sep 17 00:00:00 2001 From: Micha Reiser Date: Mon, 22 Jul 2024 14:17:00 +0200 Subject: [PATCH] Fix incorrect placement of leading function comment with type params (#12447) --- .../ruff/statement/class_definition.py | 22 +++++++++ .../test/fixtures/ruff/statement/function.py | 22 +++++++++ .../src/comments/placement.rs | 2 +- ...format@statement__class_definition.py.snap | 47 +++++++++++++++++- .../format@statement__function.py.snap | 48 +++++++++++++++++++ 5 files changed, 139 insertions(+), 2 deletions(-) diff --git a/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/class_definition.py b/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/class_definition.py index 73b8fe1b12cbc9..c261ae812f7737 100644 --- a/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/class_definition.py +++ b/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/class_definition.py @@ -224,3 +224,25 @@ def as_manager(cls): as_manager.queryset_only = True as_manager = classmethod(as_manager) + + +# Decorators +@decorator +# comment +class Foo1: ... + +@decorator +# comment +class Foo2(Foo1): ... + +@decorator +# comment +class Foo3[T]: ... + +@decorator # comment +class Foo4: ... + +@decorator +# comment +@decorato2 +class Foo5: ... diff --git a/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/function.py b/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/function.py index 57034c14a25fb1..3553c5792678e5 100644 --- a/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/function.py +++ b/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/function.py @@ -436,3 +436,25 @@ def function_with_variadic_generics(*args: *tuple[int],): ... # Generic arguments (PEP 695) def func[T](lotsoflongargs: T, lotsoflongargs2: T, lotsoflongargs3: T, lotsoflongargs4: T, lotsoflongargs5: T) -> T: ... + + +# Decorators +@decorator +# comment +def foo[S](x: S) -> S: ... + +@decorator +# comment +def foo(x: S) -> S: ... + +@decorator +# comment +def foo() -> S: ... + +@decorator +# comment +@decorator2 +def foo(x: S) -> S: ... + +@decorator # comment +def foo(x: S) -> S: ... diff --git a/crates/ruff_python_formatter/src/comments/placement.rs b/crates/ruff_python_formatter/src/comments/placement.rs index 3225874aebea56..41813d443b4e65 100644 --- a/crates/ruff_python_formatter/src/comments/placement.rs +++ b/crates/ruff_python_formatter/src/comments/placement.rs @@ -1076,7 +1076,7 @@ fn handle_leading_function_with_decorators_comment(comment: DecoratedComment) -> let is_following_parameters = comment .following_node() - .is_some_and(|node| node.is_parameters()); + .is_some_and(|node| node.is_parameters() || node.is_type_params()); if comment.line_position().is_own_line() && is_preceding_decorator && is_following_parameters { CommentPlacement::dangling(comment.enclosing_node(), comment) diff --git a/crates/ruff_python_formatter/tests/snapshots/format@statement__class_definition.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@statement__class_definition.py.snap index 6368fd730b71e0..db9773291b2c09 100644 --- a/crates/ruff_python_formatter/tests/snapshots/format@statement__class_definition.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/format@statement__class_definition.py.snap @@ -230,6 +230,28 @@ class QuerySet(AltersData): as_manager.queryset_only = True as_manager = classmethod(as_manager) + + +# Decorators +@decorator +# comment +class Foo1: ... + +@decorator +# comment +class Foo2(Foo1): ... + +@decorator +# comment +class Foo3[T]: ... + +@decorator # comment +class Foo4: ... + +@decorator +# comment +@decorato2 +class Foo5: ... ``` ## Output @@ -489,7 +511,30 @@ class QuerySet(AltersData): as_manager.queryset_only = True as_manager = classmethod(as_manager) -``` +# Decorators +@decorator +# comment +class Foo1: ... + +@decorator +# comment +class Foo2(Foo1): ... + + +@decorator +# comment +class Foo3[T]: ... + + +@decorator # comment +class Foo4: ... + + +@decorator +# comment +@decorato2 +class Foo5: ... +``` diff --git a/crates/ruff_python_formatter/tests/snapshots/format@statement__function.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@statement__function.py.snap index 9d108fc7572913..2e353d6aa2dbff 100644 --- a/crates/ruff_python_formatter/tests/snapshots/format@statement__function.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/format@statement__function.py.snap @@ -442,6 +442,28 @@ def function_with_variadic_generics(*args: *tuple[int],): ... # Generic arguments (PEP 695) def func[T](lotsoflongargs: T, lotsoflongargs2: T, lotsoflongargs3: T, lotsoflongargs4: T, lotsoflongargs5: T) -> T: ... + + +# Decorators +@decorator +# comment +def foo[S](x: S) -> S: ... + +@decorator +# comment +def foo(x: S) -> S: ... + +@decorator +# comment +def foo() -> S: ... + +@decorator +# comment +@decorator2 +def foo(x: S) -> S: ... + +@decorator # comment +def foo(x: S) -> S: ... ``` ## Output @@ -1041,6 +1063,32 @@ def func[T]( lotsoflongargs4: T, lotsoflongargs5: T, ) -> T: ... + + +# Decorators +@decorator +# comment +def foo[S](x: S) -> S: ... + + +@decorator +# comment +def foo(x: S) -> S: ... + + +@decorator +# comment +def foo() -> S: ... + + +@decorator +# comment +@decorator2 +def foo(x: S) -> S: ... + + +@decorator # comment +def foo(x: S) -> S: ... ```