From 22770fb4be78ae84a71b0834794f92036638a0e1 Mon Sep 17 00:00:00 2001 From: Charlie Marsh Date: Sat, 16 Sep 2023 13:10:35 -0400 Subject: [PATCH] Avoid extra parentheses in `await` expressions (#7424) ## Summary This PR aligns the await parenthesizing with the unary case, which is: if the value is already parenthesized, avoid parenthesizing; otherwise, only parenthesize if the _value_ needs parenthesizing. Closes https://github.com/astral-sh/ruff/issues/7420. ## Test Plan `cargo test` No change in similarity. Before: | project | similarity index | total files | changed files | |--------------|------------------:|------------------:|------------------:| | cpython | 0.76083 | 1789 | 1632 | | django | 0.99982 | 2760 | 37 | | transformers | 0.99957 | 2587 | 399 | | twine | 1.00000 | 33 | 0 | | typeshed | 0.99983 | 3496 | 18 | | warehouse | 0.99923 | 648 | 18 | | zulip | 0.99962 | 1437 | 22 | After: | project | similarity index | total files | changed files | |--------------|------------------:|------------------:|------------------:| | cpython | 0.76083 | 1789 | 1632 | | django | 0.99982 | 2760 | 37 | | transformers | 0.99957 | 2587 | 399 | | twine | 1.00000 | 33 | 0 | | typeshed | 0.99983 | 3496 | 18 | | warehouse | 0.99923 | 648 | 18 | | zulip | 0.99962 | 1437 | 22 | --- .../test/fixtures/ruff/expression/await.py | 12 +++++ .../src/expression/expr_await.rs | 10 ++-- .../format@expression__await.py.snap | 52 +++++++++++++++++++ 3 files changed, 71 insertions(+), 3 deletions(-) create mode 100644 crates/ruff_python_formatter/resources/test/fixtures/ruff/expression/await.py create mode 100644 crates/ruff_python_formatter/tests/snapshots/format@expression__await.py.snap diff --git a/crates/ruff_python_formatter/resources/test/fixtures/ruff/expression/await.py b/crates/ruff_python_formatter/resources/test/fixtures/ruff/expression/await.py new file mode 100644 index 0000000000..f5319a8195 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/ruff/expression/await.py @@ -0,0 +1,12 @@ +# Regression test for: https://github.com/astral-sh/ruff/issues/7420 +result = await self.request( + f"/applications/{int(application_id)}/guilds/{int(scope)}/commands/{int(command_id)}/permissions" +) + +result = await (self.request( + f"/applications/{int(application_id)}/guilds/{int(scope)}/commands/{int(command_id)}/permissions" +)) + +result = await (1 + f(1, 2, 3,)) + +result = (await (1 + f(1, 2, 3,))) diff --git a/crates/ruff_python_formatter/src/expression/expr_await.rs b/crates/ruff_python_formatter/src/expression/expr_await.rs index 665fec2489..50427d95b1 100644 --- a/crates/ruff_python_formatter/src/expression/expr_await.rs +++ b/crates/ruff_python_formatter/src/expression/expr_await.rs @@ -3,7 +3,9 @@ use ruff_python_ast::node::AnyNodeRef; use ruff_python_ast::ExprAwait; use crate::expression::maybe_parenthesize_expression; -use crate::expression::parentheses::{NeedsParentheses, OptionalParentheses, Parenthesize}; +use crate::expression::parentheses::{ + is_expression_parenthesized, NeedsParentheses, OptionalParentheses, Parenthesize, +}; use crate::prelude::*; #[derive(Default)] @@ -28,12 +30,14 @@ impl NeedsParentheses for ExprAwait { fn needs_parentheses( &self, parent: AnyNodeRef, - _context: &PyFormatContext, + context: &PyFormatContext, ) -> OptionalParentheses { if parent.is_expr_await() { OptionalParentheses::Always + } else if is_expression_parenthesized(self.value.as_ref().into(), context.source()) { + OptionalParentheses::Never } else { - OptionalParentheses::Multiline + self.value.needs_parentheses(self.into(), context) } } } diff --git a/crates/ruff_python_formatter/tests/snapshots/format@expression__await.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@expression__await.py.snap new file mode 100644 index 0000000000..c623da8319 --- /dev/null +++ b/crates/ruff_python_formatter/tests/snapshots/format@expression__await.py.snap @@ -0,0 +1,52 @@ +--- +source: crates/ruff_python_formatter/tests/fixtures.rs +input_file: crates/ruff_python_formatter/resources/test/fixtures/ruff/expression/await.py +--- +## Input +```py +# Regression test for: https://github.com/astral-sh/ruff/issues/7420 +result = await self.request( + f"/applications/{int(application_id)}/guilds/{int(scope)}/commands/{int(command_id)}/permissions" +) + +result = await (self.request( + f"/applications/{int(application_id)}/guilds/{int(scope)}/commands/{int(command_id)}/permissions" +)) + +result = await (1 + f(1, 2, 3,)) + +result = (await (1 + f(1, 2, 3,))) +``` + +## Output +```py +# Regression test for: https://github.com/astral-sh/ruff/issues/7420 +result = await self.request( + f"/applications/{int(application_id)}/guilds/{int(scope)}/commands/{int(command_id)}/permissions" +) + +result = await self.request( + f"/applications/{int(application_id)}/guilds/{int(scope)}/commands/{int(command_id)}/permissions" +) + +result = await ( + 1 + + f( + 1, + 2, + 3, + ) +) + +result = await ( + 1 + + f( + 1, + 2, + 3, + ) +) +``` + + +