move preview comment handling mostly into placement.rs

This commit is contained in:
Brent Westbrook 2025-12-10 09:36:48 -05:00
parent 33fcca9c53
commit 9f9b76b035
No known key found for this signature in database
3 changed files with 52 additions and 102 deletions

View File

@ -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)
};
}
}

View File

@ -127,51 +127,6 @@ impl FormatNodeRule<ExprLambda> 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<ExprLambda> 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<ExprLambda> 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

View File

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