Avoid introducing new parentheses in annotated assignments (#8233)

## Summary

We decided to avoid changing this in
https://github.com/astral-sh/ruff/issues/7315, but it's been reported
multiple times (e.g., in https://github.com/astral-sh/ruff/issues/8226,
also on Discord). I suggest we change it to improve compatibility. In
general, it also seems to lend itself to better code style.

Closes #8188 
Closes #8226

## Test Plan

Shows improvements for CPython, home-assistant, Poetry, and typeshed.

Before:

| project | similarity index | total files | changed files |

|----------------|------------------:|------------------:|------------------:|
| cpython | 0.75803 | 1799 | 1647 |
| django | 0.99983 | 2772 | 34 |
| home-assistant | 0.99953 | 10596 | 186 |
| poetry | 0.99891 | 317 | 17 |
| transformers | 0.99966 | 2657 | 330 |
| twine | 1.00000 | 33 | 0 |
| typeshed | 0.99978 | 3669 | 20 |
| warehouse | 0.99977 | 654 | 13 |
| zulip | 0.99970 | 1459 | 22 |

After:

| project | similarity index | total files | changed files |

|----------------|------------------:|------------------:|------------------:|
| cpython | 0.75804 | 1799 | 1647 |
| django | 0.99983 | 2772 | 34 |
| home-assistant | 0.99960 | 10596 | 156 |
| poetry | 0.99897 | 317 | 17 |
| transformers | 0.99966 | 2657 | 330 |
| twine | 1.00000 | 33 | 0 |
| typeshed | 0.99980 | 3669 | 18 |
| warehouse | 0.99977 | 654 | 13 |
| zulip | 0.99970 | 1459 | 22 |
This commit is contained in:
Charlie Marsh 2023-10-25 19:51:50 -07:00 committed by GitHub
parent 133a745de1
commit 88c8b47326
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 57 additions and 53 deletions

View file

@ -537,28 +537,6 @@ def update_emission_strength():
value = self.emission_strength * 2
```
#### Type annotations may be parenthesized when expanded ([#7315](https://github.com/astral-sh/ruff/issues/7315))
Black will avoid parenthesizing type annotations in an annotated assignment, while Ruff will insert
parentheses in some cases.
For example:
```python
# Black
StartElementHandler: Callable[[str, dict[str, str]], Any] | Callable[[str, list[str]], Any] | Callable[
[str, dict[str, str], list[str]], Any
] | None
# Ruff
StartElementHandler: (
Callable[[str, dict[str, str]], Any]
| Callable[[str, list[str]], Any]
| Callable[[str, dict[str, str], list[str]], Any]
| None
)
```
#### Call chain calls break differently ([#7051](https://github.com/astral-sh/ruff/issues/7051))
Black occasionally breaks call chains differently than Ruff; in particular, Black occasionally

View file

@ -1,6 +1,21 @@
# Regression test: Don't forget the parentheses in the value when breaking
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: int = a + 1 * a
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb: Bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb = (
Bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb()
)
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb: (
Bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
)= Bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb()
JSONSerializable: TypeAlias = (
"str | int | float | bool | None | list | tuple | JSONMapping"
)
JSONSerializable: str | int | float | bool | None | list | tuple | JSONMapping = {1, 2, 3, 4}
JSONSerializable: str | int | float | bool | None | list | tuple | JSONMapping = aaaaaaaaaaaaaaaa
# Regression test: Don't forget the parentheses in the annotation when breaking
class DefaultRunner:

View file

@ -21,12 +21,7 @@ impl FormatNodeRule<StmtAnnAssign> for FormatStmtAnnAssign {
write!(
f,
[
target.format(),
token(":"),
space(),
maybe_parenthesize_expression(annotation, item, Parenthesize::IfBreaks)
]
[target.format(), token(":"), space(), annotation.format(),]
)?;
if let Some(value) = value {

View file

@ -7,6 +7,21 @@ input_file: crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/
# Regression test: Don't forget the parentheses in the value when breaking
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: int = a + 1 * a
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb: Bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb = (
Bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb()
)
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb: (
Bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
)= Bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb()
JSONSerializable: TypeAlias = (
"str | int | float | bool | None | list | tuple | JSONMapping"
)
JSONSerializable: str | int | float | bool | None | list | tuple | JSONMapping = {1, 2, 3, 4}
JSONSerializable: str | int | float | bool | None | list | tuple | JSONMapping = aaaaaaaaaaaaaaaa
# Regression test: Don't forget the parentheses in the annotation when breaking
class DefaultRunner:
@ -20,12 +35,35 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: int =
a + 1 * a
)
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb: Bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb = (
Bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb()
)
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb: (
Bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
) = Bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb()
JSONSerializable: TypeAlias = (
"str | int | float | bool | None | list | tuple | JSONMapping"
)
JSONSerializable: str | int | float | bool | None | list | tuple | JSONMapping = {
1,
2,
3,
4,
}
JSONSerializable: str | int | float | bool | None | list | tuple | JSONMapping = (
aaaaaaaaaaaaaaaa
)
# Regression test: Don't forget the parentheses in the annotation when breaking
class DefaultRunner:
task_runner_cls: (
TaskRunnerProtocol | typing.Callable[[], typing.Any]
) = DefaultTaskRunner
task_runner_cls: TaskRunnerProtocol | typing.Callable[
[], typing.Any
] = DefaultTaskRunner
```