ruff/crates/ruff_python_formatter/tests/snapshots
Micha Reiser 715250a179
Prefer expanding parenthesized expressions before operands
<!--
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 implements Black's behavior where it first splits off parenthesized expressions before splitting before operands to avoid unnecessary parentheses:

```python
# We want 
if a + [ 
	b,
	c
]: 
	pass

# Rather than
if (
    a
    + [b, c]
): 
	pass
```

This is implemented by using the new IR elements introduced in #5596. 

* We give the group wrapping the optional parentheses an ID (`parentheses_id`)
* We use `conditional_group` for the lower priority groups  (all non-parenthesized expressions) with the condition that the `parentheses_id` group breaks (we want to split before operands only if the parentheses are necessary)
* We use `fits_expanded` to wrap all other parenthesized expressions (lists, dicts, sets), to prevent that expanding e.g. a list expands the `parentheses_id` group. We gate the `fits_expand` to only apply if the `parentheses_id` group fits (because we  prefer `a\n+[b, c]` over expanding `[b, c]` if the whole expression gets parenthesized).

We limit using `fits_expanded` and `conditional_group` only to expressions that themselves are not in parentheses (checking the conditions isn't free)

## Test Plan

It increases the Jaccard index for Django from 0.915 to 0.917

## Incompatibilites

There are two incompatibilities left that I'm aware of (there may be more, I didn't go through all snapshot differences). 

### Long string literals
I  commented on the regression. The issue is that a very long string (or any content without a split point) may not fit when only breaking the right side. The formatter than inserts the optional parentheses. But this is kind of useless because the overlong string will still not fit, because there are no new split points. 

I think we should ignore this incompatibility for now


### Expressions on statement level

I don't fully understand the logic behind this yet, but black doesn't break before the operators for the following example even though the expression exceeds the configured line width

```python
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa < bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb > ccccccccccccccccccccccccccccc == ddddddddddddddddddddd
```

But it would if the expression is used inside of a condition. 

