mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-26 11:59:35 +00:00
Preserve parentheses around partial call chains (#7109)
This commit is contained in:
parent
7be28a38c5
commit
ece30e7c69
4 changed files with 207 additions and 38 deletions
|
@ -161,3 +161,58 @@ max_message_id = (
|
||||||
max_message_id = (
|
max_message_id = (
|
||||||
Message.objects.filter(recipient=recipient).order_by("id").reverse()[0].id()
|
Message.objects.filter(recipient=recipient).order_by("id").reverse()[0].id()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Parentheses with fluent style within and outside of the parentheses.
|
||||||
|
(
|
||||||
|
(
|
||||||
|
df1_aaaaaaaaaaaa.merge()
|
||||||
|
)
|
||||||
|
.groupby(1,)
|
||||||
|
.sum()
|
||||||
|
)
|
||||||
|
|
||||||
|
(
|
||||||
|
( # foo
|
||||||
|
df1_aaaaaaaaaaaa.merge()
|
||||||
|
)
|
||||||
|
.groupby(1,)
|
||||||
|
.sum()
|
||||||
|
)
|
||||||
|
|
||||||
|
(
|
||||||
|
(
|
||||||
|
df1_aaaaaaaaaaaa.merge()
|
||||||
|
.groupby(1,)
|
||||||
|
)
|
||||||
|
.sum()
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
(
|
||||||
|
(
|
||||||
|
df1_aaaaaaaaaaaa.merge()
|
||||||
|
.groupby(1,)
|
||||||
|
)
|
||||||
|
.sum()
|
||||||
|
.bar()
|
||||||
|
)
|
||||||
|
|
||||||
|
(
|
||||||
|
(
|
||||||
|
df1_aaaaaaaaaaaa.merge()
|
||||||
|
.groupby(1,)
|
||||||
|
.bar()
|
||||||
|
)
|
||||||
|
.sum()
|
||||||
|
)
|
||||||
|
|
||||||
|
(
|
||||||
|
(
|
||||||
|
df1_aaaaaaaaaaaa.merge()
|
||||||
|
.groupby(1,)
|
||||||
|
.bar()
|
||||||
|
)
|
||||||
|
.sum()
|
||||||
|
.baz()
|
||||||
|
)
|
||||||
|
|
||||||
|
|
|
@ -37,49 +37,45 @@ impl FormatNodeRule<ExprAttribute> for FormatExprAttribute {
|
||||||
let call_chain_layout = self.call_chain_layout.apply_in_node(item, f);
|
let call_chain_layout = self.call_chain_layout.apply_in_node(item, f);
|
||||||
|
|
||||||
let format_inner = format_with(|f: &mut PyFormatter| {
|
let format_inner = format_with(|f: &mut PyFormatter| {
|
||||||
let needs_parentheses = matches!(
|
let parenthesize_value =
|
||||||
value.as_ref(),
|
// If the value is an integer, we need to parenthesize it to avoid a syntax error.
|
||||||
Expr::Constant(ExprConstant {
|
matches!(
|
||||||
value: Constant::Int(_) | Constant::Float(_),
|
value.as_ref(),
|
||||||
..
|
Expr::Constant(ExprConstant {
|
||||||
})
|
value: Constant::Int(_) | Constant::Float(_),
|
||||||
);
|
..
|
||||||
|
})
|
||||||
|
) || is_expression_parenthesized(value.into(), f.context().source());
|
||||||
|
|
||||||
if needs_parentheses {
|
if call_chain_layout == CallChainLayout::Fluent {
|
||||||
value.format().with_options(Parentheses::Always).fmt(f)?;
|
if parenthesize_value {
|
||||||
} else if call_chain_layout == CallChainLayout::Fluent {
|
// Don't propagate the call chain layout.
|
||||||
match value.as_ref() {
|
value.format().with_options(Parentheses::Always).fmt(f)?;
|
||||||
Expr::Attribute(expr) => {
|
|
||||||
expr.format().with_options(call_chain_layout).fmt(f)?;
|
// Format the dot on its own line.
|
||||||
}
|
soft_line_break().fmt(f)?;
|
||||||
Expr::Call(expr) => {
|
} else {
|
||||||
expr.format().with_options(call_chain_layout).fmt(f)?;
|
match value.as_ref() {
|
||||||
if call_chain_layout == CallChainLayout::Fluent {
|
Expr::Attribute(expr) => {
|
||||||
// Format the dot on its own line
|
expr.format().with_options(call_chain_layout).fmt(f)?;
|
||||||
|
}
|
||||||
|
Expr::Call(expr) => {
|
||||||
|
expr.format().with_options(call_chain_layout).fmt(f)?;
|
||||||
soft_line_break().fmt(f)?;
|
soft_line_break().fmt(f)?;
|
||||||
}
|
}
|
||||||
}
|
Expr::Subscript(expr) => {
|
||||||
Expr::Subscript(expr) => {
|
expr.format().with_options(call_chain_layout).fmt(f)?;
|
||||||
expr.format().with_options(call_chain_layout).fmt(f)?;
|
|
||||||
if call_chain_layout == CallChainLayout::Fluent {
|
|
||||||
// Format the dot on its own line
|
|
||||||
soft_line_break().fmt(f)?;
|
soft_line_break().fmt(f)?;
|
||||||
}
|
}
|
||||||
}
|
_ => {
|
||||||
_ => {
|
value.format().with_options(Parentheses::Never).fmt(f)?;
|
||||||
// This matches [`CallChainLayout::from_expression`]
|
|
||||||
if is_expression_parenthesized(value.as_ref().into(), f.context().source())
|
|
||||||
{
|
|
||||||
value.format().with_options(Parentheses::Always).fmt(f)?;
|
|
||||||
// Format the dot on its own line
|
|
||||||
soft_line_break().fmt(f)?;
|
|
||||||
} else {
|
|
||||||
value.format().fmt(f)?;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if parenthesize_value {
|
||||||
|
value.format().with_options(Parentheses::Always).fmt(f)?;
|
||||||
} else {
|
} else {
|
||||||
value.format().fmt(f)?;
|
value.format().with_options(Parentheses::Never).fmt(f)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Identify dangling comments before and after the dot:
|
// Identify dangling comments before and after the dot:
|
||||||
|
|
|
@ -630,20 +630,21 @@ impl CallChainLayout {
|
||||||
loop {
|
loop {
|
||||||
match expr {
|
match expr {
|
||||||
ExpressionRef::Attribute(ast::ExprAttribute { value, .. }) => {
|
ExpressionRef::Attribute(ast::ExprAttribute { value, .. }) => {
|
||||||
expr = ExpressionRef::from(value.as_ref());
|
|
||||||
// ```
|
// ```
|
||||||
// f().g
|
// f().g
|
||||||
// ^^^ value
|
// ^^^ value
|
||||||
// data[:100].T
|
// data[:100].T
|
||||||
// ^^^^^^^^^^ value
|
// ^^^^^^^^^^ value
|
||||||
// ```
|
// ```
|
||||||
if matches!(value.as_ref(), Expr::Call(_) | Expr::Subscript(_)) {
|
if is_expression_parenthesized(value.into(), source) {
|
||||||
attributes_after_parentheses += 1;
|
|
||||||
} else if is_expression_parenthesized(expr, source) {
|
|
||||||
// `(a).b`. We preserve these parentheses so don't recurse
|
// `(a).b`. We preserve these parentheses so don't recurse
|
||||||
attributes_after_parentheses += 1;
|
attributes_after_parentheses += 1;
|
||||||
break;
|
break;
|
||||||
|
} else if matches!(value.as_ref(), Expr::Call(_) | Expr::Subscript(_)) {
|
||||||
|
attributes_after_parentheses += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
expr = ExpressionRef::from(value.as_ref());
|
||||||
}
|
}
|
||||||
// ```
|
// ```
|
||||||
// f()
|
// f()
|
||||||
|
@ -666,9 +667,11 @@ impl CallChainLayout {
|
||||||
if is_expression_parenthesized(expr, source) {
|
if is_expression_parenthesized(expr, source) {
|
||||||
attributes_after_parentheses += 1;
|
attributes_after_parentheses += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// We preserve these parentheses so don't recurse
|
// We preserve these parentheses so don't recurse
|
||||||
if is_expression_parenthesized(expr, source) {
|
if is_expression_parenthesized(expr, source) {
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -167,6 +167,61 @@ max_message_id = (
|
||||||
max_message_id = (
|
max_message_id = (
|
||||||
Message.objects.filter(recipient=recipient).order_by("id").reverse()[0].id()
|
Message.objects.filter(recipient=recipient).order_by("id").reverse()[0].id()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Parentheses with fluent style within and outside of the parentheses.
|
||||||
|
(
|
||||||
|
(
|
||||||
|
df1_aaaaaaaaaaaa.merge()
|
||||||
|
)
|
||||||
|
.groupby(1,)
|
||||||
|
.sum()
|
||||||
|
)
|
||||||
|
|
||||||
|
(
|
||||||
|
( # foo
|
||||||
|
df1_aaaaaaaaaaaa.merge()
|
||||||
|
)
|
||||||
|
.groupby(1,)
|
||||||
|
.sum()
|
||||||
|
)
|
||||||
|
|
||||||
|
(
|
||||||
|
(
|
||||||
|
df1_aaaaaaaaaaaa.merge()
|
||||||
|
.groupby(1,)
|
||||||
|
)
|
||||||
|
.sum()
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
(
|
||||||
|
(
|
||||||
|
df1_aaaaaaaaaaaa.merge()
|
||||||
|
.groupby(1,)
|
||||||
|
)
|
||||||
|
.sum()
|
||||||
|
.bar()
|
||||||
|
)
|
||||||
|
|
||||||
|
(
|
||||||
|
(
|
||||||
|
df1_aaaaaaaaaaaa.merge()
|
||||||
|
.groupby(1,)
|
||||||
|
.bar()
|
||||||
|
)
|
||||||
|
.sum()
|
||||||
|
)
|
||||||
|
|
||||||
|
(
|
||||||
|
(
|
||||||
|
df1_aaaaaaaaaaaa.merge()
|
||||||
|
.groupby(1,)
|
||||||
|
.bar()
|
||||||
|
)
|
||||||
|
.sum()
|
||||||
|
.baz()
|
||||||
|
)
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Output
|
## Output
|
||||||
|
@ -350,6 +405,66 @@ max_message_id = (
|
||||||
max_message_id = (
|
max_message_id = (
|
||||||
Message.objects.filter(recipient=recipient).order_by("id").reverse()[0].id()
|
Message.objects.filter(recipient=recipient).order_by("id").reverse()[0].id()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Parentheses with fluent style within and outside of the parentheses.
|
||||||
|
(
|
||||||
|
(df1_aaaaaaaaaaaa.merge())
|
||||||
|
.groupby(
|
||||||
|
1,
|
||||||
|
)
|
||||||
|
.sum()
|
||||||
|
)
|
||||||
|
|
||||||
|
(
|
||||||
|
( # foo
|
||||||
|
df1_aaaaaaaaaaaa.merge()
|
||||||
|
)
|
||||||
|
.groupby(
|
||||||
|
1,
|
||||||
|
)
|
||||||
|
.sum()
|
||||||
|
)
|
||||||
|
|
||||||
|
(
|
||||||
|
(
|
||||||
|
df1_aaaaaaaaaaaa.merge().groupby(
|
||||||
|
1,
|
||||||
|
)
|
||||||
|
).sum()
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
(
|
||||||
|
(
|
||||||
|
df1_aaaaaaaaaaaa.merge().groupby(
|
||||||
|
1,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.sum()
|
||||||
|
.bar()
|
||||||
|
)
|
||||||
|
|
||||||
|
(
|
||||||
|
(
|
||||||
|
df1_aaaaaaaaaaaa.merge()
|
||||||
|
.groupby(
|
||||||
|
1,
|
||||||
|
)
|
||||||
|
.bar()
|
||||||
|
).sum()
|
||||||
|
)
|
||||||
|
|
||||||
|
(
|
||||||
|
(
|
||||||
|
df1_aaaaaaaaaaaa.merge()
|
||||||
|
.groupby(
|
||||||
|
1,
|
||||||
|
)
|
||||||
|
.bar()
|
||||||
|
)
|
||||||
|
.sum()
|
||||||
|
.baz()
|
||||||
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue