reposition dangling comments

This commit is contained in:
Brent Westbrook 2025-12-11 11:43:03 -05:00
parent 8711b1a301
commit 0f1ea90c5c
No known key found for this signature in database
3 changed files with 148 additions and 48 deletions

View File

@ -789,3 +789,18 @@ transform = lambda left, right: ibis.timestamp("2017-04-01").cast(dt.date).betwe
x:
x
)
(
lambda: # dangling-end-of-line
# dangling-own-line
( # leading-body-end-of-line
x
)
)
(
lambda: # dangling-end-of-line
( # leading-body-end-of-line
x
)
)

View File

@ -4,7 +4,9 @@ use ruff_text_size::Ranged;
use crate::builders::parenthesize_if_expands;
use crate::comments::{SourceComment, dangling_comments, leading_comments, trailing_comments};
use crate::expression::parentheses::{NeedsParentheses, OptionalParentheses, Parentheses};
use crate::expression::parentheses::{
NeedsParentheses, OptionalParentheses, Parentheses, is_expression_parenthesized,
};
use crate::expression::{CallChainLayout, has_own_parentheses};
use crate::other::parameters::ParametersParentheses;
use crate::prelude::*;
@ -377,19 +379,72 @@ impl Format<PyFormatContext<'_>> for FormatBody<'_> {
);
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(")")
]
)
// If the body is parenthesized and has its own leading comments, preserve the
// separation between the dangling lambda comments and the body comments. For example,
// preserve this comment positioning:
//
// ```python
// (
// lambda: # 1
// # 2
// ( # 3
// x
// )
// )
// ```
//
// 1 and 2 are dangling on the lambda and emitted first, followed by a hard line break
// and the parenthesized body with its leading comments.
//
// However, when removing 2, 1 and 3 can instead be formatted on the same line:
//
// ```python
// (
// lambda: ( # 1 # 3
// x
// )
// )
// ```
if is_expression_parenthesized(
(*body).into(),
f.context().comments().ranges(),
f.context().source(),
) && f.context().comments().has_leading(*body)
{
if leading_body_comments.is_empty() {
write!(
f,
[
space(),
trailing_comments(dangling),
body.format().with_options(Parentheses::Always),
]
)
} else {
write!(
f,
[
trailing_comments(dangling),
hard_line_break(),
body.format().with_options(Parentheses::Always)
]
)
}
} else {
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(")")
]
)
}
});
match layout {

View File

@ -795,6 +795,21 @@ transform = lambda left, right: ibis.timestamp("2017-04-01").cast(dt.date).betwe
x:
x
)
(
lambda: # dangling-end-of-line
# dangling-own-line
( # leading-body-end-of-line
x
)
)
(
lambda: # dangling-end-of-line
( # leading-body-end-of-line
x
)
)
```
## Output
@ -1619,6 +1634,21 @@ transform = (
# comment 1
**x: x
)
(
lambda: # dangling-end-of-line
# dangling-own-line
( # leading-body-end-of-line
x
)
)
(
lambda: # dangling-end-of-line
( # leading-body-end-of-line
x
)
)
```
@ -1738,7 +1768,7 @@ transform = (
)
lambda *x: x
@@ -161,30 +147,34 @@
@@ -161,30 +147,33 @@
)
(
@ -1780,12 +1810,11 @@ transform = (
(
- lambda: # comment
- ( # comment
+ lambda: ( # comment
+ # comment
+ lambda: ( # comment # comment
x
)
)
@@ -192,11 +182,12 @@
@@ -192,11 +181,12 @@
(
lambda # 1
# 2
@ -1803,7 +1832,7 @@ transform = (
)
(
@@ -204,9 +195,10 @@
@@ -204,9 +194,10 @@
# 2
x, # 3
# 4
@ -1817,7 +1846,7 @@ transform = (
)
(
@@ -218,71 +210,79 @@
@@ -218,71 +209,79 @@
# Leading
lambda x: (
@ -1956,7 +1985,7 @@ transform = (
# Regression tests for https://github.com/astral-sh/ruff/issues/8179
@@ -291,9 +291,9 @@
@@ -291,9 +290,9 @@
c,
d,
e,
@ -1969,7 +1998,7 @@ transform = (
)
@@ -302,15 +302,9 @@
@@ -302,15 +301,9 @@
c,
d,
e,
@ -1988,7 +2017,7 @@ transform = (
g=10,
)
@@ -320,9 +314,9 @@
@@ -320,9 +313,9 @@
c,
d,
e,
@ -2001,7 +2030,7 @@ transform = (
)
@@ -338,9 +332,9 @@
@@ -338,9 +331,9 @@
class C:
function_dict: Dict[Text, Callable[[CRFToken], Any]] = {
@ -2014,7 +2043,7 @@ transform = (
}
@@ -352,42 +346,40 @@
@@ -352,42 +345,40 @@
def foo():
if True:
if True:
@ -2073,7 +2102,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
@ -2100,7 +2129,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,
)
@ -2111,7 +2140,7 @@ transform = (
x, more_args, additional_parameters
)
)
@@ -457,12 +450,12 @@
@@ -457,12 +449,12 @@
[
# Not fluent
param(
@ -2126,7 +2155,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(
@ -2139,7 +2168,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
@ -2161,7 +2190,7 @@ transform = (
lambda x, y, z: (
x + y + z
@@ -527,7 +522,7 @@
@@ -527,7 +521,7 @@
x + y + z # trailing eol body
)
@ -2170,7 +2199,7 @@ transform = (
lambda x, y, z: (
# leading body
@@ -539,21 +534,23 @@
@@ -539,21 +533,23 @@
)
(
@ -2204,7 +2233,7 @@ transform = (
# dangling header comment
source_bucket
if name == source_bucket_name
@@ -561,8 +558,7 @@
@@ -561,8 +557,7 @@
)
(
@ -2214,7 +2243,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 @@
)
(
@ -2317,7 +2346,7 @@ transform = (
)
(
@@ -637,33 +642,37 @@
@@ -637,27 +641,31 @@
(
lambda
# comment
@ -2357,16 +2386,7 @@ transform = (
)
(
- lambda *args, **kwargs:
- # comment 1
- ( # comment 2
+ lambda *args, **kwargs: (
+ # comment 1
+ # comment 2
# comment 3
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(*args, **kwargs)
+ 1 # comment 4
@@ -672,25 +681,28 @@
@@ -672,25 +680,28 @@
)
(
@ -2407,7 +2427,7 @@ transform = (
)
(
@@ -698,9 +710,9 @@
@@ -698,9 +709,9 @@
# comment 1
*ergs,
# comment 2
@ -2420,7 +2440,7 @@ transform = (
)
(
@@ -708,19 +720,20 @@
@@ -708,19 +719,20 @@
# 2
left, # 3
# 4
@ -2451,7 +2471,7 @@ transform = (
)
)
)
@@ -738,48 +751,52 @@
@@ -738,48 +750,52 @@
foo(
lambda from_ts, # but still wrap the body if it gets too long
to_ts,
@ -2528,4 +2548,14 @@ transform = (
)
(
@@ -828,8 +844,7 @@
)
(
- lambda: # dangling-end-of-line
- ( # leading-body-end-of-line
+ lambda: ( # dangling-end-of-line # leading-body-end-of-line
x
)
)
```