What I understand so far is that Black doesn't insert optional parentheses on the expression statement level (and a few other places) and, therefore, only breaks after opening parentheses. I propose to keep this deviation for now to avoid overlong-lines and use the compatibility report to make a decision if we should implement the same behavior.
2023-07-11 14:07:39 +02:00
..
black_compatibility@conditional_expression.py.snap Format ExprIfExp (ternary operator) (#5597) 2023-07-07 19:11:52 +00:00
black_compatibility@miscellaneous__blackd_diff.py.snap Update Black tests (#5438) 2023-06-30 06:32:50 +00:00
black_compatibility@miscellaneous__debug_visitor.py.snap Format StmtAugAssign (#5655) 2023-07-11 09:06:23 +02:00
black_compatibility@miscellaneous__decorators.py.snap Format ExpressionStarred nodes (#5654) 2023-07-11 06:08:08 +00:00
black_compatibility@miscellaneous__docstring_no_string_normalization.py.snap Update Black tests (#5438) 2023-06-30 06:32:50 +00:00
black_compatibility@miscellaneous__docstring_preview_no_string_normalization.py.snap Update Black tests (#5438) 2023-06-30 06:32:50 +00:00
black_compatibility@miscellaneous__force_pyi.py.snap Format import statements (#5493) 2023-07-04 07:07:20 +00:00
black_compatibility@miscellaneous__long_strings_flag_disabled.py.snap Format StmtAugAssign (#5655) 2023-07-11 09:06:23 +02:00
black_compatibility@miscellaneous__power_op_newline.py.snap Update Black tests (#5438) 2023-06-30 06:32:50 +00:00
black_compatibility@miscellaneous__string_quotes.py.snap Update Black tests (#5438) 2023-06-30 06:32:50 +00:00
black_compatibility@py_36__numeric_literals.py.snap Update Black tests (#5438) 2023-06-30 06:32:50 +00:00
black_compatibility@py_36__numeric_literals_skip_underscores.py.snap Update Black tests (#5438) 2023-06-30 06:32:50 +00:00
black_compatibility@py_37__python37.py.snap format ExprListComp (#5600) 2023-07-11 06:35:51 +00:00
black_compatibility@py_38__pep_570.py.snap Update Black tests (#5438) 2023-06-30 06:32:50 +00:00
black_compatibility@py_38__pep_572.py.snap format ExprListComp (#5600) 2023-07-11 06:35:51 +00:00
black_compatibility@py_38__python38.py.snap Format ExpressionStarred nodes (#5654) 2023-07-11 06:08:08 +00:00
black_compatibility@py_39__pep_572_py39.py.snap Format named expressions (walrus operator) (#5642) 2023-07-10 12:32:15 +00:00
black_compatibility@py_39__python39.py.snap Format named expressions (walrus operator) (#5642) 2023-07-10 12:32:15 +00:00
black_compatibility@py_310__pattern_matching_complex.py.snap Update Black tests (#5438) 2023-06-30 06:32:50 +00:00
black_compatibility@py_310__pattern_matching_extras.py.snap Format import statements (#5493) 2023-07-04 07:07:20 +00:00
black_compatibility@py_310__pattern_matching_generic.py.snap Format StmtAugAssign (#5655) 2023-07-11 09:06:23 +02:00
black_compatibility@py_310__pattern_matching_simple.py.snap Update Black tests (#5438) 2023-06-30 06:32:50 +00:00
black_compatibility@py_310__pattern_matching_style.py.snap Don't add a magic trailing comma for a single entry (#5463) 2023-07-03 21:48:44 +02:00
black_compatibility@py_310__pep_572_py310.py.snap Format named expressions (walrus operator) (#5642) 2023-07-10 12:32:15 +00:00
black_compatibility@py_310__remove_newline_after_match.py.snap Update Black tests (#5438) 2023-06-30 06:32:50 +00:00
black_compatibility@py_310__starred_for_target.py.snap Format ExpressionStarred nodes (#5654) 2023-07-11 06:08:08 +00:00
black_compatibility@simple_cases__attribute_access_on_number_literals.py.snap Update Black tests (#5438) 2023-06-30 06:32:50 +00:00
black_compatibility@simple_cases__bracketmatch.py.snap Update Black tests (#5438) 2023-06-30 06:32:50 +00:00
black_compatibility@simple_cases__class_methods_new_line.py.snap Update Black tests (#5438) 2023-06-30 06:32:50 +00:00
black_compatibility@simple_cases__collections.py.snap Format import statements (#5493) 2023-07-04 07:07:20 +00:00
black_compatibility@simple_cases__comment_after_escaped_newline.py.snap Update Black tests (#5438) 2023-06-30 06:32:50 +00:00
black_compatibility@simple_cases__comments2.py.snap format ExprListComp (#5600) 2023-07-11 06:35:51 +00:00
black_compatibility@simple_cases__comments3.py.snap format ExprListComp (#5600) 2023-07-11 06:35:51 +00:00
black_compatibility@simple_cases__comments4.py.snap Format import statements (#5493) 2023-07-04 07:07:20 +00:00
black_compatibility@simple_cases__comments6.py.snap Format ExpressionStarred nodes (#5654) 2023-07-11 06:08:08 +00:00
black_compatibility@simple_cases__comments9.py.snap Update Black tests (#5438) 2023-06-30 06:32:50 +00:00
black_compatibility@simple_cases__comments_non_breaking_space.py.snap Format import statements (#5493) 2023-07-04 07:07:20 +00:00
black_compatibility@simple_cases__composition.py.snap Prefer expanding parenthesized expressions before operands 2023-07-11 14:07:39 +02:00
black_compatibility@simple_cases__composition_no_trailing_comma.py.snap Prefer expanding parenthesized expressions before operands 2023-07-11 14:07:39 +02:00
black_compatibility@simple_cases__docstring.py.snap Update Black tests (#5438) 2023-06-30 06:32:50 +00:00
black_compatibility@simple_cases__docstring_preview.py.snap Update Black tests (#5438) 2023-06-30 06:32:50 +00:00
black_compatibility@simple_cases__empty_lines.py.snap Prefer expanding parenthesized expressions before operands 2023-07-11 14:07:39 +02:00
black_compatibility@simple_cases__expression.py.snap format ExprListComp (#5600) 2023-07-11 06:35:51 +00:00
black_compatibility@simple_cases__fmtonoff.py.snap Format ExpressionStarred nodes (#5654) 2023-07-11 06:08:08 +00:00
black_compatibility@simple_cases__fmtonoff2.py.snap Format import statements (#5493) 2023-07-04 07:07:20 +00:00
black_compatibility@simple_cases__fmtonoff3.py.snap Update Black tests (#5438) 2023-06-30 06:32:50 +00:00
black_compatibility@simple_cases__fmtonoff4.py.snap Don't add a magic trailing comma for a single entry (#5463) 2023-07-03 21:48:44 +02:00
black_compatibility@simple_cases__fmtonoff5.py.snap Don't add a magic trailing comma for a single entry (#5463) 2023-07-03 21:48:44 +02:00
black_compatibility@simple_cases__fmtskip.py.snap Update Black tests (#5438) 2023-06-30 06:32:50 +00:00
black_compatibility@simple_cases__fmtskip2.py.snap Update Black tests (#5438) 2023-06-30 06:32:50 +00:00
black_compatibility@simple_cases__fmtskip3.py.snap Update Black tests (#5438) 2023-06-30 06:32:50 +00:00
black_compatibility@simple_cases__fmtskip5.py.snap Update Black tests (#5438) 2023-06-30 06:32:50 +00:00
black_compatibility@simple_cases__fmtskip7.py.snap Update Black tests (#5438) 2023-06-30 06:32:50 +00:00
black_compatibility@simple_cases__fmtskip8.py.snap Update Black tests (#5438) 2023-06-30 06:32:50 +00:00
black_compatibility@simple_cases__fstring.py.snap Update Black tests (#5438) 2023-06-30 06:32:50 +00:00
black_compatibility@simple_cases__function.py.snap Format raise statement (#5595) 2023-07-10 21:23:49 +02:00
black_compatibility@simple_cases__function2.py.snap Format import statements (#5493) 2023-07-04 07:07:20 +00:00
black_compatibility@simple_cases__function_trailing_comma.py.snap Prefer expanding parenthesized expressions before operands 2023-07-11 14:07:39 +02:00
black_compatibility@simple_cases__import_spacing.py.snap Format import statements (#5493) 2023-07-04 07:07:20 +00:00
black_compatibility@simple_cases__one_element_subscript.py.snap Update Black tests (#5438) 2023-06-30 06:32:50 +00:00
black_compatibility@simple_cases__power_op_spacing.py.snap format ExprListComp (#5600) 2023-07-11 06:35:51 +00:00
black_compatibility@simple_cases__remove_await_parens.py.snap Prefer expanding parenthesized expressions before operands 2023-07-11 14:07:39 +02:00
black_compatibility@simple_cases__remove_except_parens.py.snap Format raise statement (#5595) 2023-07-10 21:23:49 +02:00
black_compatibility@simple_cases__remove_for_brackets.py.snap Update Black tests (#5438) 2023-06-30 06:32:50 +00:00
black_compatibility@simple_cases__remove_newline_after_code_block_open.py.snap Format import statements (#5493) 2023-07-04 07:07:20 +00:00
black_compatibility@simple_cases__remove_parens.py.snap Update Black tests (#5438) 2023-06-30 06:32:50 +00:00
black_compatibility@simple_cases__return_annotation_brackets.py.snap Update Black tests (#5438) 2023-06-30 06:32:50 +00:00
black_compatibility@simple_cases__skip_magic_trailing_comma.py.snap Update Black tests (#5438) 2023-06-30 06:32:50 +00:00
black_compatibility@simple_cases__slices.py.snap format ExprListComp (#5600) 2023-07-11 06:35:51 +00:00
black_compatibility@simple_cases__string_prefixes.py.snap Update Black tests (#5438) 2023-06-30 06:32:50 +00:00
black_compatibility@simple_cases__torture.py.snap Prefer expanding parenthesized expressions before operands 2023-07-11 14:07:39 +02:00
black_compatibility@simple_cases__trailing_comma_optional_parens1.py.snap Prefer expanding parenthesized expressions before operands 2023-07-11 14:07:39 +02:00
black_compatibility@simple_cases__trailing_comma_optional_parens3.py.snap Prefer expanding parenthesized expressions before operands 2023-07-11 14:07:39 +02:00
black_compatibility@simple_cases__trailing_commas_in_leading_parts.py.snap Prefer expanding parenthesized expressions before operands 2023-07-11 14:07:39 +02:00
black_compatibility@simple_cases__tupleassign.py.snap Update Black tests (#5438) 2023-06-30 06:32:50 +00:00
black_compatibility@simple_cases__whitespace.py.snap Update Black tests (#5438) 2023-06-30 06:32:50 +00:00
format@carriage_return__string.py.snap Normalize '\r' in string literals to '\n' 2023-06-30 10:13:23 +02:00
format@expression__attribute.py.snap Format import statements (#5493) 2023-07-04 07:07:20 +00:00
format@expression__binary.py.snap Prefer expanding parenthesized expressions before operands 2023-07-11 14:07:39 +02:00
format@expression__boolean_operation.py.snap Format call expressions (without call chaining) (#5341) 2023-06-27 09:29:40 +00:00
format@expression__call.py.snap Format import statements (#5493) 2023-07-04 07:07:20 +00:00
format@expression__compare.py.snap Prefer expanding parenthesized expressions before operands 2023-07-11 14:07:39 +02:00
format@expression__dict.py.snap Fix typos found by codespell (#5607) 2023-07-08 12:33:18 +02:00
format@expression__if.py.snap Fix find_only_token_in_range with expression parentheses (#5645) 2023-07-10 15:55:19 +02:00
format@expression__list.py.snap Don't add a magic trailing comma for a single entry (#5463) 2023-07-03 21:48:44 +02:00
format@expression__list_comp.py.snap formatter: tidy: list_comp is an expression, not a statement (#5677) 2023-07-11 08:00:10 +00:00
format@expression__named_expr.py.snap Format named expressions (walrus operator) (#5642) 2023-07-10 12:32:15 +00:00
format@expression__slice.py.snap Format call expressions (without call chaining) (#5341) 2023-06-27 09:29:40 +00:00
format@expression__starred.py.snap Format ExpressionStarred nodes (#5654) 2023-07-11 06:08:08 +00:00
format@expression__string.py.snap Fix typos found by codespell (#5607) 2023-07-08 12:33:18 +02:00
format@expression__tuple.py.snap Format raise statement (#5595) 2023-07-10 21:23:49 +02:00
format@expression__unary.py.snap Prefer expanding parenthesized expressions before operands 2023-07-11 14:07:39 +02:00
format@skip_magic_trailing_comma.py.snap Fix typos found by codespell (#5607) 2023-07-08 12:33:18 +02:00
format@statement__ann_assign.py.snap Format StmtAugAssign (#5655) 2023-07-11 09:06:23 +02:00
format@statement__assign.py.snap Add tests for skip magic trailing comma 2023-06-26 14:15:55 +02:00
format@statement__break.py.snap Add tests for skip magic trailing comma 2023-06-26 14:15:55 +02:00
format@statement__class_definition.py.snap Fix invalid syntax for binary expression in unary op (#5370) 2023-06-29 08:09:26 +02:00
format@statement__delete.py.snap Format delete statement (#5169) 2023-07-11 08:36:26 +02:00
format@statement__for.py.snap Add tests for skip magic trailing comma 2023-06-26 14:15:55 +02:00
format@statement__function.py.snap Add tests for skip magic trailing comma 2023-06-26 14:15:55 +02:00
format@statement__if.py.snap Add tests for skip magic trailing comma 2023-06-26 14:15:55 +02:00
format@statement__import.py.snap Format import statements (#5493) 2023-07-04 07:07:20 +00:00
format@statement__import_from.py.snap Format import statements (#5493) 2023-07-04 07:07:20 +00:00
format@statement__raise.py.snap Prefer expanding parenthesized expressions before operands 2023-07-11 14:07:39 +02:00
format@statement__try.py.snap Fix formatter StmtTry test (#5568) 2023-07-06 18:23:53 +00:00
format@statement__while.py.snap Format call expressions (without call chaining) (#5341) 2023-06-27 09:29:40 +00:00
format@statement__with.py.snap Format ExpressionStarred nodes (#5654) 2023-07-11 06:08:08 +00:00
format@trivia.py.snap Add tests for skip magic trailing comma 2023-06-26 14:15:55 +02:00