mirror of
				https://github.com/astral-sh/ruff.git
				synced 2025-11-04 05:34:07 +00:00 
			
		
		
		
	Correctly handle left/right breaking 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
Black supports for layouts when it comes to breaking binary expressions:
```rust
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
enum BinaryLayout {
    /// Put each operand on their own line if either side expands
    Default,
    /// Try to expand the left to make it fit. Add parentheses if the left or right don't fit.
    ///
    ///```python
    /// [
    ///     a,
    ///     b
    /// ] & c
    ///```
    ExpandLeft,
    /// Try to expand the right to make it fix. Add parentheses if the left or right don't fit.
    ///
    /// ```python
    /// a & [
    ///     b,
    ///     c
    /// ]
    /// ```
    ExpandRight,
    /// Both the left and right side can be expanded. Try in the following order:
    /// * expand the right side
    /// * expand the left side
    /// * expand both sides
    ///
    /// to make the expression fit
    ///
    /// ```python
    /// [
    ///     a,
    ///     b
    /// ] & [
    ///     c,
    ///     d
    /// ]
    /// ```
    ExpandRightThenLeft,
}
```
Our current implementation only handles `ExpandRight` and `Default` correctly. This PR adds support for `ExpandRightThenLeft` and `ExpandLeft`. 
## Test Plan
I added tests that play through all 4 binary expression layouts.
			
			
This commit is contained in:
		
							parent
							
								
									a332f078db
								
							
						
					
					
						commit
						3973836420
					
				
					 3 changed files with 613 additions and 83 deletions
				
			
		| 
						 | 
					@ -52,3 +52,138 @@ if (
 | 
				
			||||||
    ccccccccccc
 | 
					    ccccccccccc
 | 
				
			||||||
):
 | 
					):
 | 
				
			||||||
    pass
 | 
					    pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Left only breaks
 | 
				
			||||||
 | 
					if [
 | 
				
			||||||
 | 
					    aaaaaaaaaaaaa,
 | 
				
			||||||
 | 
					    bbbbbbbbbbbbbbbbbbbb,
 | 
				
			||||||
 | 
					    cccccccccccccccccccc,
 | 
				
			||||||
 | 
					    dddddddddddddddddddd,
 | 
				
			||||||
 | 
					    eeeeeeeeee,
 | 
				
			||||||
 | 
					] & aaaaaaaaaaaaaaaaaaaaaaaaaa:
 | 
				
			||||||
 | 
					    ...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if [
 | 
				
			||||||
 | 
					    aaaaaaaaaaaaa,
 | 
				
			||||||
 | 
					    bbbbbbbbbbbbbbbbbbbb,
 | 
				
			||||||
 | 
					    cccccccccccccccccccc,
 | 
				
			||||||
 | 
					    dddddddddddddddddddd,
 | 
				
			||||||
 | 
					    eeeeeeeeee,
 | 
				
			||||||
 | 
					] & aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:
 | 
				
			||||||
 | 
					    ...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Right only can break
 | 
				
			||||||
 | 
					if aaaaaaaaaaaaaaaaaaaaaaaaaa & [
 | 
				
			||||||
 | 
					    aaaaaaaaaaaaa,
 | 
				
			||||||
 | 
					    bbbbbbbbbbbbbbbbbbbb,
 | 
				
			||||||
 | 
					    cccccccccccccccccccc,
 | 
				
			||||||
 | 
					    dddddddddddddddddddd,
 | 
				
			||||||
 | 
					    eeeeeeeeee,
 | 
				
			||||||
 | 
					]:
 | 
				
			||||||
 | 
					    ...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa & [
 | 
				
			||||||
 | 
					    aaaaaaaaaaaaa,
 | 
				
			||||||
 | 
					    bbbbbbbbbbbbbbbbbbbb,
 | 
				
			||||||
 | 
					    cccccccccccccccccccc,
 | 
				
			||||||
 | 
					    dddddddddddddddddddd,
 | 
				
			||||||
 | 
					    eeeeeeeeee,
 | 
				
			||||||
 | 
					]:
 | 
				
			||||||
 | 
					    ...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Left or right can break
 | 
				
			||||||
 | 
					if [2222, 333] & [
 | 
				
			||||||
 | 
					    aaaaaaaaaaaaa,
 | 
				
			||||||
 | 
					    bbbbbbbbbbbbbbbbbbbb,
 | 
				
			||||||
 | 
					    cccccccccccccccccccc,
 | 
				
			||||||
 | 
					    dddddddddddddddddddd,
 | 
				
			||||||
 | 
					    eeeeeeeeee,
 | 
				
			||||||
 | 
					]:
 | 
				
			||||||
 | 
					    ...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if [
 | 
				
			||||||
 | 
					    aaaaaaaaaaaaa,
 | 
				
			||||||
 | 
					    bbbbbbbbbbbbbbbbbbbb,
 | 
				
			||||||
 | 
					    cccccccccccccccccccc,
 | 
				
			||||||
 | 
					    dddddddddddddddddddd,
 | 
				
			||||||
 | 
					    eeeeeeeeee,
 | 
				
			||||||
 | 
					] & [2222, 333]:
 | 
				
			||||||
 | 
					    ...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if [
 | 
				
			||||||
 | 
					    aaaaaaaaaaaaa,
 | 
				
			||||||
 | 
					    bbbbbbbbbbbbbbbbbbbb,
 | 
				
			||||||
 | 
					    cccccccccccccccccccc,
 | 
				
			||||||
 | 
					    dddddddddddddddddddd,
 | 
				
			||||||
 | 
					    eeeeeeeeee,
 | 
				
			||||||
 | 
					] & [fffffffffffffffff, gggggggggggggggggggg, hhhhhhhhhhhhhhhhhhhhh, iiiiiiiiiiiiiiii, jjjjjjjjjjjjj]:
 | 
				
			||||||
 | 
					    ...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if (
 | 
				
			||||||
 | 
					    # comment
 | 
				
			||||||
 | 
					    [
 | 
				
			||||||
 | 
					        aaaaaaaaaaaaa,
 | 
				
			||||||
 | 
					        bbbbbbbbbbbbbbbbbbbb,
 | 
				
			||||||
 | 
					        cccccccccccccccccccc,
 | 
				
			||||||
 | 
					        dddddddddddddddddddd,
 | 
				
			||||||
 | 
					        eeeeeeeeee,
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					) & [
 | 
				
			||||||
 | 
					    fffffffffffffffff,
 | 
				
			||||||
 | 
					    gggggggggggggggggggg,
 | 
				
			||||||
 | 
					    hhhhhhhhhhhhhhhhhhhhh,
 | 
				
			||||||
 | 
					    iiiiiiiiiiiiiiii,
 | 
				
			||||||
 | 
					    jjjjjjjjjjjjj,
 | 
				
			||||||
 | 
					]:
 | 
				
			||||||
 | 
					    pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Nesting
 | 
				
			||||||
 | 
					if (aaaa + b) & [
 | 
				
			||||||
 | 
					    fffffffffffffffff,
 | 
				
			||||||
 | 
					    gggggggggggggggggggg,
 | 
				
			||||||
 | 
					    hhhhhhhhhhhhhhhhhhhhh,
 | 
				
			||||||
 | 
					    iiiiiiiiiiiiiiii,
 | 
				
			||||||
 | 
					    jjjjjjjjjjjjj,
 | 
				
			||||||
 | 
					]:
 | 
				
			||||||
 | 
					    ...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if [
 | 
				
			||||||
 | 
					    fffffffffffffffff,
 | 
				
			||||||
 | 
					    gggggggggggggggggggg,
 | 
				
			||||||
 | 
					    hhhhhhhhhhhhhhhhhhhhh,
 | 
				
			||||||
 | 
					    iiiiiiiiiiiiiiii,
 | 
				
			||||||
 | 
					    jjjjjjjjjjjjj,
 | 
				
			||||||
 | 
					] & (a + b):
 | 
				
			||||||
 | 
					    ...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if [
 | 
				
			||||||
 | 
					    fffffffffffffffff,
 | 
				
			||||||
 | 
					    gggggggggggggggggggg,
 | 
				
			||||||
 | 
					    hhhhhhhhhhhhhhhhhhhhh,
 | 
				
			||||||
 | 
					    iiiiiiiiiiiiiiii,
 | 
				
			||||||
 | 
					    jjjjjjjjjjjjj,
 | 
				
			||||||
 | 
					] & (
 | 
				
			||||||
 | 
					    # comment
 | 
				
			||||||
 | 
					    a
 | 
				
			||||||
 | 
					    + b
 | 
				
			||||||
 | 
					):
 | 
				
			||||||
 | 
					    ...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if (
 | 
				
			||||||
 | 
					    [
 | 
				
			||||||
 | 
					        fffffffffffffffff,
 | 
				
			||||||
 | 
					        gggggggggggggggggggg,
 | 
				
			||||||
 | 
					        hhhhhhhhhhhhhhhhhhhhh,
 | 
				
			||||||
 | 
					        iiiiiiiiiiiiiiii,
 | 
				
			||||||
 | 
					        jjjjjjjjjjjjj,
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					    &
 | 
				
			||||||
 | 
					    # comment
 | 
				
			||||||
 | 
					    a + b
 | 
				
			||||||
 | 
					):
 | 
				
			||||||
 | 
					    ...
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -36,9 +36,78 @@ impl FormatNodeRule<ExprBinOp> for FormatExprBinOp {
 | 
				
			||||||
            range: _,
 | 
					            range: _,
 | 
				
			||||||
        } = item;
 | 
					        } = item;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let should_break_right = self.parentheses == Some(Parentheses::Custom);
 | 
					        let layout = if self.parentheses == Some(Parentheses::Custom) {
 | 
				
			||||||
 | 
					            BinaryLayout::from(item)
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            BinaryLayout::Default
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if should_break_right {
 | 
					        match layout {
 | 
				
			||||||
 | 
					            BinaryLayout::Default => {
 | 
				
			||||||
 | 
					                let comments = f.context().comments().clone();
 | 
				
			||||||
 | 
					                let operator_comments = comments.dangling_comments(item.as_any_node_ref());
 | 
				
			||||||
 | 
					                let needs_space = !is_simple_power_expression(item);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                let before_operator_space = if needs_space {
 | 
				
			||||||
 | 
					                    soft_line_break_or_space()
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                    soft_line_break()
 | 
				
			||||||
 | 
					                };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                write!(
 | 
				
			||||||
 | 
					                    f,
 | 
				
			||||||
 | 
					                    [
 | 
				
			||||||
 | 
					                        left.format(),
 | 
				
			||||||
 | 
					                        before_operator_space,
 | 
				
			||||||
 | 
					                        op.format(),
 | 
				
			||||||
 | 
					                        trailing_comments(operator_comments),
 | 
				
			||||||
 | 
					                    ]
 | 
				
			||||||
 | 
					                )?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                // Format the operator on its own line if the right side has any leading comments.
 | 
				
			||||||
 | 
					                if comments.has_leading_comments(right.as_ref()) {
 | 
				
			||||||
 | 
					                    write!(f, [hard_line_break()])?;
 | 
				
			||||||
 | 
					                } else if needs_space {
 | 
				
			||||||
 | 
					                    write!(f, [space()])?;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                write!(f, [group(&right.format())])
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            BinaryLayout::ExpandLeft => {
 | 
				
			||||||
 | 
					                let left = left.format().memoized();
 | 
				
			||||||
 | 
					                let right = right.format().memoized();
 | 
				
			||||||
 | 
					                write!(
 | 
				
			||||||
 | 
					                    f,
 | 
				
			||||||
 | 
					                    [best_fitting![
 | 
				
			||||||
 | 
					                        // Everything on a single line
 | 
				
			||||||
 | 
					                        format_args![left, space(), op.format(), space(), right],
 | 
				
			||||||
 | 
					                        // Break the left over multiple lines, keep the right flat
 | 
				
			||||||
 | 
					                        format_args![
 | 
				
			||||||
 | 
					                            group(&left).should_expand(true),
 | 
				
			||||||
 | 
					                            space(),
 | 
				
			||||||
 | 
					                            op.format(),
 | 
				
			||||||
 | 
					                            space(),
 | 
				
			||||||
 | 
					                            right
 | 
				
			||||||
 | 
					                        ],
 | 
				
			||||||
 | 
					                        // The content doesn't fit, indent the content and break before the operator.
 | 
				
			||||||
 | 
					                        format_args![
 | 
				
			||||||
 | 
					                            text("("),
 | 
				
			||||||
 | 
					                            block_indent(&format_args![
 | 
				
			||||||
 | 
					                                left,
 | 
				
			||||||
 | 
					                                hard_line_break(),
 | 
				
			||||||
 | 
					                                op.format(),
 | 
				
			||||||
 | 
					                                space(),
 | 
				
			||||||
 | 
					                                right
 | 
				
			||||||
 | 
					                            ]),
 | 
				
			||||||
 | 
					                            text(")")
 | 
				
			||||||
 | 
					                        ]
 | 
				
			||||||
 | 
					                    ]
 | 
				
			||||||
 | 
					                    .with_mode(BestFittingMode::AllLines)]
 | 
				
			||||||
 | 
					                )
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            BinaryLayout::ExpandRight => {
 | 
				
			||||||
                let left_group = f.group_id("BinaryLeft");
 | 
					                let left_group = f.group_id("BinaryLeft");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                write!(
 | 
					                write!(
 | 
				
			||||||
| 
						 | 
					@ -69,35 +138,22 @@ impl FormatNodeRule<ExprBinOp> for FormatExprBinOp {
 | 
				
			||||||
                            .with_group_id(Some(left_group))
 | 
					                            .with_group_id(Some(left_group))
 | 
				
			||||||
                    ]
 | 
					                    ]
 | 
				
			||||||
                )
 | 
					                )
 | 
				
			||||||
        } else {
 | 
					            }
 | 
				
			||||||
            let comments = f.context().comments().clone();
 | 
					 | 
				
			||||||
            let operator_comments = comments.dangling_comments(item.as_any_node_ref());
 | 
					 | 
				
			||||||
            let needs_space = !is_simple_power_expression(item);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            let before_operator_space = if needs_space {
 | 
					 | 
				
			||||||
                soft_line_break_or_space()
 | 
					 | 
				
			||||||
            } else {
 | 
					 | 
				
			||||||
                soft_line_break()
 | 
					 | 
				
			||||||
            };
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            BinaryLayout::ExpandRightThenLeft => {
 | 
				
			||||||
 | 
					                // The formatter expands group-sequences from right to left, and expands both if
 | 
				
			||||||
 | 
					                // there isn't enough space when expanding only one of them.
 | 
				
			||||||
                write!(
 | 
					                write!(
 | 
				
			||||||
                    f,
 | 
					                    f,
 | 
				
			||||||
                    [
 | 
					                    [
 | 
				
			||||||
                    left.format(),
 | 
					                        group(&left.format()),
 | 
				
			||||||
                    before_operator_space,
 | 
					                        space(),
 | 
				
			||||||
                        op.format(),
 | 
					                        op.format(),
 | 
				
			||||||
                    trailing_comments(operator_comments),
 | 
					                        space(),
 | 
				
			||||||
 | 
					                        group(&right.format())
 | 
				
			||||||
                    ]
 | 
					                    ]
 | 
				
			||||||
            )?;
 | 
					                )
 | 
				
			||||||
 | 
					 | 
				
			||||||
            // Format the operator on its own line if the right side has any leading comments.
 | 
					 | 
				
			||||||
            if comments.has_leading_comments(right.as_ref()) {
 | 
					 | 
				
			||||||
                write!(f, [hard_line_break()])?;
 | 
					 | 
				
			||||||
            } else if needs_space {
 | 
					 | 
				
			||||||
                write!(f, [space()])?;
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					 | 
				
			||||||
            write!(f, [group(&right.format())])
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -179,10 +235,13 @@ impl NeedsParentheses for ExprBinOp {
 | 
				
			||||||
    ) -> Parentheses {
 | 
					    ) -> Parentheses {
 | 
				
			||||||
        match default_expression_needs_parentheses(self.into(), parenthesize, source, comments) {
 | 
					        match default_expression_needs_parentheses(self.into(), parenthesize, source, comments) {
 | 
				
			||||||
            Parentheses::Optional => {
 | 
					            Parentheses::Optional => {
 | 
				
			||||||
                if should_binary_break_right_side_first(self) {
 | 
					                if BinaryLayout::from(self) == BinaryLayout::Default
 | 
				
			||||||
                    Parentheses::Custom
 | 
					                    || comments.has_leading_comments(self.right.as_ref())
 | 
				
			||||||
                } else {
 | 
					                    || comments.has_dangling_comments(self)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
                    Parentheses::Optional
 | 
					                    Parentheses::Optional
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                    Parentheses::Custom
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            parentheses => parentheses,
 | 
					            parentheses => parentheses,
 | 
				
			||||||
| 
						 | 
					@ -190,13 +249,65 @@ impl NeedsParentheses for ExprBinOp {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub(super) fn should_binary_break_right_side_first(expr: &ExprBinOp) -> bool {
 | 
					#[derive(Copy, Clone, Debug, Eq, PartialEq)]
 | 
				
			||||||
 | 
					enum BinaryLayout {
 | 
				
			||||||
 | 
					    /// Put each operand on their own line if either side expands
 | 
				
			||||||
 | 
					    Default,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Try to expand the left to make it fit. Add parentheses if the left or right don't fit.
 | 
				
			||||||
 | 
					    ///
 | 
				
			||||||
 | 
					    ///```python
 | 
				
			||||||
 | 
					    /// [
 | 
				
			||||||
 | 
					    ///     a,
 | 
				
			||||||
 | 
					    ///     b
 | 
				
			||||||
 | 
					    /// ] & c
 | 
				
			||||||
 | 
					    ///```
 | 
				
			||||||
 | 
					    ExpandLeft,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Try to expand the right to make it fix. Add parentheses if the left or right don't fit.
 | 
				
			||||||
 | 
					    ///
 | 
				
			||||||
 | 
					    /// ```python
 | 
				
			||||||
 | 
					    /// a & [
 | 
				
			||||||
 | 
					    ///     b,
 | 
				
			||||||
 | 
					    ///     c
 | 
				
			||||||
 | 
					    /// ]
 | 
				
			||||||
 | 
					    /// ```
 | 
				
			||||||
 | 
					    ExpandRight,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Both the left and right side can be expanded. Try in the following order:
 | 
				
			||||||
 | 
					    /// * expand the right side
 | 
				
			||||||
 | 
					    /// * expand the left side
 | 
				
			||||||
 | 
					    /// * expand both sides
 | 
				
			||||||
 | 
					    ///
 | 
				
			||||||
 | 
					    /// to make the expression fit
 | 
				
			||||||
 | 
					    ///
 | 
				
			||||||
 | 
					    /// ```python
 | 
				
			||||||
 | 
					    /// [
 | 
				
			||||||
 | 
					    ///     a,
 | 
				
			||||||
 | 
					    ///     b
 | 
				
			||||||
 | 
					    /// ] & [
 | 
				
			||||||
 | 
					    ///     c,
 | 
				
			||||||
 | 
					    ///     d
 | 
				
			||||||
 | 
					    /// ]
 | 
				
			||||||
 | 
					    /// ```
 | 
				
			||||||
 | 
					    ExpandRightThenLeft,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl BinaryLayout {
 | 
				
			||||||
 | 
					    fn from(expr: &ExprBinOp) -> Self {
 | 
				
			||||||
 | 
					        match (can_break(&expr.left), can_break(&expr.right)) {
 | 
				
			||||||
 | 
					            (false, false) => Self::Default,
 | 
				
			||||||
 | 
					            (true, false) => Self::ExpandLeft,
 | 
				
			||||||
 | 
					            (false, true) => Self::ExpandRight,
 | 
				
			||||||
 | 
					            (true, true) => Self::ExpandRightThenLeft,
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn can_break(expr: &Expr) -> bool {
 | 
				
			||||||
    use ruff_python_ast::prelude::*;
 | 
					    use ruff_python_ast::prelude::*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if expr.left.is_bin_op_expr() {
 | 
					    match expr {
 | 
				
			||||||
        false
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
        match expr.right.as_ref() {
 | 
					 | 
				
			||||||
        Expr::Tuple(ExprTuple {
 | 
					        Expr::Tuple(ExprTuple {
 | 
				
			||||||
            elts: expressions, ..
 | 
					            elts: expressions, ..
 | 
				
			||||||
        })
 | 
					        })
 | 
				
			||||||
| 
						 | 
					@ -210,11 +321,8 @@ pub(super) fn should_binary_break_right_side_first(expr: &ExprBinOp) -> bool {
 | 
				
			||||||
            values: expressions,
 | 
					            values: expressions,
 | 
				
			||||||
            ..
 | 
					            ..
 | 
				
			||||||
        }) => !expressions.is_empty(),
 | 
					        }) => !expressions.is_empty(),
 | 
				
			||||||
            Expr::Call(ExprCall { args, keywords, .. }) => !args.is_empty() && !keywords.is_empty(),
 | 
					        Expr::Call(ExprCall { args, keywords, .. }) => !(args.is_empty() && keywords.is_empty()),
 | 
				
			||||||
            Expr::ListComp(_) | Expr::SetComp(_) | Expr::DictComp(_) | Expr::GeneratorExp(_) => {
 | 
					        Expr::ListComp(_) | Expr::SetComp(_) | Expr::DictComp(_) | Expr::GeneratorExp(_) => true,
 | 
				
			||||||
                true
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        _ => false,
 | 
					        _ => false,
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -58,6 +58,141 @@ if (
 | 
				
			||||||
    ccccccccccc
 | 
					    ccccccccccc
 | 
				
			||||||
):
 | 
					):
 | 
				
			||||||
    pass
 | 
					    pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Left only breaks
 | 
				
			||||||
 | 
					if [
 | 
				
			||||||
 | 
					    aaaaaaaaaaaaa,
 | 
				
			||||||
 | 
					    bbbbbbbbbbbbbbbbbbbb,
 | 
				
			||||||
 | 
					    cccccccccccccccccccc,
 | 
				
			||||||
 | 
					    dddddddddddddddddddd,
 | 
				
			||||||
 | 
					    eeeeeeeeee,
 | 
				
			||||||
 | 
					] & aaaaaaaaaaaaaaaaaaaaaaaaaa:
 | 
				
			||||||
 | 
					    ...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if [
 | 
				
			||||||
 | 
					    aaaaaaaaaaaaa,
 | 
				
			||||||
 | 
					    bbbbbbbbbbbbbbbbbbbb,
 | 
				
			||||||
 | 
					    cccccccccccccccccccc,
 | 
				
			||||||
 | 
					    dddddddddddddddddddd,
 | 
				
			||||||
 | 
					    eeeeeeeeee,
 | 
				
			||||||
 | 
					] & aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:
 | 
				
			||||||
 | 
					    ...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Right only can break
 | 
				
			||||||
 | 
					if aaaaaaaaaaaaaaaaaaaaaaaaaa & [
 | 
				
			||||||
 | 
					    aaaaaaaaaaaaa,
 | 
				
			||||||
 | 
					    bbbbbbbbbbbbbbbbbbbb,
 | 
				
			||||||
 | 
					    cccccccccccccccccccc,
 | 
				
			||||||
 | 
					    dddddddddddddddddddd,
 | 
				
			||||||
 | 
					    eeeeeeeeee,
 | 
				
			||||||
 | 
					]:
 | 
				
			||||||
 | 
					    ...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa & [
 | 
				
			||||||
 | 
					    aaaaaaaaaaaaa,
 | 
				
			||||||
 | 
					    bbbbbbbbbbbbbbbbbbbb,
 | 
				
			||||||
 | 
					    cccccccccccccccccccc,
 | 
				
			||||||
 | 
					    dddddddddddddddddddd,
 | 
				
			||||||
 | 
					    eeeeeeeeee,
 | 
				
			||||||
 | 
					]:
 | 
				
			||||||
 | 
					    ...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Left or right can break
 | 
				
			||||||
 | 
					if [2222, 333] & [
 | 
				
			||||||
 | 
					    aaaaaaaaaaaaa,
 | 
				
			||||||
 | 
					    bbbbbbbbbbbbbbbbbbbb,
 | 
				
			||||||
 | 
					    cccccccccccccccccccc,
 | 
				
			||||||
 | 
					    dddddddddddddddddddd,
 | 
				
			||||||
 | 
					    eeeeeeeeee,
 | 
				
			||||||
 | 
					]:
 | 
				
			||||||
 | 
					    ...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if [
 | 
				
			||||||
 | 
					    aaaaaaaaaaaaa,
 | 
				
			||||||
 | 
					    bbbbbbbbbbbbbbbbbbbb,
 | 
				
			||||||
 | 
					    cccccccccccccccccccc,
 | 
				
			||||||
 | 
					    dddddddddddddddddddd,
 | 
				
			||||||
 | 
					    eeeeeeeeee,
 | 
				
			||||||
 | 
					] & [2222, 333]:
 | 
				
			||||||
 | 
					    ...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if [
 | 
				
			||||||
 | 
					    aaaaaaaaaaaaa,
 | 
				
			||||||
 | 
					    bbbbbbbbbbbbbbbbbbbb,
 | 
				
			||||||
 | 
					    cccccccccccccccccccc,
 | 
				
			||||||
 | 
					    dddddddddddddddddddd,
 | 
				
			||||||
 | 
					    eeeeeeeeee,
 | 
				
			||||||
 | 
					] & [fffffffffffffffff, gggggggggggggggggggg, hhhhhhhhhhhhhhhhhhhhh, iiiiiiiiiiiiiiii, jjjjjjjjjjjjj]:
 | 
				
			||||||
 | 
					    ...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if (
 | 
				
			||||||
 | 
					    # comment
 | 
				
			||||||
 | 
					    [
 | 
				
			||||||
 | 
					        aaaaaaaaaaaaa,
 | 
				
			||||||
 | 
					        bbbbbbbbbbbbbbbbbbbb,
 | 
				
			||||||
 | 
					        cccccccccccccccccccc,
 | 
				
			||||||
 | 
					        dddddddddddddddddddd,
 | 
				
			||||||
 | 
					        eeeeeeeeee,
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					) & [
 | 
				
			||||||
 | 
					    fffffffffffffffff,
 | 
				
			||||||
 | 
					    gggggggggggggggggggg,
 | 
				
			||||||
 | 
					    hhhhhhhhhhhhhhhhhhhhh,
 | 
				
			||||||
 | 
					    iiiiiiiiiiiiiiii,
 | 
				
			||||||
 | 
					    jjjjjjjjjjjjj,
 | 
				
			||||||
 | 
					]:
 | 
				
			||||||
 | 
					    pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Nesting
 | 
				
			||||||
 | 
					if (aaaa + b) & [
 | 
				
			||||||
 | 
					    fffffffffffffffff,
 | 
				
			||||||
 | 
					    gggggggggggggggggggg,
 | 
				
			||||||
 | 
					    hhhhhhhhhhhhhhhhhhhhh,
 | 
				
			||||||
 | 
					    iiiiiiiiiiiiiiii,
 | 
				
			||||||
 | 
					    jjjjjjjjjjjjj,
 | 
				
			||||||
 | 
					]:
 | 
				
			||||||
 | 
					    ...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if [
 | 
				
			||||||
 | 
					    fffffffffffffffff,
 | 
				
			||||||
 | 
					    gggggggggggggggggggg,
 | 
				
			||||||
 | 
					    hhhhhhhhhhhhhhhhhhhhh,
 | 
				
			||||||
 | 
					    iiiiiiiiiiiiiiii,
 | 
				
			||||||
 | 
					    jjjjjjjjjjjjj,
 | 
				
			||||||
 | 
					] & (a + b):
 | 
				
			||||||
 | 
					    ...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if [
 | 
				
			||||||
 | 
					    fffffffffffffffff,
 | 
				
			||||||
 | 
					    gggggggggggggggggggg,
 | 
				
			||||||
 | 
					    hhhhhhhhhhhhhhhhhhhhh,
 | 
				
			||||||
 | 
					    iiiiiiiiiiiiiiii,
 | 
				
			||||||
 | 
					    jjjjjjjjjjjjj,
 | 
				
			||||||
 | 
					] & (
 | 
				
			||||||
 | 
					    # comment
 | 
				
			||||||
 | 
					    a
 | 
				
			||||||
 | 
					    + b
 | 
				
			||||||
 | 
					):
 | 
				
			||||||
 | 
					    ...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if (
 | 
				
			||||||
 | 
					    [
 | 
				
			||||||
 | 
					        fffffffffffffffff,
 | 
				
			||||||
 | 
					        gggggggggggggggggggg,
 | 
				
			||||||
 | 
					        hhhhhhhhhhhhhhhhhhhhh,
 | 
				
			||||||
 | 
					        iiiiiiiiiiiiiiii,
 | 
				
			||||||
 | 
					        jjjjjjjjjjjjj,
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					    &
 | 
				
			||||||
 | 
					    # comment
 | 
				
			||||||
 | 
					    a + b
 | 
				
			||||||
 | 
					):
 | 
				
			||||||
 | 
					    ...
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -139,6 +274,158 @@ if (
 | 
				
			||||||
    ccccccccccc
 | 
					    ccccccccccc
 | 
				
			||||||
):
 | 
					):
 | 
				
			||||||
    pass
 | 
					    pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Left only breaks
 | 
				
			||||||
 | 
					if [
 | 
				
			||||||
 | 
					    aaaaaaaaaaaaa,
 | 
				
			||||||
 | 
					    bbbbbbbbbbbbbbbbbbbb,
 | 
				
			||||||
 | 
					    cccccccccccccccccccc,
 | 
				
			||||||
 | 
					    dddddddddddddddddddd,
 | 
				
			||||||
 | 
					    eeeeeeeeee,
 | 
				
			||||||
 | 
					] & aaaaaaaaaaaaaaaaaaaaaaaaaa:
 | 
				
			||||||
 | 
					    ...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if (
 | 
				
			||||||
 | 
					    [
 | 
				
			||||||
 | 
					        aaaaaaaaaaaaa,
 | 
				
			||||||
 | 
					        bbbbbbbbbbbbbbbbbbbb,
 | 
				
			||||||
 | 
					        cccccccccccccccccccc,
 | 
				
			||||||
 | 
					        dddddddddddddddddddd,
 | 
				
			||||||
 | 
					        eeeeeeeeee,
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					    & aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
 | 
				
			||||||
 | 
					):
 | 
				
			||||||
 | 
					    ...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Right only can break
 | 
				
			||||||
 | 
					if aaaaaaaaaaaaaaaaaaaaaaaaaa & [
 | 
				
			||||||
 | 
					    aaaaaaaaaaaaa,
 | 
				
			||||||
 | 
					    bbbbbbbbbbbbbbbbbbbb,
 | 
				
			||||||
 | 
					    cccccccccccccccccccc,
 | 
				
			||||||
 | 
					    dddddddddddddddddddd,
 | 
				
			||||||
 | 
					    eeeeeeeeee,
 | 
				
			||||||
 | 
					]:
 | 
				
			||||||
 | 
					    ...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if (
 | 
				
			||||||
 | 
					    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
 | 
				
			||||||
 | 
					    & [
 | 
				
			||||||
 | 
					        aaaaaaaaaaaaa,
 | 
				
			||||||
 | 
					        bbbbbbbbbbbbbbbbbbbb,
 | 
				
			||||||
 | 
					        cccccccccccccccccccc,
 | 
				
			||||||
 | 
					        dddddddddddddddddddd,
 | 
				
			||||||
 | 
					        eeeeeeeeee,
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					):
 | 
				
			||||||
 | 
					    ...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Left or right can break
 | 
				
			||||||
 | 
					if [2222, 333] & [
 | 
				
			||||||
 | 
					    aaaaaaaaaaaaa,
 | 
				
			||||||
 | 
					    bbbbbbbbbbbbbbbbbbbb,
 | 
				
			||||||
 | 
					    cccccccccccccccccccc,
 | 
				
			||||||
 | 
					    dddddddddddddddddddd,
 | 
				
			||||||
 | 
					    eeeeeeeeee,
 | 
				
			||||||
 | 
					]:
 | 
				
			||||||
 | 
					    ...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if [
 | 
				
			||||||
 | 
					    aaaaaaaaaaaaa,
 | 
				
			||||||
 | 
					    bbbbbbbbbbbbbbbbbbbb,
 | 
				
			||||||
 | 
					    cccccccccccccccccccc,
 | 
				
			||||||
 | 
					    dddddddddddddddddddd,
 | 
				
			||||||
 | 
					    eeeeeeeeee,
 | 
				
			||||||
 | 
					] & [2222, 333]:
 | 
				
			||||||
 | 
					    ...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if [
 | 
				
			||||||
 | 
					    aaaaaaaaaaaaa,
 | 
				
			||||||
 | 
					    bbbbbbbbbbbbbbbbbbbb,
 | 
				
			||||||
 | 
					    cccccccccccccccccccc,
 | 
				
			||||||
 | 
					    dddddddddddddddddddd,
 | 
				
			||||||
 | 
					    eeeeeeeeee,
 | 
				
			||||||
 | 
					] & [
 | 
				
			||||||
 | 
					    fffffffffffffffff,
 | 
				
			||||||
 | 
					    gggggggggggggggggggg,
 | 
				
			||||||
 | 
					    hhhhhhhhhhhhhhhhhhhhh,
 | 
				
			||||||
 | 
					    iiiiiiiiiiiiiiii,
 | 
				
			||||||
 | 
					    jjjjjjjjjjjjj,
 | 
				
			||||||
 | 
					]:
 | 
				
			||||||
 | 
					    ...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if (
 | 
				
			||||||
 | 
					    # comment
 | 
				
			||||||
 | 
					    [
 | 
				
			||||||
 | 
					        aaaaaaaaaaaaa,
 | 
				
			||||||
 | 
					        bbbbbbbbbbbbbbbbbbbb,
 | 
				
			||||||
 | 
					        cccccccccccccccccccc,
 | 
				
			||||||
 | 
					        dddddddddddddddddddd,
 | 
				
			||||||
 | 
					        eeeeeeeeee,
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					) & [
 | 
				
			||||||
 | 
					    fffffffffffffffff,
 | 
				
			||||||
 | 
					    gggggggggggggggggggg,
 | 
				
			||||||
 | 
					    hhhhhhhhhhhhhhhhhhhhh,
 | 
				
			||||||
 | 
					    iiiiiiiiiiiiiiii,
 | 
				
			||||||
 | 
					    jjjjjjjjjjjjj,
 | 
				
			||||||
 | 
					]:
 | 
				
			||||||
 | 
					    pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Nesting
 | 
				
			||||||
 | 
					if (aaaa + b) & [
 | 
				
			||||||
 | 
					    fffffffffffffffff,
 | 
				
			||||||
 | 
					    gggggggggggggggggggg,
 | 
				
			||||||
 | 
					    hhhhhhhhhhhhhhhhhhhhh,
 | 
				
			||||||
 | 
					    iiiiiiiiiiiiiiii,
 | 
				
			||||||
 | 
					    jjjjjjjjjjjjj,
 | 
				
			||||||
 | 
					]:
 | 
				
			||||||
 | 
					    ...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if [
 | 
				
			||||||
 | 
					    fffffffffffffffff,
 | 
				
			||||||
 | 
					    gggggggggggggggggggg,
 | 
				
			||||||
 | 
					    hhhhhhhhhhhhhhhhhhhhh,
 | 
				
			||||||
 | 
					    iiiiiiiiiiiiiiii,
 | 
				
			||||||
 | 
					    jjjjjjjjjjjjj,
 | 
				
			||||||
 | 
					] & (a + b):
 | 
				
			||||||
 | 
					    ...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if (
 | 
				
			||||||
 | 
					    [
 | 
				
			||||||
 | 
					        fffffffffffffffff,
 | 
				
			||||||
 | 
					        gggggggggggggggggggg,
 | 
				
			||||||
 | 
					        hhhhhhhhhhhhhhhhhhhhh,
 | 
				
			||||||
 | 
					        iiiiiiiiiiiiiiii,
 | 
				
			||||||
 | 
					        jjjjjjjjjjjjj,
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					    &
 | 
				
			||||||
 | 
					    (
 | 
				
			||||||
 | 
					        # comment
 | 
				
			||||||
 | 
					        a
 | 
				
			||||||
 | 
					        + b
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					):
 | 
				
			||||||
 | 
					    ...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if (
 | 
				
			||||||
 | 
					    [
 | 
				
			||||||
 | 
					        fffffffffffffffff,
 | 
				
			||||||
 | 
					        gggggggggggggggggggg,
 | 
				
			||||||
 | 
					        hhhhhhhhhhhhhhhhhhhhh,
 | 
				
			||||||
 | 
					        iiiiiiiiiiiiiiii,
 | 
				
			||||||
 | 
					        jjjjjjjjjjjjj,
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					    &
 | 
				
			||||||
 | 
					    # comment
 | 
				
			||||||
 | 
					    a
 | 
				
			||||||
 | 
					    + b
 | 
				
			||||||
 | 
					):
 | 
				
			||||||
 | 
					    ...
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue