From f248478d0766cf9541c035953cef6355c27ada69 Mon Sep 17 00:00:00 2001 From: Charlie Marsh Date: Mon, 7 Aug 2023 21:10:56 -0400 Subject: [PATCH] Ungroup --- .../test/fixtures/ruff/statement/function.py | 26 ++++++ .../src/other/parameters.rs | 18 +++-- .../src/statement/stmt_function_def.rs | 38 +++++---- ..._cases__return_annotation_brackets.py.snap | 12 ++- .../format@statement__function.py.snap | 80 ++++++++++++++++++- 5 files changed, 147 insertions(+), 27 deletions(-) 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 e59547d6ce547..d24275114327b 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 @@ -409,3 +409,29 @@ def double(a: int) -> ( # Hello def double(a: int) -> ( # Hello ): return 2*a + +# Breaking over parameters and return types. (Black adds a trailing comma when the +# function arguments break here with a single argument; we do not.) +def f(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) -> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: + ... + +def f(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, a) -> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: + ... + +def f(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) -> a: + ... + +def f(a) -> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: + ... + +def f[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa]() -> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: + ... + +def f[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa]() -> a: + ... + +def f[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa](aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) -> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: + ... + +def f[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa](aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) -> a: + ... diff --git a/crates/ruff_python_formatter/src/other/parameters.rs b/crates/ruff_python_formatter/src/other/parameters.rs index cbd9b594b7a75..74013248903ad 100644 --- a/crates/ruff_python_formatter/src/other/parameters.rs +++ b/crates/ruff_python_formatter/src/other/parameters.rs @@ -7,14 +7,15 @@ use ruff_python_trivia::{SimpleToken, SimpleTokenKind, SimpleTokenizer}; use ruff_text_size::{TextRange, TextSize}; use crate::comments::{ - leading_comments, leading_node_comments, trailing_comments, CommentLinePosition, SourceComment, + dangling_open_parenthesis_comments, leading_comments, leading_node_comments, trailing_comments, + CommentLinePosition, SourceComment, }; use crate::context::{NodeLevel, WithNodeLevel}; -use crate::expression::parentheses::{empty_parenthesized, parenthesized}; +use crate::expression::parentheses::empty_parenthesized; use crate::prelude::*; use crate::FormatNodeRule; -#[derive(Eq, PartialEq, Debug, Default)] +#[derive(Debug, Copy, Clone, Eq, PartialEq, Default)] pub enum ParametersParentheses { /// By default, parameters will always preserve their surrounding parentheses. #[default] @@ -246,10 +247,17 @@ impl FormatNodeRule for FormatParameters { // No parameters, format any dangling comments between `()` write!(f, [empty_parenthesized("(", dangling, ")")]) } else { + // Intentionally avoid `parenthesized`, which groups the entire formatted contents. + // We want parameters to be grouped alongside return types, one level up, so we + // format them "inline" here. write!( f, - [parenthesized("(", &group(&format_inner), ")") - .with_dangling_comments(parenthesis_dangling)] + [ + text("("), + &dangling_open_parenthesis_comments(parenthesis_dangling), + &soft_block_indent(&format_args!(&group(&format_inner),)), + text(")") + ] ) } } diff --git a/crates/ruff_python_formatter/src/statement/stmt_function_def.rs b/crates/ruff_python_formatter/src/statement/stmt_function_def.rs index 4533a6012cd1a..746b69de42824 100644 --- a/crates/ruff_python_formatter/src/statement/stmt_function_def.rs +++ b/crates/ruff_python_formatter/src/statement/stmt_function_def.rs @@ -58,24 +58,28 @@ impl FormatNodeRule for FormatStmtFunctionDef { write!(f, [type_params.format()])?; } - write!(f, [item.parameters.format()])?; - - if let Some(return_annotation) = item.returns.as_ref() { - write!(f, [space(), text("->"), space()])?; - if return_annotation.is_tuple_expr() { - write!( - f, - [return_annotation.format().with_options(Parentheses::Never)] - )?; - } else { - write!( - f, - [optional_parentheses( - &return_annotation.format().with_options(Parentheses::Never), - )] - )?; + let format_inner = format_with(|f: &mut PyFormatter| { + write!(f, [item.parameters.format()])?; + if let Some(return_annotation) = item.returns.as_ref() { + write!(f, [space(), text("->"), space()])?; + if return_annotation.is_tuple_expr() { + write!( + f, + [return_annotation.format().with_options(Parentheses::Never)] + )?; + } else { + write!( + f, + [optional_parentheses( + &return_annotation.format().with_options(Parentheses::Never), + )] + )?; + } } - } + Ok(()) + }); + + write!(f, [group(&format_inner)])?; write!( f, diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__return_annotation_brackets.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__return_annotation_brackets.py.snap index c35111a8b1b18..36e4656eb051e 100644 --- a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__return_annotation_brackets.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__return_annotation_brackets.py.snap @@ -100,18 +100,20 @@ def foo() -> tuple[int, int, int,]: ```diff --- Black +++ Ruff -@@ -26,7 +26,9 @@ +@@ -26,7 +26,11 @@ return 2 * a -def double(a: int) -> int: # Hello -+def double(a: int) -> ( ++def double( ++ a: int ++) -> ( + int # Hello +): return 2 * a -@@ -54,7 +56,9 @@ +@@ -54,7 +58,9 @@ a: int, b: int, c: int, @@ -155,7 +157,9 @@ def double(a: int) -> int: # Hello return 2 * a -def double(a: int) -> ( +def double( + a: int +) -> ( int # Hello ): return 2 * a 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 7868120be5494..d9f8a55ccf6db 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 @@ -415,6 +415,32 @@ def double(a: int) -> ( # Hello def double(a: int) -> ( # Hello ): return 2*a + +# Breaking over parameters and return types. (Black adds a trailing comma when the +# function arguments break here with a single argument; we do not.) +def f(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) -> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: + ... + +def f(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, a) -> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: + ... + +def f(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) -> a: + ... + +def f(a) -> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: + ... + +def f[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa]() -> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: + ... + +def f[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa]() -> a: + ... + +def f[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa](aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) -> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: + ... + +def f[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa](aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) -> a: + ... ``` ## Output @@ -1023,9 +1049,61 @@ def double(a: int) -> int: # Hello return 2 * a -def double(a: int) -> ( # Hello +def double( + a: int +) -> ( # Hello ): return 2 * a + + +# Breaking over parameters and return types. (Black adds a trailing comma when the +# function arguments break here with a single argument; we do not.) +def f( + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +) -> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: + ... + + +def f( + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, a +) -> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: + ... + + +def f( + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +) -> a: + ... + + +def f( + a +) -> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: + ... + + +def f[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa]() -> ( + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +): + ... + + +def f[ + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +]() -> a: + ... + + +def f[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa]( + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +) -> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: + ... + + +def f[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa]( + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +) -> a: + ... ```