Skip to content

Commit

Permalink
Avoid introducing new parentheses in annotated assignments (#8233)
Browse files Browse the repository at this point in the history
## Summary

We decided to avoid changing this in
#7315, but it's been reported
multiple times (e.g., in #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 |
  • Loading branch information
charliermarsh authored Oct 26, 2023
1 parent 133a745 commit 88c8b47
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 53 deletions.
22 changes: 0 additions & 22 deletions crates/ruff_python_formatter/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
@@ -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:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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
```


Expand Down
22 changes: 0 additions & 22 deletions docs/formatter/black.md
Original file line number Diff line number Diff line change
Expand Up @@ -399,28 +399,6 @@ def update_emission_strength():
value = self.emission_strength * 2
```

### Type annotations may be parenthesized when expanded

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

Black occasionally breaks call chains differently than Ruff; in particular, Black occasionally
Expand Down

0 comments on commit 88c8b47

Please sign in to comment.