mirror of
https://github.com/astral-sh/ruff.git
synced 2025-07-23 04:55:09 +00:00
Preserve parentheses around left side of binary expression
<!-- Thank you for contributing to Ruff! To help us out with reviewing, please consider the following: - Does this pull request include a summary of the change? (See below.) - Does this pull request include a descriptive title? - Does this pull request include references to any relevant issues? --> ## Summary This PR fixes an issue where the binary expression formatting removed parentheses around the left hand side of an expression. <!-- What's the purpose of the change? What does it do, and why? --> ## Test Plan I added a new regression test and re-ran the ecosystem check. It brings down the `check-formatter-stability` output from a 3.4MB file down to 900KB. <!-- How was it tested? -->
This commit is contained in:
parent
ae25638b0b
commit
9c2a75284b
5 changed files with 41 additions and 19 deletions
|
@ -1,12 +1,14 @@
|
|||
use crate::comments::{trailing_comments, trailing_node_comments, Comments};
|
||||
use crate::expression::binary_like::{BinaryLayout, FormatBinaryLike};
|
||||
use crate::expression::parentheses::{
|
||||
default_expression_needs_parentheses, NeedsParentheses, Parenthesize,
|
||||
default_expression_needs_parentheses, is_expression_parenthesized, NeedsParentheses,
|
||||
Parenthesize,
|
||||
};
|
||||
use crate::expression::Parentheses;
|
||||
use crate::prelude::*;
|
||||
use crate::FormatNodeRule;
|
||||
use ruff_formatter::{write, FormatOwnedWithRule, FormatRefWithRule, FormatRuleWithOptions};
|
||||
use ruff_python_ast::node::AstNode;
|
||||
use rustpython_parser::ast::{
|
||||
Constant, Expr, ExprAttribute, ExprBinOp, ExprConstant, ExprUnaryOp, Operator, UnaryOp,
|
||||
};
|
||||
|
@ -44,9 +46,18 @@ impl<'ast> FormatBinaryLike<'ast> for ExprBinOp {
|
|||
fn fmt_default(&self, f: &mut PyFormatter<'ast, '_>) -> FormatResult<()> {
|
||||
let comments = f.context().comments().clone();
|
||||
|
||||
let format_inner = format_with(|f| {
|
||||
let binary_chain: SmallVec<[&ExprBinOp; 4]> =
|
||||
iter::successors(Some(self), |parent| parent.left.as_bin_op_expr()).collect();
|
||||
let format_inner = format_with(|f: &mut PyFormatter| {
|
||||
let source = f.context().contents();
|
||||
let binary_chain: SmallVec<[&ExprBinOp; 4]> = iter::successors(Some(self), |parent| {
|
||||
parent.left.as_bin_op_expr().and_then(|bin_expression| {
|
||||
if is_expression_parenthesized(bin_expression.as_any_node_ref(), source) {
|
||||
None
|
||||
} else {
|
||||
Some(bin_expression)
|
||||
}
|
||||
})
|
||||
})
|
||||
.collect();
|
||||
|
||||
// SAFETY: `binary_chain` is guaranteed not to be empty because it always contains the current expression.
|
||||
let left_most = binary_chain.last().unwrap();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue