From 549173b3959e5becbe723bc8a85078a9ea604cc4 Mon Sep 17 00:00:00 2001 From: konsti Date: Thu, 13 Jul 2023 12:51:25 +0200 Subject: [PATCH] Fix `StmtAnnAssign` formatting by mirroring `StmtAssign` (#5732) ## Summary `StmtAnnAssign` would not insert parentheses when breaking the same way `StmtAssign` does, causing unstable formatting and likely some syntax errors. ## Test Plan I added a regression test. --- .../fixtures/ruff/statement/ann_assign.py | 10 +++++--- .../fixtures/ruff/statement/aug_assign.py | 5 ++++ .../src/statement/stmt_ann_assign.rs | 19 ++++++++++++-- .../format@statement__ann_assign.py.snap | 25 ++++++++++++------- .../format@statement__aug_assign.py.snap | 25 +++++++++++++++++++ 5 files changed, 69 insertions(+), 15 deletions(-) create mode 100644 crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/aug_assign.py create mode 100644 crates/ruff_python_formatter/tests/snapshots/format@statement__aug_assign.py.snap diff --git a/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/ann_assign.py b/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/ann_assign.py index 6c9d3155f6..b965199c98 100644 --- a/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/ann_assign.py +++ b/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/ann_assign.py @@ -1,5 +1,7 @@ -tree_depth += 1 +# Regression test: Don't forget the parentheses in the value when breaking +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: int = a + 1 * a -greeting += "This is very long, formal greeting for whomever is name here. Dear %s, it will break the line" % len( - name -) + +# Regression test: Don't forget the parentheses in the annotation when breaking +class DefaultRunner: + task_runner_cls: TaskRunnerProtocol | typing.Callable[[], typing.Any] = DefaultTaskRunner diff --git a/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/aug_assign.py b/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/aug_assign.py new file mode 100644 index 0000000000..6c9d3155f6 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/aug_assign.py @@ -0,0 +1,5 @@ +tree_depth += 1 + +greeting += "This is very long, formal greeting for whomever is name here. Dear %s, it will break the line" % len( + name +) diff --git a/crates/ruff_python_formatter/src/statement/stmt_ann_assign.rs b/crates/ruff_python_formatter/src/statement/stmt_ann_assign.rs index c9d5cf2fdf..418b4d52c1 100644 --- a/crates/ruff_python_formatter/src/statement/stmt_ann_assign.rs +++ b/crates/ruff_python_formatter/src/statement/stmt_ann_assign.rs @@ -1,3 +1,5 @@ +use crate::expression::maybe_parenthesize_expression; +use crate::expression::parentheses::Parenthesize; use crate::prelude::*; use crate::FormatNodeRule; use ruff_formatter::write; @@ -18,11 +20,24 @@ impl FormatNodeRule for FormatStmtAnnAssign { write!( f, - [target.format(), text(":"), space(), annotation.format()] + [ + target.format(), + text(":"), + space(), + maybe_parenthesize_expression(annotation, item, Parenthesize::IfBreaks) + ] )?; if let Some(value) = value { - write!(f, [space(), text("="), space(), value.format()])?; + write!( + f, + [ + space(), + text("="), + space(), + maybe_parenthesize_expression(value, item, Parenthesize::IfBreaks) + ] + )?; } Ok(()) diff --git a/crates/ruff_python_formatter/tests/snapshots/format@statement__ann_assign.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@statement__ann_assign.py.snap index 9385c1b1ba..52d136a3be 100644 --- a/crates/ruff_python_formatter/tests/snapshots/format@statement__ann_assign.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/format@statement__ann_assign.py.snap @@ -4,21 +4,28 @@ input_file: crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/ --- ## Input ```py -tree_depth += 1 +# Regression test: Don't forget the parentheses in the value when breaking +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: int = a + 1 * a -greeting += "This is very long, formal greeting for whomever is name here. Dear %s, it will break the line" % len( - name -) + +# Regression test: Don't forget the parentheses in the annotation when breaking +class DefaultRunner: + task_runner_cls: TaskRunnerProtocol | typing.Callable[[], typing.Any] = DefaultTaskRunner ``` ## Output ```py -tree_depth += 1 - -greeting += ( - "This is very long, formal greeting for whomever is name here. Dear %s, it will break the line" - % len(name) +# Regression test: Don't forget the parentheses in the value when breaking +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: int = ( + a + 1 * a ) + + +# Regression test: Don't forget the parentheses in the annotation when breaking +class DefaultRunner: + task_runner_cls: ( + TaskRunnerProtocol | typing.Callable[[], typing.Any] + ) = DefaultTaskRunner ``` diff --git a/crates/ruff_python_formatter/tests/snapshots/format@statement__aug_assign.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@statement__aug_assign.py.snap new file mode 100644 index 0000000000..715c6cd154 --- /dev/null +++ b/crates/ruff_python_formatter/tests/snapshots/format@statement__aug_assign.py.snap @@ -0,0 +1,25 @@ +--- +source: crates/ruff_python_formatter/tests/fixtures.rs +input_file: crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/aug_assign.py +--- +## Input +```py +tree_depth += 1 + +greeting += "This is very long, formal greeting for whomever is name here. Dear %s, it will break the line" % len( + name +) +``` + +## Output +```py +tree_depth += 1 + +greeting += ( + "This is very long, formal greeting for whomever is name here. Dear %s, it will break the line" + % len(name) +) +``` + + +