From 3d03e75a9d42c4d519062677405bc2fce307a22a Mon Sep 17 00:00:00 2001 From: Charlie Marsh Date: Sun, 15 Oct 2023 21:41:50 -0400 Subject: [PATCH] Force parentheses for power operations in unary expressions (#7955) ## Summary E.g., given `-10**100`, reformat as `-(10**100)`. Black special cases this (https://github.com/psf/black/pull/909) and it's currently a deviation. Closes https://github.com/astral-sh/ruff/issues/7951. --- .../src/expression/expr_unary_op.rs | 11 +++++++++-- ...ack_compatibility@simple_cases__expression.py.snap | 11 +---------- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/crates/ruff_python_formatter/src/expression/expr_unary_op.rs b/crates/ruff_python_formatter/src/expression/expr_unary_op.rs index 62646e2da8..cd5d30e97b 100644 --- a/crates/ruff_python_formatter/src/expression/expr_unary_op.rs +++ b/crates/ruff_python_formatter/src/expression/expr_unary_op.rs @@ -4,7 +4,7 @@ use ruff_python_ast::UnaryOp; use crate::comments::{trailing_comments, SourceComment}; use crate::expression::parentheses::{ - is_expression_parenthesized, NeedsParentheses, OptionalParentheses, + is_expression_parenthesized, NeedsParentheses, OptionalParentheses, Parentheses, }; use crate::prelude::*; @@ -57,7 +57,14 @@ impl FormatNodeRule for FormatExprUnaryOp { space().fmt(f)?; } - operand.format().fmt(f) + if operand + .as_bin_op_expr() + .is_some_and(|bin_op| bin_op.op.is_pow()) + { + operand.format().with_options(Parentheses::Always).fmt(f) + } else { + operand.format().fmt(f) + } } fn fmt_dangling_comments( diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__expression.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__expression.py.snap index 43e5c13e54..02a6a4a76c 100644 --- a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__expression.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__expression.py.snap @@ -266,15 +266,6 @@ last_call() ```diff --- Black +++ Ruff -@@ -31,7 +31,7 @@ - -1 - ~int and not v1 ^ 123 + v2 | True - (~int) and (not ((v1 ^ (123 + v2)) | True)) --+(really ** -(confusing ** ~(operator**-precedence))) -++really ** -confusing ** ~operator**-precedence - flags & ~select.EPOLLIN and waiters.write_task is not None - lambda arg: None - lambda a=True: a @@ -115,7 +115,7 @@ arg, another, @@ -322,7 +313,7 @@ not great -1 ~int and not v1 ^ 123 + v2 | True (~int) and (not ((v1 ^ (123 + v2)) | True)) -+really ** -confusing ** ~operator**-precedence ++(really ** -(confusing ** ~(operator**-precedence))) flags & ~select.EPOLLIN and waiters.write_task is not None lambda arg: None lambda a=True: a