diff --git a/crates/ruff_python_formatter/src/comments/placement.rs b/crates/ruff_python_formatter/src/comments/placement.rs index 4a33095f43..8f8121f1b6 100644 --- a/crates/ruff_python_formatter/src/comments/placement.rs +++ b/crates/ruff_python_formatter/src/comments/placement.rs @@ -1830,7 +1830,7 @@ fn handle_lambda_comment<'a>( comment: DecoratedComment<'a>, lambda: &'a ast::ExprLambda, source: &str, - _preview: PreviewMode, + preview: PreviewMode, ) -> CommentPlacement<'a> { if let Some(parameters) = lambda.parameters.as_deref() { // End-of-line comments between the `lambda` and the parameters are dangling on the lambda: @@ -1885,7 +1885,11 @@ fn handle_lambda_comment<'a>( return CommentPlacement::Default(comment); } - return CommentPlacement::dangling(comment.enclosing_node(), comment); + return if preview.is_enabled() { + CommentPlacement::leading(&*lambda.body, comment) + } else { + CommentPlacement::dangling(comment.enclosing_node(), comment) + }; } } else { // Comments between the lambda and the body are dangling on the lambda: @@ -1914,7 +1918,11 @@ fn handle_lambda_comment<'a>( return CommentPlacement::Default(comment); } - return CommentPlacement::dangling(comment.enclosing_node(), comment); + return if preview.is_enabled() { + CommentPlacement::leading(&*lambda.body, comment) + } else { + CommentPlacement::dangling(comment.enclosing_node(), comment) + }; } } diff --git a/crates/ruff_python_formatter/src/expression/expr_lambda.rs b/crates/ruff_python_formatter/src/expression/expr_lambda.rs index 9e23f2212a..baadc0c630 100644 --- a/crates/ruff_python_formatter/src/expression/expr_lambda.rs +++ b/crates/ruff_python_formatter/src/expression/expr_lambda.rs @@ -127,51 +127,6 @@ impl FormatNodeRule for FormatExprLambda { if dangling_after_parameters.is_empty() { write!(f, [space()])?; - } - // In preview, always parenthesize the body if there are dangling comments. - else if preview { - // Can't use partition_point because there can be additional end of line comments - // after the initial set. All of these comments are dangling, for example: - // - // ```python - // ( - // lambda # 1 - // # 2 - // : # 3 - // # 4 - // y - // ) - // ``` - // - // and alternate between own line and end of line. - let (after_parameters_end_of_line, leading_body_comments) = - dangling_after_parameters.split_at( - dangling_after_parameters - .iter() - .position(|comment| comment.line_position().is_own_line()) - .unwrap_or(dangling_after_parameters.len()), - ); - - let fmt_body = format_with(|f: &mut PyFormatter| { - write!( - f, - [ - space(), - token("("), - trailing_comments(after_parameters_end_of_line), - block_indent(&format_args!( - leading_comments(leading_body_comments), - body.format().with_options(Parentheses::Never) - )), - token(")") - ] - ) - }); - - return match self.layout { - ExprLambdaLayout::Assignment => fits_expanded(&fmt_body).fmt(f), - ExprLambdaLayout::Default => fmt_body.fmt(f), - }; } else { write!(f, [dangling_comments(dangling_after_parameters)])?; } @@ -181,36 +136,6 @@ impl FormatNodeRule for FormatExprLambda { // In this context, a dangling comment is a comment between the `lambda` and the body. if dangling.is_empty() { write!(f, [space()])?; - } - // In preview, always parenthesize the body if there are dangling comments. - else if preview { - let (dangling_end_of_line, dangling_own_line) = dangling.split_at( - dangling - .iter() - .position(|comment| comment.line_position().is_own_line()) - .unwrap_or(dangling.len()), - ); - - let fmt_body = format_with(|f: &mut PyFormatter| { - write!( - f, - [ - space(), - token("("), - trailing_comments(dangling_end_of_line), - block_indent(&format_args!( - leading_comments(dangling_own_line), - body.format().with_options(Parentheses::Never) - )), - token(")") - ] - ) - }); - - return match self.layout { - ExprLambdaLayout::Assignment => fits_expanded(&fmt_body).fmt(f), - ExprLambdaLayout::Default => fmt_body.fmt(f), - }; } else { write!(f, [dangling_comments(dangling)])?; } @@ -223,7 +148,25 @@ impl FormatNodeRule for FormatExprLambda { // ensures that we correctly handle parenthesized comments, and don't need to worry // about them in the implementation below. if body_comments.has_leading() || body_comments.has_trailing_own_line() { - body.format().with_options(Parentheses::Always).fmt(f) + let (leading_end_of_line, leading_own_line) = body_comments.leading.split_at( + body_comments + .leading + .iter() + .position(|comment| comment.line_position().is_own_line()) + .unwrap_or(body_comments.leading.len()), + ); + write!( + f, + [ + token("("), + trailing_comments(leading_end_of_line), + block_indent(&format_args!( + leading_comments(leading_own_line), + body.format().with_options(Parentheses::Never) + )), + token(")") + ] + ) } // Calls and subscripts require special formatting because they have their own // parentheses, but they can also have an arbitrary amount of text before the diff --git a/crates/ruff_python_formatter/tests/snapshots/format@expression__lambda.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@expression__lambda.py.snap index 637802fb7f..ddf0e7ea29 100644 --- a/crates/ruff_python_formatter/tests/snapshots/format@expression__lambda.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/format@expression__lambda.py.snap @@ -1653,7 +1653,7 @@ transform = ( ) lambda *x: x -@@ -161,30 +147,34 @@ +@@ -161,30 +147,33 @@ ) ( @@ -1695,12 +1695,11 @@ transform = ( ( - lambda: # comment - ( # comment -+ lambda: ( # comment -+ # comment ++ lambda: ( # comment # comment x ) ) -@@ -192,11 +182,12 @@ +@@ -192,11 +181,12 @@ ( lambda # 1 # 2 @@ -1718,7 +1717,7 @@ transform = ( ) ( -@@ -204,9 +195,10 @@ +@@ -204,9 +194,10 @@ # 2 x, # 3 # 4 @@ -1732,7 +1731,7 @@ transform = ( ) ( -@@ -218,71 +210,79 @@ +@@ -218,71 +209,79 @@ # Leading lambda x: ( @@ -1871,7 +1870,7 @@ transform = ( # Regression tests for https://github.com/astral-sh/ruff/issues/8179 -@@ -291,9 +291,9 @@ +@@ -291,9 +290,9 @@ c, d, e, @@ -1884,7 +1883,7 @@ transform = ( ) -@@ -302,15 +302,9 @@ +@@ -302,15 +301,9 @@ c, d, e, @@ -1903,7 +1902,7 @@ transform = ( g=10, ) -@@ -320,9 +314,9 @@ +@@ -320,9 +313,9 @@ c, d, e, @@ -1916,7 +1915,7 @@ transform = ( ) -@@ -338,9 +332,9 @@ +@@ -338,9 +331,9 @@ class C: function_dict: Dict[Text, Callable[[CRFToken], Any]] = { @@ -1929,7 +1928,7 @@ transform = ( } -@@ -352,42 +346,40 @@ +@@ -352,42 +345,40 @@ def foo(): if True: if True: @@ -1988,7 +1987,7 @@ transform = ( CREATE TABLE {table} AS SELECT ROW_NUMBER() OVER () AS id, {var} FROM ( -@@ -401,18 +393,19 @@ +@@ -401,18 +392,19 @@ long_assignment_target.with_attribute.and_a_slice[with_an_index] = ( # 1 # 2 @@ -2015,7 +2014,7 @@ transform = ( ) very_long_variable_name_x, very_long_variable_name_y = ( -@@ -420,8 +413,8 @@ +@@ -420,8 +412,8 @@ lambda b: b * another_very_long_expression_here, ) @@ -2026,7 +2025,7 @@ transform = ( x, more_args, additional_parameters ) ) -@@ -457,12 +450,12 @@ +@@ -457,12 +449,12 @@ [ # Not fluent param( @@ -2041,7 +2040,7 @@ transform = ( ), param( lambda left, right: ( -@@ -471,9 +464,9 @@ +@@ -471,9 +463,9 @@ ), param(lambda left, right: ibis.timestamp("2017-04-01").cast(dt.date)), param( @@ -2054,7 +2053,7 @@ transform = ( ), # This is too long on one line in the lambda body and gets wrapped # inside the body. -@@ -507,16 +500,18 @@ +@@ -507,16 +499,18 @@ ] # adds parentheses around the body @@ -2076,7 +2075,7 @@ transform = ( lambda x, y, z: ( x + y + z -@@ -527,7 +522,7 @@ +@@ -527,7 +521,7 @@ x + y + z # trailing eol body ) @@ -2085,7 +2084,7 @@ transform = ( lambda x, y, z: ( # leading body -@@ -539,21 +534,23 @@ +@@ -539,21 +533,23 @@ ) ( @@ -2119,7 +2118,7 @@ transform = ( # dangling header comment source_bucket if name == source_bucket_name -@@ -561,8 +558,7 @@ +@@ -561,8 +557,7 @@ ) ( @@ -2129,7 +2128,7 @@ transform = ( source_bucket if name == source_bucket_name else storage.Bucket(mock_service, destination_bucket_name) -@@ -570,61 +566,70 @@ +@@ -570,61 +565,70 @@ ) ( @@ -2232,7 +2231,7 @@ transform = ( ) ( -@@ -637,27 +642,31 @@ +@@ -637,27 +641,31 @@ ( lambda # comment @@ -2272,7 +2271,7 @@ transform = ( ) ( -@@ -665,19 +674,20 @@ +@@ -665,19 +673,20 @@ # 2 left, # 3 # 4 @@ -2303,7 +2302,7 @@ transform = ( ) ) ) -@@ -695,48 +705,52 @@ +@@ -695,48 +704,52 @@ foo( lambda from_ts, # but still wrap the body if it gets too long to_ts,