diff --git a/crates/ruff_python_formatter/resources/test/fixtures/ruff/expression/lambda.py b/crates/ruff_python_formatter/resources/test/fixtures/ruff/expression/lambda.py index 036ef2c3c8..500b14f0ea 100644 --- a/crates/ruff_python_formatter/resources/test/fixtures/ruff/expression/lambda.py +++ b/crates/ruff_python_formatter/resources/test/fixtures/ruff/expression/lambda.py @@ -804,3 +804,12 @@ transform = lambda left, right: ibis.timestamp("2017-04-01").cast(dt.date).betwe x ) ) + +lambda x: ( + x := 1 +) + +( + lambda # dangling header comment + : (x := 1) +) diff --git a/crates/ruff_python_formatter/src/expression/expr_lambda.rs b/crates/ruff_python_formatter/src/expression/expr_lambda.rs index 63e8aa6d97..14ec1393d8 100644 --- a/crates/ruff_python_formatter/src/expression/expr_lambda.rs +++ b/crates/ruff_python_formatter/src/expression/expr_lambda.rs @@ -145,6 +145,7 @@ impl FormatNodeRule for FormatExprLambda { let fmt_body = FormatBody { body, dangling_header_comments, + needs_parentheses: body.needs_parentheses(item.into(), f.context()), }; match self.layout { @@ -262,6 +263,7 @@ struct FormatBody<'a> { /// ) /// ``` dangling_header_comments: &'a [SourceComment], + needs_parentheses: OptionalParentheses, } impl Format> for FormatBody<'_> { @@ -269,6 +271,7 @@ impl Format> for FormatBody<'_> { let FormatBody { dangling_header_comments, body, + needs_parentheses, } = self; let body = *body; @@ -438,6 +441,14 @@ impl Format> for FormatBody<'_> { else if has_own_parentheses(body, f.context()).is_some() { body.format().fmt(f) } + // Include parentheses for cases that always require them, such as named expressions: + // + // ```py + // lambda x: (y := x + 1) + // ``` + else if matches!(needs_parentheses, OptionalParentheses::Always) { + body.format().with_options(Parentheses::Always).fmt(f) + } // Finally, for expressions without their own parentheses, use // `parenthesize_if_expands` to add parentheses around the body, only if it expands // across multiple lines. The `Parentheses::Never` here also removes unnecessary diff --git a/crates/ruff_python_formatter/src/expression/expr_named.rs b/crates/ruff_python_formatter/src/expression/expr_named.rs index 117e42825e..a983a0c160 100644 --- a/crates/ruff_python_formatter/src/expression/expr_named.rs +++ b/crates/ruff_python_formatter/src/expression/expr_named.rs @@ -66,6 +66,7 @@ impl NeedsParentheses for ExprNamed { || parent.is_stmt_delete() || parent.is_stmt_for() || parent.is_stmt_function_def() + || parent.is_expr_lambda() { OptionalParentheses::Always } else { 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 393995f523..fb7452ee87 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 @@ -1,6 +1,5 @@ --- source: crates/ruff_python_formatter/tests/fixtures.rs -input_file: crates/ruff_python_formatter/resources/test/fixtures/ruff/expression/lambda.py --- ## Input ```python @@ -810,6 +809,15 @@ transform = lambda left, right: ibis.timestamp("2017-04-01").cast(dt.date).betwe x ) ) + +lambda x: ( + x := 1 +) + +( + lambda # dangling header comment + : (x := 1) +) ``` ## Output @@ -1649,6 +1657,13 @@ transform = ( x ) ) + +lambda x: (x := 1) + +( + lambda: # dangling header comment + (x := 1) +) ``` @@ -2567,4 +2582,14 @@ transform = ( x ) ) +@@ -837,6 +854,7 @@ + lambda x: (x := 1) + + ( +- lambda: # dangling header comment +- (x := 1) ++ lambda: ( # dangling header comment ++ x := 1 ++ ) + ) ```