mirror of
https://github.com/astral-sh/ruff.git
synced 2025-08-03 02:12:22 +00:00
Avoid omitting parentheses for trailing attributes on call expressions (#6322)
## Summary This PR modifies our `can_omit_optional_parentheses` rules to ensure that if we see a call followed by an attribute, we treat that as an attribute access rather than a splittable call expression. This in turn ensures that we wrap like: ```python ct_match = aaaaaaaaaaact_id == self.get_content_type( obj=rel_obj, using=instance._state.db ) ``` For calls, but: ```python ct_match = ( aaaaaaaaaaact_id == self.get_content_type(obj=rel_obj, using=instance._state.db).id ) ``` For calls with trailing attribute accesses. Closes https://github.com/astral-sh/ruff/issues/6065. ## Test Plan Similarity index before: - `zulip`: 0.99436 - `django`: 0.99779 - `warehouse`: 0.99504 - `transformers`: 0.99403 - `cpython`: 0.75912 - `typeshed`: 0.72293 And after: - `zulip`: 0.99436 - `django`: 0.99780 - `warehouse`: 0.99504 - `transformers`: 0.99404 - `cpython`: 0.75913 - `typeshed`: 0.72293
This commit is contained in:
parent
c439435615
commit
63ffadf0b8
3 changed files with 162 additions and 2 deletions
|
@ -59,3 +59,55 @@ return 1 == 2 and (
|
||||||
>= c
|
>= c
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
def f():
|
||||||
|
return (
|
||||||
|
unicodedata.normalize("NFKC", s1).casefold()
|
||||||
|
== unicodedata.normalize("NFKC", s2).casefold()
|
||||||
|
)
|
||||||
|
|
||||||
|
# Call expressions with trailing attributes.
|
||||||
|
|
||||||
|
ct_match = (
|
||||||
|
aaaaaaaaaaact_id == self.get_content_type(obj=rel_obj, using=instance._state.db).id
|
||||||
|
)
|
||||||
|
|
||||||
|
ct_match = (
|
||||||
|
{aaaaaaaaaaaaaaaa} == self.get_content_type(obj=rel_obj, using=instance._state.db).id
|
||||||
|
)
|
||||||
|
|
||||||
|
ct_match = (
|
||||||
|
(aaaaaaaaaaaaaaaa) == self.get_content_type(obj=rel_obj, using=instance._state.db).id
|
||||||
|
)
|
||||||
|
|
||||||
|
ct_match = aaaaaaaaaaact_id == self.get_content_type(
|
||||||
|
obj=rel_obj, using=instance._state.db
|
||||||
|
)
|
||||||
|
|
||||||
|
# Call expressions with trailing subscripts.
|
||||||
|
|
||||||
|
ct_match = (
|
||||||
|
aaaaaaaaaaact_id == self.get_content_type(obj=rel_obj, using=instance._state.db)[id]
|
||||||
|
)
|
||||||
|
|
||||||
|
ct_match = (
|
||||||
|
{aaaaaaaaaaaaaaaa} == self.get_content_type(obj=rel_obj, using=instance._state.db)[id]
|
||||||
|
)
|
||||||
|
|
||||||
|
ct_match = (
|
||||||
|
(aaaaaaaaaaaaaaaa) == self.get_content_type(obj=rel_obj, using=instance._state.db)[id]
|
||||||
|
)
|
||||||
|
|
||||||
|
# Subscripts expressions with trailing attributes.
|
||||||
|
|
||||||
|
ct_match = (
|
||||||
|
aaaaaaaaaaact_id == self.get_content_type[obj, rel_obj, using, instance._state.db].id
|
||||||
|
)
|
||||||
|
|
||||||
|
ct_match = (
|
||||||
|
{aaaaaaaaaaaaaaaa} == self.get_content_type[obj, rel_obj, using, instance._state.db].id
|
||||||
|
)
|
||||||
|
|
||||||
|
ct_match = (
|
||||||
|
(aaaaaaaaaaaaaaaa) == self.get_content_type[obj, rel_obj, using, instance._state.db].id
|
||||||
|
)
|
||||||
|
|
|
@ -178,10 +178,9 @@ impl Format<PyFormatContext<'_>> for MaybeParenthesizeExpression<'_> {
|
||||||
Parenthesize::Optional | Parenthesize::IfBreaks => needs_parentheses,
|
Parenthesize::Optional | Parenthesize::IfBreaks => needs_parentheses,
|
||||||
};
|
};
|
||||||
|
|
||||||
let can_omit_optional_parentheses = can_omit_optional_parentheses(expression, f.context());
|
|
||||||
match needs_parentheses {
|
match needs_parentheses {
|
||||||
OptionalParentheses::Multiline if *parenthesize != Parenthesize::IfRequired => {
|
OptionalParentheses::Multiline if *parenthesize != Parenthesize::IfRequired => {
|
||||||
if can_omit_optional_parentheses {
|
if can_omit_optional_parentheses(expression, f.context()) {
|
||||||
optional_parentheses(&expression.format().with_options(Parentheses::Never))
|
optional_parentheses(&expression.format().with_options(Parentheses::Never))
|
||||||
.fmt(f)
|
.fmt(f)
|
||||||
} else {
|
} else {
|
||||||
|
@ -407,9 +406,12 @@ impl<'input> CanOmitOptionalParenthesesVisitor<'input> {
|
||||||
attr: _,
|
attr: _,
|
||||||
ctx: _,
|
ctx: _,
|
||||||
}) => {
|
}) => {
|
||||||
|
self.visit_expr(value);
|
||||||
if has_parentheses(value, self.source) {
|
if has_parentheses(value, self.source) {
|
||||||
self.update_max_priority(OperatorPriority::Attribute);
|
self.update_max_priority(OperatorPriority::Attribute);
|
||||||
}
|
}
|
||||||
|
self.last = Some(expr);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Expr::NamedExpr(_)
|
Expr::NamedExpr(_)
|
||||||
|
|
|
@ -65,6 +65,58 @@ return 1 == 2 and (
|
||||||
>= c
|
>= c
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
def f():
|
||||||
|
return (
|
||||||
|
unicodedata.normalize("NFKC", s1).casefold()
|
||||||
|
== unicodedata.normalize("NFKC", s2).casefold()
|
||||||
|
)
|
||||||
|
|
||||||
|
# Call expressions with trailing attributes.
|
||||||
|
|
||||||
|
ct_match = (
|
||||||
|
aaaaaaaaaaact_id == self.get_content_type(obj=rel_obj, using=instance._state.db).id
|
||||||
|
)
|
||||||
|
|
||||||
|
ct_match = (
|
||||||
|
{aaaaaaaaaaaaaaaa} == self.get_content_type(obj=rel_obj, using=instance._state.db).id
|
||||||
|
)
|
||||||
|
|
||||||
|
ct_match = (
|
||||||
|
(aaaaaaaaaaaaaaaa) == self.get_content_type(obj=rel_obj, using=instance._state.db).id
|
||||||
|
)
|
||||||
|
|
||||||
|
ct_match = aaaaaaaaaaact_id == self.get_content_type(
|
||||||
|
obj=rel_obj, using=instance._state.db
|
||||||
|
)
|
||||||
|
|
||||||
|
# Call expressions with trailing subscripts.
|
||||||
|
|
||||||
|
ct_match = (
|
||||||
|
aaaaaaaaaaact_id == self.get_content_type(obj=rel_obj, using=instance._state.db)[id]
|
||||||
|
)
|
||||||
|
|
||||||
|
ct_match = (
|
||||||
|
{aaaaaaaaaaaaaaaa} == self.get_content_type(obj=rel_obj, using=instance._state.db)[id]
|
||||||
|
)
|
||||||
|
|
||||||
|
ct_match = (
|
||||||
|
(aaaaaaaaaaaaaaaa) == self.get_content_type(obj=rel_obj, using=instance._state.db)[id]
|
||||||
|
)
|
||||||
|
|
||||||
|
# Subscripts expressions with trailing attributes.
|
||||||
|
|
||||||
|
ct_match = (
|
||||||
|
aaaaaaaaaaact_id == self.get_content_type[obj, rel_obj, using, instance._state.db].id
|
||||||
|
)
|
||||||
|
|
||||||
|
ct_match = (
|
||||||
|
{aaaaaaaaaaaaaaaa} == self.get_content_type[obj, rel_obj, using, instance._state.db].id
|
||||||
|
)
|
||||||
|
|
||||||
|
ct_match = (
|
||||||
|
(aaaaaaaaaaaaaaaa) == self.get_content_type[obj, rel_obj, using, instance._state.db].id
|
||||||
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
## Output
|
## Output
|
||||||
|
@ -171,6 +223,60 @@ return 1 == 2 and (
|
||||||
>= c
|
>= c
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def f():
|
||||||
|
return unicodedata.normalize("NFKC", s1).casefold() == unicodedata.normalize(
|
||||||
|
"NFKC", s2
|
||||||
|
).casefold()
|
||||||
|
|
||||||
|
|
||||||
|
# Call expressions with trailing attributes.
|
||||||
|
|
||||||
|
ct_match = (
|
||||||
|
aaaaaaaaaaact_id == self.get_content_type(obj=rel_obj, using=instance._state.db).id
|
||||||
|
)
|
||||||
|
|
||||||
|
ct_match = {aaaaaaaaaaaaaaaa} == self.get_content_type(
|
||||||
|
obj=rel_obj, using=instance._state.db
|
||||||
|
).id
|
||||||
|
|
||||||
|
ct_match = (aaaaaaaaaaaaaaaa) == self.get_content_type(
|
||||||
|
obj=rel_obj, using=instance._state.db
|
||||||
|
).id
|
||||||
|
|
||||||
|
ct_match = aaaaaaaaaaact_id == self.get_content_type(
|
||||||
|
obj=rel_obj, using=instance._state.db
|
||||||
|
)
|
||||||
|
|
||||||
|
# Call expressions with trailing subscripts.
|
||||||
|
|
||||||
|
ct_match = (
|
||||||
|
aaaaaaaaaaact_id == self.get_content_type(obj=rel_obj, using=instance._state.db)[id]
|
||||||
|
)
|
||||||
|
|
||||||
|
ct_match = {
|
||||||
|
aaaaaaaaaaaaaaaa
|
||||||
|
} == self.get_content_type(obj=rel_obj, using=instance._state.db)[id]
|
||||||
|
|
||||||
|
ct_match = (
|
||||||
|
aaaaaaaaaaaaaaaa
|
||||||
|
) == self.get_content_type(obj=rel_obj, using=instance._state.db)[id]
|
||||||
|
|
||||||
|
# Subscripts expressions with trailing attributes.
|
||||||
|
|
||||||
|
ct_match = (
|
||||||
|
aaaaaaaaaaact_id
|
||||||
|
== self.get_content_type[obj, rel_obj, using, instance._state.db].id
|
||||||
|
)
|
||||||
|
|
||||||
|
ct_match = {
|
||||||
|
aaaaaaaaaaaaaaaa
|
||||||
|
} == self.get_content_type[obj, rel_obj, using, instance._state.db].id
|
||||||
|
|
||||||
|
ct_match = (
|
||||||
|
aaaaaaaaaaaaaaaa
|
||||||
|
) == self.get_content_type[obj, rel_obj, using, instance._state.db].id
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue