This commit is contained in:
Brent Westbrook 2025-11-16 22:49:15 +08:00 committed by GitHub
commit 62a299fae2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 531 additions and 16 deletions

View file

@ -125,6 +125,13 @@ lambda a, /, c: a
*x: x
)
(
lambda
# comment
*x,
**y: x
)
(
lambda
# comment 1
@ -196,6 +203,17 @@ lambda: ( # comment
x
)
(
lambda # 1
# 2
x, # 3
# 4
y
: # 5
# 6
x
)
(
lambda
x,
@ -204,6 +222,71 @@ lambda: ( # comment
z
)
# Leading
lambda x: (
lambda y: lambda z: x
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ z # Trailing
) # Trailing
# Leading
lambda x: lambda y: lambda z: [
x,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
z
] # Trailing
# Trailing
lambda self, araa, kkkwargs=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(*args, **kwargs), e=1, f=2, g=2: d
# Regression tests for https://github.com/astral-sh/ruff/issues/8179

View file

@ -1,12 +1,16 @@
use ruff_formatter::RemoveSoftLinesBuffer;
use ruff_formatter::write;
use ruff_python_ast::AnyNodeRef;
use ruff_python_ast::ExprLambda;
use ruff_text_size::Ranged;
use crate::comments::dangling_comments;
use crate::expression::parentheses::{NeedsParentheses, OptionalParentheses};
use crate::expression::parentheses::{NeedsParentheses, OptionalParentheses, Parenthesize};
use crate::expression::{has_own_parentheses, maybe_parenthesize_expression};
use crate::other::parameters::ParametersParentheses;
use crate::prelude::*;
use crate::preview::is_force_single_line_lambda_parameters_enabled;
use crate::preview::is_parenthesize_lambda_bodies_enabled;
#[derive(Default)]
pub struct FormatExprLambda;
@ -26,7 +30,7 @@ impl FormatNodeRule<ExprLambda> for FormatExprLambda {
write!(f, [token("lambda")])?;
if let Some(parameters) = parameters {
// In this context, a dangling comment can either be a comment between the `lambda` the
// In this context, a dangling comment can either be a comment between the `lambda` and the
// parameters, or a comment between the parameters and the body.
let (dangling_before_parameters, dangling_after_parameters) = dangling
.split_at(dangling.partition_point(|comment| comment.end() < parameters.start()));
@ -37,12 +41,25 @@ impl FormatNodeRule<ExprLambda> for FormatExprLambda {
write!(f, [dangling_comments(dangling_before_parameters)])?;
}
write!(
f,
[parameters
.format()
.with_options(ParametersParentheses::Never)]
)?;
// Try to keep the parameters on a single line, unless there are intervening comments.
if is_force_single_line_lambda_parameters_enabled(f.context())
&& !comments.contains_comments(parameters.as_ref().into())
{
let mut buffer = RemoveSoftLinesBuffer::new(f);
write!(
buffer,
[parameters
.format()
.with_options(ParametersParentheses::Never)]
)?;
} else {
write!(
f,
[parameters
.format()
.with_options(ParametersParentheses::Never)]
)?;
}
write!(f, [token(":")])?;
@ -62,7 +79,15 @@ impl FormatNodeRule<ExprLambda> for FormatExprLambda {
}
}
write!(f, [body.format()])
// Avoid parenthesizing lists, dictionaries, etc.
if is_parenthesize_lambda_bodies_enabled(f.context())
&& has_own_parentheses(body, f.context()).is_none()
{
maybe_parenthesize_expression(body, item, Parenthesize::IfBreaksParenthesizedNested)
.fmt(f)
} else {
body.format().fmt(f)
}
}
}

View file

@ -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 {

View file

@ -52,3 +52,19 @@ pub(crate) const fn is_avoid_parens_for_long_as_captures_enabled(
) -> bool {
context.is_preview()
}
/// Returns `true` if the
/// [`parenthesize_lambda_bodies`](https://github.com/astral-sh/ruff/pull/21385) preview style is
/// enabled.
pub(crate) const fn is_parenthesize_lambda_bodies_enabled(context: &PyFormatContext) -> bool {
context.is_preview()
}
/// Returns `true` if the
/// [`force_single_line_lambda_parameters`](https://github.com/astral-sh/ruff/pull/21385) preview
/// style is enabled.
pub(crate) const fn is_force_single_line_lambda_parameters_enabled(
context: &PyFormatContext,
) -> bool {
context.is_preview()
}

View file

@ -854,7 +854,7 @@ x = {
long_unmergable_string_with_pragma = (
"This is a really long string that can't be merged because it has a likely pragma at the end" # type: ignore
@@ -468,49 +358,24 @@
@@ -468,49 +358,26 @@
" of it."
)
@ -910,11 +910,13 @@ x = {
- f"this is a very very very very long lambda value {x} that doesn't fit on a"
- " single line"
+msg = (
+ lambda x: f"this is a very very very very long lambda value {x} that doesn't fit on a single line"
+ lambda x: (
+ f"this is a very very very very long lambda value {x} that doesn't fit on a single line"
+ )
)
dict_with_lambda_values = {
@@ -522,65 +387,58 @@
@@ -522,65 +389,58 @@
# Complex string concatenations with a method call in the middle.
code = (
@ -998,7 +1000,7 @@ x = {
)
log.info(
@@ -588,7 +446,7 @@
@@ -588,7 +448,7 @@
)
log.info(
@ -1007,7 +1009,7 @@ x = {
)
x = {
@@ -597,10 +455,10 @@
@@ -597,10 +457,10 @@
)
}
x = {
@ -1404,7 +1406,9 @@ string_with_escaped_nameescape = "..............................................
string_with_escaped_nameescape = "........................................................................... \\N{LAO KO LA}"
msg = (
lambda x: f"this is a very very very very long lambda value {x} that doesn't fit on a single line"
lambda x: (
f"this is a very very very very long lambda value {x} that doesn't fit on a single line"
)
)
dict_with_lambda_values = {

View file

@ -1,7 +1,6 @@
---
source: crates/ruff_python_formatter/tests/fixtures.rs
input_file: crates/ruff_python_formatter/resources/test/fixtures/ruff/expression/lambda.py
snapshot_kind: text
---
## Input
```python
@ -132,6 +131,13 @@ lambda a, /, c: a
*x: x
)
(
lambda
# comment
*x,
**y: x
)
(
lambda
# comment 1
@ -203,6 +209,17 @@ lambda: ( # comment
x
)
(
lambda # 1
# 2
x, # 3
# 4
y
: # 5
# 6
x
)
(
lambda
x,
@ -211,6 +228,71 @@ lambda: ( # comment
z
)
# Leading
lambda x: (
lambda y: lambda z: x
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ z # Trailing
) # Trailing
# Leading
lambda x: lambda y: lambda z: [
x,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
z
] # Trailing
# Trailing
lambda self, araa, kkkwargs=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(*args, **kwargs), e=1, f=2, g=2: d
# Regression tests for https://github.com/astral-sh/ruff/issues/8179
@ -367,6 +449,12 @@ lambda a, /, c: a
*x: x
)
(
lambda
# comment
*x, **y: x
)
(
lambda
# comment 1
@ -434,12 +522,87 @@ lambda: ( # comment
x
)
(
lambda # 1
# 2
x, # 3
# 4
y: # 5
# 6
x
)
(
lambda x,
# comment
y: z
)
# Leading
lambda x: (
lambda y: lambda z: x
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ y
+ z # Trailing
) # Trailing
# Leading
lambda x: lambda y: lambda z: [
x,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
y,
z,
] # Trailing
# Trailing
lambda self, araa, kkkwargs=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(
*args, **kwargs
), e=1, f=2, g=2: d
@ -474,3 +637,226 @@ def a():
g=10,
)
```
## Preview changes
```diff
--- Stable
+++ Preview
@@ -27,30 +27,10 @@
# Trailing
# Leading
-lambda x: lambda y: lambda z: (
- x,
- y,
- y,
- y,
- y,
- y,
- y,
- y,
- y,
- y,
- y,
- y,
- y,
- y,
- y,
- y,
- y,
- y,
- y,
- y,
- y,
- y,
- z,
+lambda x: (
+ lambda y: (
+ lambda z: (x, y, y, y, y, y, y, y, y, y, y, y, y, y, y, y, y, y, y, y, y, y, z)
+ )
) # Trailing
# Trailing
@@ -74,7 +54,9 @@
# lambda arguments don't have parentheses, so we never add a magic trailing comma ...
def f(
- aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb = lambda x: y,
+ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb = lambda x: (
+ y
+ ),
):
pass
@@ -218,71 +200,79 @@
# Leading
lambda x: (
- lambda y: lambda z: x
- + y
- + y
- + y
- + y
- + y
- + y
- + y
- + y
- + y
- + y
- + y
- + y
- + y
- + y
- + y
- + y
- + y
- + y
- + y
- + y
- + y
- + z # Trailing
+ lambda y: (
+ lambda z: (
+ x
+ + y
+ + y
+ + y
+ + y
+ + y
+ + y
+ + y
+ + y
+ + y
+ + y
+ + y
+ + y
+ + y
+ + y
+ + y
+ + y
+ + y
+ + y
+ + y
+ + y
+ + y
+ + z
+ )
+ ) # Trailing
) # Trailing
# Leading
-lambda x: lambda y: lambda z: [
- x,
- y,
- y,
- y,
- y,
- y,
- y,
- y,
- y,
- y,
- y,
- y,
- y,
- y,
- y,
- y,
- y,
- y,
- y,
- y,
- y,
- y,
- y,
- y,
- y,
- y,
- y,
- y,
- y,
- y,
- z,
-] # Trailing
+lambda x: (
+ lambda y: (
+ lambda z: [
+ x,
+ y,
+ y,
+ y,
+ y,
+ y,
+ y,
+ y,
+ y,
+ y,
+ y,
+ y,
+ y,
+ y,
+ y,
+ y,
+ y,
+ y,
+ y,
+ y,
+ y,
+ y,
+ y,
+ y,
+ y,
+ y,
+ y,
+ y,
+ y,
+ y,
+ z,
+ ]
+ )
+) # Trailing
# Trailing
-lambda self, araa, kkkwargs=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(
- *args, **kwargs
-), e=1, f=2, g=2: d
+lambda self, araa, kkkwargs=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(*args, **kwargs), e=1, f=2, g=2: (
+ d
+)
# Regression tests for https://github.com/astral-sh/ruff/issues/8179
@@ -291,9 +281,9 @@
c,
d,
e,
- f=lambda self,
- *args,
- **kwargs: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(*args, **kwargs),
+ f=lambda self, *args, **kwargs: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(
+ *args, **kwargs
+ ),
)
@@ -302,14 +292,8 @@
c,
d,
e,
- f=lambda self,
- araa,
- kkkwargs,
- aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,
- args,
- kwargs,
- e=1,
- f=2,
- g=2: d,
+ f=lambda self, araa, kkkwargs, aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, args, kwargs, e=1, f=2, g=2: (
+ d
+ ),
g=10,
)
```