ruff/crates/ruff_python_formatter/tests/snapshots
Charlie Marsh 1811312722
Improve with statement comment handling and expression breaking (#6621)
## Summary

The motivating code here was:

```python
with test as (
    # test
foo):
    pass
```

Which we were formatting as:

```python
with test as
# test
(foo):
    pass
```

`with` statements are oddly difficult. This PR makes a bunch of subtle
modifications and adds a more extensive test suite. For example, we now
only preserve parentheses if there's more than one `WithItem` _or_ a
trailing comma; before, we always preserved.

Our formatting is_not_ the same as Black, but here's a diff of our
formatted code vs. Black's for the `with.py` test suite. The primary
difference is that we tend to break parentheses when they contain
comments rather than move them to the end of the life (this is a
consistent difference that we make across the codebase):

```diff
diff --git a/crates/ruff_python_formatter/foo.py b/crates/ruff_python_formatter/foo.py
index 85e761080..31625c876 100644
--- a/crates/ruff_python_formatter/foo.py
+++ b/crates/ruff_python_formatter/foo.py
@@ -1,6 +1,4 @@
-with (
-    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-), aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:
+with aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:
     ...
     # trailing
 
@@ -16,28 +14,33 @@ with (
     # trailing
 
 
-with a, b:  # a  # comma  # c  # colon
+with (
+    a,  # a  # comma
+    b,  # c
+):  # colon
     ...
 
 
 with (
-    a as  # a  # as
-    # own line
-    b,  # b  # comma
+    a as (  # a  # as
+        # own line
+        b
+    ),  # b  # comma
     c,  # c
 ):  # colon
     ...  # body
     # body trailing own
 
-with (
-    a as  # a  # as
+with a as (  # a  # as
     # own line
-    bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb  # b
-):
+    bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+):  # b
     pass
 
 
-with (a,):  # magic trailing comma
+with (
+    a,
+):  # magic trailing comma
     ...
 
 
@@ -47,6 +50,7 @@ with a:  # should remove brackets
 with aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb as c:
     ...
 
+
 with (
     # leading comment
     a
@@ -74,8 +78,7 @@ with (
 with (
     a  # trailing same line comment
     # trailing own line comment
-    as b
-):
+) as b:
     ...
 
 with (
@@ -87,7 +90,9 @@ with (
 with (
     a
     # trailing own line comment
-) as b:  # trailing as same line comment  # trailing b same line comment
+) as (  # trailing as same line comment
+    b
+):  # trailing b same line comment
     ...
 
 with (
@@ -124,18 +129,24 @@ with (  # comment
     ...
 
 with (  # outer comment
-    CtxManager1() as example1,  # inner comment
+    (  # inner comment
+        CtxManager1()
+    ) as example1,
     CtxManager2() as example2,
     CtxManager3() as example3,
 ):
     ...
 
-with CtxManager() as example:  # outer comment
+with (  # outer comment
+    CtxManager()
+) as example:
     ...
 
 with (  # outer comment
     CtxManager()
-) as example, CtxManager2() as example2:  # inner comment
+) as example, (  # inner comment
+    CtxManager2()
+) as example2:
     ...
 
 with (  # outer comment
@@ -145,7 +156,9 @@ with (  # outer comment
     ...
 
 with (  # outer comment
-    (CtxManager1()),  # inner comment
+    (  # inner comment
+        CtxManager1()
+    ),
     CtxManager2(),
 ) as example:
     ...
@@ -179,7 +192,9 @@ with (
 ):
     pass
 
-with a as (b):  # foo
+with a as (  # foo
+    b
+):
     pass
 
 with f(
@@ -209,17 +224,13 @@ with f(
 ) as b, c as d:
     pass
 
-with (
-    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
-) as b:
+with aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb as b:
     pass
 
 with aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb as b:
     pass
 
-with (
-    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
-) as b, c as d:
+with aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb as b, c as d:
     pass
 
 with (
@@ -230,6 +241,8 @@ with (
     pass
 
 with (
-    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
-) as b, c as d:
+    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+    + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb as b,
+    c as d,
+):
     pass
```

Closes https://github.com/astral-sh/ruff/issues/6600.
## Test Plan

Before:

| project      | similarity index |
|--------------|------------------|
| cpython      | 0.75473          |
| django       | 0.99804          |
| transformers | 0.99618          |
| twine        | 0.99876          |
| typeshed     | 0.74292          |
| warehouse    | 0.99601          |
| zulip        | 0.99727          |

After:

| project      | similarity index |
|--------------|------------------|
| cpython      | 0.75473          |
| django       | 0.99804          |
| transformers | 0.99618          |
| twine        | 0.99876          |
| typeshed     | 0.74292          |
| warehouse    | 0.99601          |
| zulip        | 0.99727          |

`cargo test`
2023-08-18 03:30:38 +00:00
..
black_compatibility@conditional_expression.py.snap Format expr generator exp (#5804) 2023-07-19 13:01:58 +02: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 ExprJoinedStr (#5932) 2023-08-01 08:26:30 +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 Format docstrings (#6452) 2023-08-14 12:28:58 +00:00
black_compatibility@miscellaneous__docstring_preview_no_string_normalization.py.snap format ExprJoinedStr (#5932) 2023-08-01 08:26:30 +02:00
black_compatibility@miscellaneous__force_pyi.py.snap Format target: annotation = value? expressions (#5661) 2023-07-11 16:40:28 +02:00
black_compatibility@miscellaneous__long_strings_flag_disabled.py.snap format ExprJoinedStr (#5932) 2023-08-01 08:26:30 +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 format ExprJoinedStr (#5932) 2023-08-01 08:26:30 +02:00
black_compatibility@py_38__pep_572_remove_parens.py.snap Update Black tests (#6618) 2023-08-16 15:05:51 +00:00
black_compatibility@py_39__python39.py.snap Remove parentheses around some walrus operators (#6173) 2023-07-29 10:06:26 -04:00
black_compatibility@py_310__pattern_matching_complex.py.snap Call pattern formatting (#6594) 2023-08-16 08:31:25 +05:30
black_compatibility@py_310__pattern_matching_extras.py.snap Call pattern formatting (#6594) 2023-08-16 08:31:25 +05:30
black_compatibility@py_310__pattern_matching_generic.py.snap Call pattern formatting (#6594) 2023-08-16 08:31:25 +05:30
black_compatibility@py_310__pattern_matching_simple.py.snap Call pattern formatting (#6594) 2023-08-16 08:31:25 +05:30
black_compatibility@py_310__pattern_matching_style.py.snap Call pattern formatting (#6594) 2023-08-16 08:31:25 +05:30
black_compatibility@py_310__pep_572_py310.py.snap Format expr generator exp (#5804) 2023-07-19 13:01:58 +02:00
black_compatibility@py_310__remove_newline_after_match.py.snap Call pattern formatting (#6594) 2023-08-16 08:31:25 +05:30
black_compatibility@simple_cases__attribute_access_on_number_literals.py.snap Format numeric constants (#5972) 2023-07-24 07:04:40 +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 Add trailing comma for single-element import-from groups (#6583) 2023-08-15 07:15:33 -04:00
black_compatibility@simple_cases__comments6.py.snap Add general support for parenthesized comments on expressions (#6485) 2023-08-15 18:59:18 +00:00
black_compatibility@simple_cases__comments9.py.snap Remove newline-insertion logic from JoinNodesBuilder (#6205) 2023-07-31 16:58:15 -04:00
black_compatibility@simple_cases__composition.py.snap Mark trailing comments in parenthesized tests (#6287) 2023-08-03 20:45:03 +00:00
black_compatibility@simple_cases__composition_no_trailing_comma.py.snap Mark trailing comments in parenthesized tests (#6287) 2023-08-03 20:45:03 +00:00
black_compatibility@simple_cases__docstring_preview.py.snap Format docstrings (#6452) 2023-08-14 12:28:58 +00:00
black_compatibility@simple_cases__empty_lines.py.snap format ExprJoinedStr (#5932) 2023-08-01 08:26:30 +02:00
black_compatibility@simple_cases__expression.py.snap Call chain formatting in fluent style (#6151) 2023-08-04 13:58:01 +00:00
black_compatibility@simple_cases__fmtonoff.py.snap Support fmt: skip for simple-statements and decorators (#6561) 2023-08-17 05:58:19 +00:00
black_compatibility@simple_cases__fmtonoff4.py.snap fmt: off..on suppression comments (#6477) 2023-08-14 15:57:36 +00:00
black_compatibility@simple_cases__fmtonoff5.py.snap fmt: off..on suppression comments (#6477) 2023-08-14 15:57:36 +00:00
black_compatibility@simple_cases__fmtskip5.py.snap Improve comprehension line break beheavior 2023-07-11 16:51:24 +02:00
black_compatibility@simple_cases__function.py.snap Call chain formatting in fluent style (#6151) 2023-08-04 13:58:01 +00:00
black_compatibility@simple_cases__function2.py.snap Add empty lines before nested functions and classes (#6206) 2023-08-01 15:30:59 +00:00
black_compatibility@simple_cases__ignore_pyi.py.snap Rewrite placement logic (#6040) 2023-07-26 16:21:23 +00:00
black_compatibility@simple_cases__multiline_consecutive_open_parentheses_ignore.py.snap Add general support for parenthesized comments on expressions (#6485) 2023-08-15 18:59:18 +00:00
black_compatibility@simple_cases__remove_await_parens.py.snap Add general support for parenthesized comments on expressions (#6485) 2023-08-15 18:59:18 +00: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 Format lambda expression (#5806) 2023-07-19 11:47:56 +00:00
black_compatibility@simple_cases__remove_parens.py.snap format ExprJoinedStr (#5932) 2023-08-01 08:26:30 +02:00
black_compatibility@simple_cases__return_annotation_brackets.py.snap Add general support for parenthesized comments on expressions (#6485) 2023-08-15 18:59:18 +00:00
black_compatibility@simple_cases__torture.py.snap Expand parents whenever open-parenthesis comments are present (#6389) 2023-08-08 08:45:20 -04: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 Format assert statement (#5168) 2023-07-14 09:01:33 +02:00
black_compatibility@simple_cases__tupleassign.py.snap Format bytes string (#6166) 2023-07-31 10:46:40 +02: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@docstring.py.snap Format docstrings (#6452) 2023-08-14 12:28:58 +00:00
format@expression__annotated_assign.py.snap Format target: annotation = value? expressions (#5661) 2023-07-11 16:40:28 +02:00
format@expression__attribute.py.snap Add general support for parenthesized comments on expressions (#6485) 2023-08-15 18:59:18 +00:00
format@expression__binary.py.snap Fix zulip unstable formatting with end-of-line comments (#6386) 2023-08-08 09:15:35 +00:00
format@expression__binary_implicit_string.py.snap Fix formatting of chained boolean operations (#6394) 2023-08-07 12:22:33 -05:00
format@expression__boolean_operation.py.snap Fix formatting of chained boolean operations (#6394) 2023-08-07 12:22:33 -05:00
format@expression__bytes.py.snap Format bytes string (#6166) 2023-07-31 10:46:40 +02:00
format@expression__call.py.snap Add general support for parenthesized comments on expressions (#6485) 2023-08-15 18:59:18 +00:00
format@expression__compare.py.snap Avoid omitting optional parentheses for argument-less parentheses (#6484) 2023-08-11 17:58:42 +00:00
format@expression__dict.py.snap Fix zulip unstable formatting with end-of-line comments (#6386) 2023-08-08 09:15:35 +00:00
format@expression__dict_comp.py.snap Expand parents whenever open-parenthesis comments are present (#6389) 2023-08-08 08:45:20 -04:00
format@expression__fstring.py.snap move comments from expressions in f-strings out (#6481) 2023-08-11 09:22:30 +02:00
format@expression__generator_exp.py.snap Add general support for parenthesized comments on expressions (#6485) 2023-08-15 18:59:18 +00: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__lambda.py.snap Formatter: Fix posonlyargs for expr_lambda (#6562) 2023-08-14 17:38:56 +02:00
format@expression__list.py.snap Expand parents whenever open-parenthesis comments are present (#6389) 2023-08-08 08:45:20 -04:00
format@expression__list_comp.py.snap Tweak breaking groups for comprehensions (#6321) 2023-08-04 14:00:54 +00:00
format@expression__named_expr.py.snap Manually format comments around := in named expressions (#6634) 2023-08-18 03:10:45 +00:00
format@expression__set_comp.py.snap Avoid line break before for in comprehension if outer expression expands (#5912) 2023-07-20 10:07:22 +00:00
format@expression__slice.py.snap Improve slice formatting (#5922) 2023-07-20 15:05:18 +00:00
format@expression__split_empty_brackets.py.snap Avoid omitting optional parentheses for argument-less parentheses (#6484) 2023-08-11 17:58:42 +00:00
format@expression__starred.py.snap Fix comment formatting for yielded tuples (#6603) 2023-08-16 13:41:07 +00:00
format@expression__string.py.snap Fix formatting of trailing unescaped quotes in raw triple quoted strings (#6202) 2023-07-31 19:25:16 +02:00
format@expression__tuple.py.snap Fix parenthesized detection for tuples (#6599) 2023-08-16 13:20:48 +00:00
format@expression__unary.py.snap Prefer expanding parenthesized expressions before operands 2023-07-11 14:07:39 +02:00
format@expression__yield.py.snap Fix comment formatting for yielded tuples (#6603) 2023-08-16 13:41:07 +00:00
format@expression__yield_from.py.snap Format ExprYield/ExprYieldFrom (#5921) 2023-07-21 12:07:51 +00:00
format@fmt_on_off__comments.py.snap Indent statements in suppressed ranges (#6507) 2023-08-15 08:00:35 +02:00
format@fmt_on_off__empty_file.py.snap fmt: off..on suppression comments (#6477) 2023-08-14 15:57:36 +00:00
format@fmt_on_off__fmt_off_docstring.py.snap Indent statements in suppressed ranges (#6507) 2023-08-15 08:00:35 +02:00
format@fmt_on_off__form_feed.py.snap fmt: off..on suppression comments (#6477) 2023-08-14 15:57:36 +00:00
format@fmt_on_off__indent.py.snap Indent statements in suppressed ranges (#6507) 2023-08-15 08:00:35 +02:00
format@fmt_on_off__last_statement.py.snap fmt: off..on suppression comments (#6477) 2023-08-14 15:57:36 +00:00
format@fmt_on_off__mixed_space_and_tab.py.snap Indent statements in suppressed ranges (#6507) 2023-08-15 08:00:35 +02:00
format@fmt_on_off__no_fmt_on.py.snap fmt: off..on suppression comments (#6477) 2023-08-14 15:57:36 +00:00
format@fmt_on_off__off_on_off_on.py.snap fmt: off..on suppression comments (#6477) 2023-08-14 15:57:36 +00:00
format@fmt_on_off__simple.py.snap fmt: off..on suppression comments (#6477) 2023-08-14 15:57:36 +00:00
format@fmt_on_off__trailing_comments.py.snap fmt: off..on suppression comments (#6477) 2023-08-14 15:57:36 +00:00
format@fmt_on_off__yapf.py.snap fmt: off..on suppression comments (#6477) 2023-08-14 15:57:36 +00:00
format@fmt_skip__decorators.py.snap Support fmt: skip for simple-statements and decorators (#6561) 2023-08-17 05:58:19 +00:00
format@fmt_skip__docstrings.py.snap Support fmt: skip for simple-statements and decorators (#6561) 2023-08-17 05:58:19 +00:00
format@fmt_skip__match.py.snap Support fmt: skip on compound statements (#6593) 2023-08-17 06:05:41 +00:00
format@fmt_skip__or_else.py.snap Support fmt: skip on compound statements (#6593) 2023-08-17 06:05:41 +00:00
format@fmt_skip__parentheses.py.snap Support fmt: skip on compound statements (#6593) 2023-08-17 06:05:41 +00:00
format@fmt_skip__type_params.py.snap Support fmt: skip on compound statements (#6593) 2023-08-17 06:05:41 +00:00
format@parentheses__call_chains.py.snap Avoid breaking call chains unnecessarily (#6488) 2023-08-11 13:33:15 +00:00
format@parentheses__nested.py.snap Add general support for parenthesized comments on expressions (#6485) 2023-08-15 18:59:18 +00:00
format@parentheses__opening_parentheses_comment_empty.py.snap Call pattern formatting (#6594) 2023-08-16 08:31:25 +05:30
format@parentheses__opening_parentheses_comment_value.py.snap Call pattern formatting (#6594) 2023-08-16 08:31:25 +05:30
format@skip_magic_trailing_comma.py.snap Improve with statement comment handling and expression breaking (#6621) 2023-08-18 03:30:38 +00:00
format@statement__ann_assign.py.snap Fix StmtAnnAssign formatting by mirroring StmtAssign (#5732) 2023-07-13 10:51:25 +00:00
format@statement__assert.py.snap Add general support for parenthesized comments on expressions (#6485) 2023-08-15 18:59:18 +00:00
format@statement__assign.py.snap Add general support for parenthesized comments on expressions (#6485) 2023-08-15 18:59:18 +00:00
format@statement__aug_assign.py.snap Fix StmtAnnAssign formatting by mirroring StmtAssign (#5732) 2023-07-13 10:51:25 +00: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 Add formatting of type parameters in class and function definitions (#6161) 2023-08-02 20:29:28 +00:00
format@statement__delete.py.snap Fix zulip unstable formatting with end-of-line comments (#6386) 2023-08-08 09:15:35 +00:00
format@statement__for.py.snap Fix parenthesized detection for tuples (#6599) 2023-08-16 13:20:48 +00:00
format@statement__function.py.snap Add test case for walrus operators in return types (#6438) 2023-08-11 18:28:48 +00:00
format@statement__global.py.snap Break global and nonlocal statements over continuation lines (#6172) 2023-08-02 19:55:00 +00:00
format@statement__if.py.snap Fix formatter instability with half-indented comment (#6460) 2023-08-11 11:21:16 +00:00
format@statement__import.py.snap Add trailing comma for single-element import-from groups (#6583) 2023-08-15 07:15:33 -04:00
format@statement__import_from.py.snap Add trailing comma for single-element import-from groups (#6583) 2023-08-15 07:15:33 -04:00
format@statement__match.py.snap Call pattern formatting (#6594) 2023-08-16 08:31:25 +05:30
format@statement__nonlocal.py.snap Break global and nonlocal statements over continuation lines (#6172) 2023-08-02 19:55:00 +00:00
format@statement__raise.py.snap Add general support for parenthesized comments on expressions (#6485) 2023-08-15 18:59:18 +00:00
format@statement__return_annotation.py.snap Add general support for parenthesized comments on expressions (#6485) 2023-08-15 18:59:18 +00:00
format@statement__top_level.py.snap Use one line between top-level items if formatting a stub file (#6501) 2023-08-15 09:33:57 +02:00
format@statement__top_level.pyi.snap Use one line between top-level items if formatting a stub file (#6501) 2023-08-15 09:33:57 +02:00
format@statement__try.py.snap Mark trailing comments in parenthesized tests (#6287) 2023-08-03 20:45:03 +00:00
format@statement__type_alias.py.snap Add formatting of type alias statements (#6162) 2023-08-02 20:40:32 +00:00
format@statement__while.py.snap Pass parent to NeedsParentheses (#5708) 2023-07-13 08:57:29 +02:00
format@statement__with.py.snap Improve with statement comment handling and expression breaking (#6621) 2023-08-18 03:30:38 +00:00
format@trivia.py.snap Add tests for skip magic trailing comma 2023-06-26 14:15:55 +02:00