diff --git a/crates/ruff_python_ast/src/nodes.rs b/crates/ruff_python_ast/src/nodes.rs index 9c4d8b594a..4a27d9d375 100644 --- a/crates/ruff_python_ast/src/nodes.rs +++ b/crates/ruff_python_ast/src/nodes.rs @@ -2135,6 +2135,15 @@ impl Parameters { } false } + + /// Returns `true` if the [`Parameters`] is empty. + pub fn is_empty(&self) -> bool { + self.posonlyargs.is_empty() + && self.args.is_empty() + && self.kwonlyargs.is_empty() + && self.vararg.is_none() + && self.kwarg.is_none() + } } /// An alternative type of AST `arg`. This is used for each function argument that might have a default value. diff --git a/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/return_annotation.py b/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/return_annotation.py index 7831370076..2c73d8248b 100644 --- a/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/return_annotation.py +++ b/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/return_annotation.py @@ -75,6 +75,12 @@ def xxxxxxxxxxxxxxxxxxxxxxxxxxxx() -> Set[ ]: ... +def xxxxxxxxxxxxxxxxxxxxxxxxxxxx( +) -> Set[ + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +]: + ... + def xxxxxxxxxxxxxxxxxxxxxxxxxxxx() -> ( Set[ "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"] 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 9d1d3280a1..e55c5e3aa6 100644 --- a/crates/ruff_python_formatter/src/statement/stmt_function_def.rs +++ b/crates/ruff_python_formatter/src/statement/stmt_function_def.rs @@ -1,9 +1,7 @@ -use crate::comments::format::empty_lines_before_trailing_comments; use ruff_formatter::write; -use ruff_python_ast::{Parameters, StmtFunctionDef}; -use ruff_python_trivia::{SimpleTokenKind, SimpleTokenizer}; -use ruff_text_size::Ranged; +use ruff_python_ast::StmtFunctionDef; +use crate::comments::format::empty_lines_before_trailing_comments; use crate::comments::SourceComment; use crate::expression::maybe_parenthesize_expression; use crate::expression::parentheses::{Parentheses, Parenthesize}; @@ -147,29 +145,30 @@ fn format_function_header(f: &mut PyFormatter, item: &StmtFunctionDef) -> Format [return_annotation.format().with_options(Parentheses::Always)] )?; } else { + let parenthesize = if parameters.is_empty() && !comments.has(parameters.as_ref()) { + // If the parameters are empty, add parentheses if the return annotation + // breaks at all. + Parenthesize::IfBreaksOrIfRequired + } else { + // Otherwise, use our normal rules for parentheses, which allows us to break + // like: + // ```python + // def f( + // x, + // ) -> Tuple[ + // int, + // int, + // ]: + // ... + // ``` + Parenthesize::IfBreaks + }; write!( f, [maybe_parenthesize_expression( return_annotation, item, - if empty_parameters(parameters, f.context().source()) { - // If the parameters are empty, add parentheses if the return annotation - // breaks at all. - Parenthesize::IfBreaksOrIfRequired - } else { - // Otherwise, use our normal rules for parentheses, which allows us to break - // like: - // ```python - // def f( - // x, - // ) -> Tuple[ - // int, - // int, - // ]: - // ... - // ``` - Parenthesize::IfBreaks - }, + parenthesize )] )?; } @@ -179,25 +178,3 @@ fn format_function_header(f: &mut PyFormatter, item: &StmtFunctionDef) -> Format group(&format_inner).fmt(f) } - -/// Returns `true` if [`Parameters`] is empty (no parameters, no comments, etc.). -fn empty_parameters(parameters: &Parameters, source: &str) -> bool { - let mut tokenizer = SimpleTokenizer::new(source, parameters.range()) - .filter(|token| !matches!(token.kind, SimpleTokenKind::Whitespace)); - - let Some(lpar) = tokenizer.next() else { - return false; - }; - if !matches!(lpar.kind, SimpleTokenKind::LParen) { - return false; - } - - let Some(rpar) = tokenizer.next() else { - return false; - }; - if !matches!(rpar.kind, SimpleTokenKind::RParen) { - return false; - } - - true -} diff --git a/crates/ruff_python_formatter/tests/snapshots/format@statement__return_annotation.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@statement__return_annotation.py.snap index a927576f72..2f8f6b710a 100644 --- a/crates/ruff_python_formatter/tests/snapshots/format@statement__return_annotation.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/format@statement__return_annotation.py.snap @@ -81,6 +81,12 @@ def xxxxxxxxxxxxxxxxxxxxxxxxxxxx() -> Set[ ]: ... +def xxxxxxxxxxxxxxxxxxxxxxxxxxxx( +) -> Set[ + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +]: + ... + def xxxxxxxxxxxxxxxxxxxxxxxxxxxx() -> ( Set[ "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"] @@ -365,6 +371,14 @@ def xxxxxxxxxxxxxxxxxxxxxxxxxxxx() -> ( ... +def xxxxxxxxxxxxxxxxxxxxxxxxxxxx() -> ( + Set[ + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + ] +): + ... + + def xxxxxxxxxxxxxxxxxxxxxxxxxxxx( x ) -> Set[