Skip to content

Commit 4f836b4

Browse files
Preserve required annotation parentheses in annotated assignments (#23865)
1 parent 7200fb9 commit 4f836b4

3 files changed

Lines changed: 16 additions & 3 deletions

File tree

crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/ann_assign.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717

1818
JSONSerializable: str | int | float | bool | None | list | tuple | JSONMapping = aaaaaaaaaaaaaaaa
1919

20+
D: (E := 4) = (F := 5)
21+
2022
# Regression test: Don't forget the parentheses in the annotation when breaking
2123
class DefaultRunner:
2224
task_runner_cls: TaskRunnerProtocol | typing.Callable[[], typing.Any] = DefaultTaskRunner

crates/ruff_python_formatter/src/statement/stmt_ann_assign.rs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use ruff_formatter::write;
22
use ruff_python_ast::StmtAnnAssign;
33

44
use crate::expression::is_splittable_expression;
5-
use crate::expression::parentheses::Parentheses;
5+
use crate::expression::parentheses::{NeedsParentheses, OptionalParentheses, Parentheses};
66
use crate::prelude::*;
77
use crate::statement::stmt_assign::{
88
AnyAssignmentOperator, AnyBeforeOperator, FormatStatementsLastExpression,
@@ -37,9 +37,16 @@ impl FormatNodeRule<StmtAnnAssign> for FormatStmtAnnAssign {
3737
} else {
3838
// Remove unnecessary parentheses around the annotation if the parenthesize long type hints preview style is enabled.
3939
// Ensure we keep the parentheses if the annotation has any comments.
40-
if f.context().comments().has_leading(annotation.as_ref())
40+
let preserve_parentheses = f.context().comments().has_leading(annotation.as_ref())
4141
|| f.context().comments().has_trailing(annotation.as_ref())
42-
{
42+
|| matches!(
43+
annotation
44+
.as_ref()
45+
.needs_parentheses(item.into(), f.context()),
46+
OptionalParentheses::Always
47+
);
48+
49+
if preserve_parentheses {
4350
annotation
4451
.format()
4552
.with_options(Parentheses::Always)

crates/ruff_python_formatter/tests/snapshots/format@statement__ann_assign.py.snap

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ JSONSerializable: str | int | float | bool | None | list | tuple | JSONMapping =
2323
2424
JSONSerializable: str | int | float | bool | None | list | tuple | JSONMapping = aaaaaaaaaaaaaaaa
2525
26+
D: (E := 4) = (F := 5)
27+
2628
# Regression test: Don't forget the parentheses in the annotation when breaking
2729
class DefaultRunner:
2830
task_runner_cls: TaskRunnerProtocol | typing.Callable[[], typing.Any] = DefaultTaskRunner
@@ -58,6 +60,8 @@ JSONSerializable: str | int | float | bool | None | list | tuple | JSONMapping =
5860
aaaaaaaaaaaaaaaa
5961
)
6062
63+
D: (E := 4) = (F := 5)
64+
6165
6266
# Regression test: Don't forget the parentheses in the annotation when breaking
6367
class DefaultRunner:

0 commit comments

Comments
 (0)