mirror of
https://github.com/astral-sh/ruff.git
synced 2025-08-03 02:13:08 +00:00
Use space
separator before parenthesiszed expressions in comprehensions with leading comments. (#12282)
This commit is contained in:
parent
d0298dc26d
commit
bd01004a42
4 changed files with 274 additions and 6 deletions
|
@ -105,3 +105,66 @@ aaaaaaaaaaaaaaaaaaaaa = [
|
|||
# Parenthesized targets and iterators.
|
||||
[x for (x) in y]
|
||||
[x for x in (y)]
|
||||
|
||||
|
||||
# Leading expression comments:
|
||||
y = [
|
||||
a
|
||||
for (
|
||||
# comment
|
||||
a
|
||||
) in (
|
||||
# comment
|
||||
x
|
||||
)
|
||||
if (
|
||||
# asdasd
|
||||
"askldaklsdnmklasmdlkasmdlkasmdlkasmdasd"
|
||||
!= "as,mdnaskldmlkasdmlaksdmlkasdlkasdm"
|
||||
and "zxcm,.nzxclm,zxnckmnzxckmnzxczxc" != "zxcasdasdlmnasdlknaslkdnmlaskdm"
|
||||
)
|
||||
if (
|
||||
# comment
|
||||
x
|
||||
)
|
||||
]
|
||||
|
||||
# Tuple target:
|
||||
y = [
|
||||
a
|
||||
for
|
||||
# comment
|
||||
a, b
|
||||
in x
|
||||
if True
|
||||
]
|
||||
|
||||
|
||||
y = [
|
||||
a
|
||||
for (
|
||||
# comment
|
||||
a, b
|
||||
)
|
||||
in x
|
||||
if True
|
||||
]
|
||||
|
||||
|
||||
y = [
|
||||
a
|
||||
for
|
||||
# comment
|
||||
a
|
||||
in
|
||||
# comment
|
||||
x
|
||||
if
|
||||
# asdasd
|
||||
"askldaklsdnmklasmdlkasmdlkasmdlkasmdasd"
|
||||
!= "as,mdnaskldmlkasdmlaksdmlkasdlkasdm"
|
||||
and "zxcm,.nzxclm,zxnckmnzxckmnzxczxc" != "zxcasdasdlmnasdlknaslkdnmlaskdm"
|
||||
if
|
||||
# comment
|
||||
x
|
||||
]
|
||||
|
|
|
@ -5,18 +5,47 @@ use ruff_text_size::{Ranged, TextRange};
|
|||
|
||||
use crate::comments::{leading_comments, trailing_comments};
|
||||
use crate::expression::expr_tuple::TupleParentheses;
|
||||
use crate::expression::parentheses::is_expression_parenthesized;
|
||||
use crate::prelude::*;
|
||||
use crate::preview::is_comprehension_leading_expression_comments_same_line_enabled;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct FormatComprehension;
|
||||
|
||||
impl FormatNodeRule<Comprehension> for FormatComprehension {
|
||||
fn fmt_fields(&self, item: &Comprehension, f: &mut PyFormatter) -> FormatResult<()> {
|
||||
struct Spacer<'a>(&'a Expr);
|
||||
struct Spacer<'a> {
|
||||
expression: &'a Expr,
|
||||
preserve_parentheses: bool,
|
||||
}
|
||||
|
||||
impl Format<PyFormatContext<'_>> for Spacer<'_> {
|
||||
fn fmt(&self, f: &mut PyFormatter) -> FormatResult<()> {
|
||||
if f.context().comments().has_leading(self.0) {
|
||||
let has_leading_comments = f.context().comments().has_leading(self.expression);
|
||||
|
||||
// Don't add a soft line break for parenthesized expressions with a leading comment.
|
||||
// The comments are rendered **inside** the parentheses and adding a softline break
|
||||
// unnecessarily forces the parentheses to be on their own line.
|
||||
// ```python
|
||||
// y = [
|
||||
// ...
|
||||
// if
|
||||
// (
|
||||
// # See how the `(` gets forced on its own line? We don't want that.
|
||||
// ...
|
||||
// )
|
||||
// ]
|
||||
// ```
|
||||
let will_be_parenthesized =
|
||||
is_comprehension_leading_expression_comments_same_line_enabled(f.context())
|
||||
&& self.preserve_parentheses
|
||||
&& is_expression_parenthesized(
|
||||
self.expression.into(),
|
||||
f.context().comments().ranges(),
|
||||
f.context().source(),
|
||||
);
|
||||
|
||||
if has_leading_comments && !will_be_parenthesized {
|
||||
soft_line_break_or_space().fmt(f)
|
||||
} else {
|
||||
space().fmt(f)
|
||||
|
@ -68,13 +97,19 @@ impl FormatNodeRule<Comprehension> for FormatComprehension {
|
|||
[
|
||||
token("for"),
|
||||
trailing_comments(before_target_comments),
|
||||
Spacer(target),
|
||||
Spacer {
|
||||
expression: target,
|
||||
preserve_parentheses: !target.is_tuple_expr()
|
||||
},
|
||||
ExprTupleWithoutParentheses(target),
|
||||
in_spacer,
|
||||
leading_comments(before_in_comments),
|
||||
token("in"),
|
||||
trailing_comments(trailing_in_comments),
|
||||
Spacer(iter),
|
||||
Spacer {
|
||||
expression: iter,
|
||||
preserve_parentheses: true
|
||||
},
|
||||
iter.format(),
|
||||
]
|
||||
)?;
|
||||
|
@ -99,7 +134,10 @@ impl FormatNodeRule<Comprehension> for FormatComprehension {
|
|||
leading_comments(own_line_if_comments),
|
||||
token("if"),
|
||||
trailing_comments(end_of_line_if_comments),
|
||||
Spacer(if_case),
|
||||
Spacer {
|
||||
expression: if_case,
|
||||
preserve_parentheses: true
|
||||
},
|
||||
if_case.format(),
|
||||
));
|
||||
|
||||
|
|
|
@ -22,3 +22,10 @@ pub(crate) fn is_f_string_formatting_enabled(context: &PyFormatContext) -> bool
|
|||
pub(crate) fn is_with_single_item_pre_39_enabled(context: &PyFormatContext) -> bool {
|
||||
context.is_preview()
|
||||
}
|
||||
|
||||
/// See [#12282](https://github.com/astral-sh/ruff/pull/12282).
|
||||
pub(crate) fn is_comprehension_leading_expression_comments_same_line_enabled(
|
||||
context: &PyFormatContext,
|
||||
) -> bool {
|
||||
context.is_preview()
|
||||
}
|
||||
|
|
|
@ -111,6 +111,69 @@ aaaaaaaaaaaaaaaaaaaaa = [
|
|||
# Parenthesized targets and iterators.
|
||||
[x for (x) in y]
|
||||
[x for x in (y)]
|
||||
|
||||
|
||||
# Leading expression comments:
|
||||
y = [
|
||||
a
|
||||
for (
|
||||
# comment
|
||||
a
|
||||
) in (
|
||||
# comment
|
||||
x
|
||||
)
|
||||
if (
|
||||
# asdasd
|
||||
"askldaklsdnmklasmdlkasmdlkasmdlkasmdasd"
|
||||
!= "as,mdnaskldmlkasdmlaksdmlkasdlkasdm"
|
||||
and "zxcm,.nzxclm,zxnckmnzxckmnzxczxc" != "zxcasdasdlmnasdlknaslkdnmlaskdm"
|
||||
)
|
||||
if (
|
||||
# comment
|
||||
x
|
||||
)
|
||||
]
|
||||
|
||||
# Tuple target:
|
||||
y = [
|
||||
a
|
||||
for
|
||||
# comment
|
||||
a, b
|
||||
in x
|
||||
if True
|
||||
]
|
||||
|
||||
|
||||
y = [
|
||||
a
|
||||
for (
|
||||
# comment
|
||||
a, b
|
||||
)
|
||||
in x
|
||||
if True
|
||||
]
|
||||
|
||||
|
||||
y = [
|
||||
a
|
||||
for
|
||||
# comment
|
||||
a
|
||||
in
|
||||
# comment
|
||||
x
|
||||
if
|
||||
# asdasd
|
||||
"askldaklsdnmklasmdlkasmdlkasmdlkasmdasd"
|
||||
!= "as,mdnaskldmlkasdmlaksdmlkasdlkasdm"
|
||||
and "zxcm,.nzxclm,zxnckmnzxckmnzxczxc" != "zxcasdasdlmnasdlknaslkdnmlaskdm"
|
||||
if
|
||||
# comment
|
||||
x
|
||||
]
|
||||
```
|
||||
|
||||
## Output
|
||||
|
@ -254,7 +317,104 @@ aaaaaaaaaaaaaaaaaaaaa = [
|
|||
# Parenthesized targets and iterators.
|
||||
[x for (x) in y]
|
||||
[x for x in (y)]
|
||||
|
||||
|
||||
# Leading expression comments:
|
||||
y = [
|
||||
a
|
||||
for
|
||||
(
|
||||
# comment
|
||||
a
|
||||
) in
|
||||
(
|
||||
# comment
|
||||
x
|
||||
)
|
||||
if
|
||||
(
|
||||
# asdasd
|
||||
"askldaklsdnmklasmdlkasmdlkasmdlkasmdasd"
|
||||
!= "as,mdnaskldmlkasdmlaksdmlkasdlkasdm"
|
||||
and "zxcm,.nzxclm,zxnckmnzxckmnzxczxc" != "zxcasdasdlmnasdlknaslkdnmlaskdm"
|
||||
)
|
||||
if
|
||||
(
|
||||
# comment
|
||||
x
|
||||
)
|
||||
]
|
||||
|
||||
# Tuple target:
|
||||
y = [
|
||||
a
|
||||
for
|
||||
# comment
|
||||
a, b in x
|
||||
if True
|
||||
]
|
||||
|
||||
|
||||
y = [
|
||||
a
|
||||
for (
|
||||
# comment
|
||||
a,
|
||||
b,
|
||||
) in x
|
||||
if True
|
||||
]
|
||||
|
||||
|
||||
y = [
|
||||
a
|
||||
for
|
||||
# comment
|
||||
a in
|
||||
# comment
|
||||
x
|
||||
if
|
||||
# asdasd
|
||||
"askldaklsdnmklasmdlkasmdlkasmdlkasmdasd" != "as,mdnaskldmlkasdmlaksdmlkasdlkasdm"
|
||||
and "zxcm,.nzxclm,zxnckmnzxckmnzxczxc" != "zxcasdasdlmnasdlknaslkdnmlaskdm"
|
||||
if
|
||||
# comment
|
||||
x
|
||||
]
|
||||
```
|
||||
|
||||
|
||||
|
||||
## Preview changes
|
||||
```diff
|
||||
--- Stable
|
||||
+++ Preview
|
||||
@@ -142,24 +142,20 @@
|
||||
# Leading expression comments:
|
||||
y = [
|
||||
a
|
||||
- for
|
||||
- (
|
||||
+ for (
|
||||
# comment
|
||||
a
|
||||
- ) in
|
||||
- (
|
||||
+ ) in (
|
||||
# comment
|
||||
x
|
||||
)
|
||||
- if
|
||||
- (
|
||||
+ if (
|
||||
# asdasd
|
||||
"askldaklsdnmklasmdlkasmdlkasmdlkasmdasd"
|
||||
!= "as,mdnaskldmlkasdmlaksdmlkasdlkasdm"
|
||||
and "zxcm,.nzxclm,zxnckmnzxckmnzxczxc" != "zxcasdasdlmnasdlknaslkdnmlaskdm"
|
||||
)
|
||||
- if
|
||||
- (
|
||||
+ if (
|
||||
# comment
|
||||
x
|
||||
)
|
||||
```
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue