format StmtWith (#5350)

This commit is contained in:
David Szotten 2023-06-26 15:09:06 +01:00 committed by GitHub
parent 49cabca3e7
commit d00559e42a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 380 additions and 80 deletions

View file

@ -0,0 +1,54 @@
with aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:
...
# trailing
with a, a: # after colon
...
# trailing
with (
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,
):
...
# trailing
with (
a # a
, # comma
b # c
): # colon
...
with (
a # a
as # as
b # b
, # comma
c # c
): # colon
... # body
# body trailing own
with (a,): # magic trailing comma
...
with (a): # should remove brackets
...
# TODO: black doesn't wrap this, but maybe we want to anyway?
# if we do want to wrap, do we prefer to wrap the entire WithItem or to let the
# WithItem allow the `aa + bb` content expression to be wrapped
with aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb as c:
...
# currently unparsable by black: https://github.com/psf/black/issues/3678
with (name_2 for name_0 in name_4):
pass
with (a, *b):
pass

View file

@ -2,7 +2,7 @@ use crate::comments::Comments;
use crate::expression::parentheses::{
default_expression_needs_parentheses, NeedsParentheses, Parentheses, Parenthesize,
};
use crate::{not_yet_implemented, FormatNodeRule, PyFormatter};
use crate::{not_yet_implemented_custom_text, FormatNodeRule, PyFormatter};
use ruff_formatter::{write, Buffer, FormatResult};
use rustpython_parser::ast::ExprStarred;
@ -10,8 +10,13 @@ use rustpython_parser::ast::ExprStarred;
pub struct FormatExprStarred;
impl FormatNodeRule<ExprStarred> for FormatExprStarred {
fn fmt_fields(&self, item: &ExprStarred, f: &mut PyFormatter) -> FormatResult<()> {
write!(f, [not_yet_implemented(item)])
fn fmt_fields(&self, _item: &ExprStarred, f: &mut PyFormatter) -> FormatResult<()> {
write!(
f,
[not_yet_implemented_custom_text(
"*NOT_YET_IMPLEMENTED_ExprStarred"
)]
)
}
}

View file

@ -1,4 +1,6 @@
use crate::{not_yet_implemented, FormatNodeRule, PyFormatter};
use crate::expression::parentheses::Parenthesize;
use crate::prelude::*;
use crate::{FormatNodeRule, PyFormatter};
use ruff_formatter::{write, Buffer, FormatResult};
use rustpython_parser::ast::WithItem;
@ -7,6 +9,22 @@ pub struct FormatWithItem;
impl FormatNodeRule<WithItem> for FormatWithItem {
fn fmt_fields(&self, item: &WithItem, f: &mut PyFormatter) -> FormatResult<()> {
write!(f, [not_yet_implemented(item)])
let WithItem {
range: _,
context_expr,
optional_vars,
} = item;
let inner = format_with(|f| {
write!(
f,
[context_expr.format().with_options(Parenthesize::IfBreaks)]
)?;
if let Some(optional_vars) = optional_vars {
write!(f, [space(), text("as"), space(), optional_vars.format()])?;
}
Ok(())
});
write!(f, [group(&inner)])
}
}

View file

@ -1,5 +1,9 @@
use crate::{not_yet_implemented, FormatNodeRule, PyFormatter};
use crate::builders::optional_parentheses;
use crate::comments::trailing_comments;
use crate::prelude::*;
use crate::{FormatNodeRule, PyFormatter};
use ruff_formatter::{write, Buffer, FormatResult};
use ruff_python_ast::prelude::*;
use rustpython_parser::ast::StmtWith;
#[derive(Default)]
@ -7,6 +11,33 @@ pub struct FormatStmtWith;
impl FormatNodeRule<StmtWith> for FormatStmtWith {
fn fmt_fields(&self, item: &StmtWith, f: &mut PyFormatter) -> FormatResult<()> {
write!(f, [not_yet_implemented(item)])
let StmtWith {
range: _,
items,
body,
type_comment: _,
} = item;
let comments = f.context().comments().clone();
let dangling_comments = comments.dangling_comments(item.as_any_node_ref());
let joined_items = format_with(|f| f.join_comma_separated().nodes(items.iter()).finish());
write!(
f,
[
text("with"),
space(),
group(&optional_parentheses(&joined_items)),
text(":"),
trailing_comments(dangling_comments),
block_indent(&body.format())
]
)
}
fn fmt_dangling_comments(&self, _node: &StmtWith, _f: &mut PyFormatter) -> FormatResult<()> {
// Handled in `fmt_fields`
Ok(())
}
}

View file

@ -93,7 +93,7 @@ if __name__ == "__main__":
# Comment belongs to the `if` block.
# This one belongs to the `while` block.
@@ -8,26 +8,20 @@
@@ -8,26 +8,21 @@
# This one is properly standalone now.
@ -110,22 +110,23 @@ if __name__ == "__main__":
-with open(some_temp_file) as f:
- data = f.read()
+NOT_YET_IMPLEMENTED_StmtWith
-
-try:
- with open(some_other_file) as w:
- w.write(data)
+NOT_YET_IMPLEMENTED_StmtTry
+with NOT_IMPLEMENTED_call(NOT_IMPLEMENTED_arg) as f:
+ data = NOT_IMPLEMENTED_call()
-except OSError:
- print("problems")
-
+NOT_YET_IMPLEMENTED_StmtTry
-import sys
+NOT_YET_IMPLEMENTED_StmtImport
# leading function comment
@@ -42,7 +36,7 @@
@@ -42,7 +37,7 @@
# leading 1
@deco1
# leading 2
@ -134,7 +135,7 @@ if __name__ == "__main__":
# leading 3
@deco3
def decorated1():
@@ -52,7 +46,7 @@
@@ -52,7 +47,7 @@
# leading 1
@deco1
# leading 2
@ -143,7 +144,7 @@ if __name__ == "__main__":
# leading function comment
def decorated1():
...
@@ -70,4 +64,4 @@
@@ -70,4 +65,4 @@
if __name__ == "__main__":
@ -173,7 +174,8 @@ for i in NOT_IMPLEMENTED_call(NOT_IMPLEMENTED_arg):
NOT_IMPLEMENTED_call(NOT_IMPLEMENTED_arg)
# and finally we loop around
NOT_YET_IMPLEMENTED_StmtWith
with NOT_IMPLEMENTED_call(NOT_IMPLEMENTED_arg) as f:
data = NOT_IMPLEMENTED_call()
NOT_YET_IMPLEMENTED_StmtTry

View file

@ -193,7 +193,7 @@ class C:
```diff
--- Black
+++ Ruff
@@ -1,159 +1,42 @@
@@ -1,23 +1,10 @@
class C:
def test(self) -> None:
- with patch("black.out", print):
@ -214,18 +214,22 @@ class C:
- "2 files reformatted, 2 files left unchanged, 2 files failed to"
- " reformat.",
- )
- for i in (a,):
- if (
- # Rule 1
- i % 2 == 0
- # Rule 2
- and i % 3 == 0
- ):
- while (
- # Just a comment
+ with NOT_IMPLEMENTED_call(NOT_IMPLEMENTED_arg):
+ NOT_IMPLEMENTED_call(NOT_IMPLEMENTED_arg)
+ NOT_IMPLEMENTED_call(NOT_IMPLEMENTED_arg)
+ NOT_IMPLEMENTED_call(NOT_IMPLEMENTED_arg)
+ NOT_IMPLEMENTED_call(NOT_IMPLEMENTED_arg)
for i in (a,):
if (
# Rule 1
@@ -27,133 +14,46 @@
):
while (
# Just a comment
- call()
- # Another
- ):
+ NOT_IMPLEMENTED_call()
):
- print(i)
- xxxxxxxxxxxxxxxx = Yyyy2YyyyyYyyyyy(
- push_manager=context.request.resource_manager,
@ -235,7 +239,8 @@ class C:
- # Only send the first n items.
- items=items[:num_items]
- )
+ NOT_YET_IMPLEMENTED_StmtWith
+ # Another
+ NOT_IMPLEMENTED_call(NOT_IMPLEMENTED_arg)
+ xxxxxxxxxxxxxxxx = NOT_IMPLEMENTED_call(NOT_IMPLEMENTED_arg)
return (
'Utterly failed doctest test for %s\n File "%s", line %s, in %s\n\n%s'
@ -371,7 +376,7 @@ class C:
%3d 0 LOAD_FAST 1 (x)
2 LOAD_CONST 1 (1)
4 COMPARE_OP 2 (==)
@@ -161,21 +44,8 @@
@@ -161,21 +61,8 @@
8 STORE_ATTR 0 (x)
10 LOAD_CONST 0 (None)
12 RETURN_VALUE
@ -403,7 +408,24 @@ class C:
```py
class C:
def test(self) -> None:
NOT_YET_IMPLEMENTED_StmtWith
with NOT_IMPLEMENTED_call(NOT_IMPLEMENTED_arg):
NOT_IMPLEMENTED_call(NOT_IMPLEMENTED_arg)
NOT_IMPLEMENTED_call(NOT_IMPLEMENTED_arg)
NOT_IMPLEMENTED_call(NOT_IMPLEMENTED_arg)
NOT_IMPLEMENTED_call(NOT_IMPLEMENTED_arg)
for i in (a,):
if (
# Rule 1
i % 2 == 0
# Rule 2
and i % 3 == 0
):
while (
# Just a comment
NOT_IMPLEMENTED_call()
):
# Another
NOT_IMPLEMENTED_call(NOT_IMPLEMENTED_arg)
xxxxxxxxxxxxxxxx = NOT_IMPLEMENTED_call(NOT_IMPLEMENTED_arg)
return (
'Utterly failed doctest test for %s\n File "%s", line %s, in %s\n\n%s'

View file

@ -193,7 +193,7 @@ class C:
```diff
--- Black
+++ Ruff
@@ -1,159 +1,42 @@
@@ -1,23 +1,10 @@
class C:
def test(self) -> None:
- with patch("black.out", print):
@ -214,18 +214,22 @@ class C:
- "2 files reformatted, 2 files left unchanged, 2 files failed to"
- " reformat.",
- )
- for i in (a,):
- if (
- # Rule 1
- i % 2 == 0
- # Rule 2
- and i % 3 == 0
- ):
- while (
- # Just a comment
+ with NOT_IMPLEMENTED_call(NOT_IMPLEMENTED_arg):
+ NOT_IMPLEMENTED_call(NOT_IMPLEMENTED_arg)
+ NOT_IMPLEMENTED_call(NOT_IMPLEMENTED_arg)
+ NOT_IMPLEMENTED_call(NOT_IMPLEMENTED_arg)
+ NOT_IMPLEMENTED_call(NOT_IMPLEMENTED_arg)
for i in (a,):
if (
# Rule 1
@@ -27,133 +14,46 @@
):
while (
# Just a comment
- call()
- # Another
- ):
+ NOT_IMPLEMENTED_call()
):
- print(i)
- xxxxxxxxxxxxxxxx = Yyyy2YyyyyYyyyyy(
- push_manager=context.request.resource_manager,
@ -235,7 +239,8 @@ class C:
- # Only send the first n items.
- items=items[:num_items]
- )
+ NOT_YET_IMPLEMENTED_StmtWith
+ # Another
+ NOT_IMPLEMENTED_call(NOT_IMPLEMENTED_arg)
+ xxxxxxxxxxxxxxxx = NOT_IMPLEMENTED_call(NOT_IMPLEMENTED_arg)
return (
'Utterly failed doctest test for %s\n File "%s", line %s, in %s\n\n%s'
@ -371,7 +376,7 @@ class C:
%3d 0 LOAD_FAST 1 (x)
2 LOAD_CONST 1 (1)
4 COMPARE_OP 2 (==)
@@ -161,21 +44,8 @@
@@ -161,21 +61,8 @@
8 STORE_ATTR 0 (x)
10 LOAD_CONST 0 (None)
12 RETURN_VALUE
@ -403,7 +408,24 @@ class C:
```py
class C:
def test(self) -> None:
NOT_YET_IMPLEMENTED_StmtWith
with NOT_IMPLEMENTED_call(NOT_IMPLEMENTED_arg):
NOT_IMPLEMENTED_call(NOT_IMPLEMENTED_arg)
NOT_IMPLEMENTED_call(NOT_IMPLEMENTED_arg)
NOT_IMPLEMENTED_call(NOT_IMPLEMENTED_arg)
NOT_IMPLEMENTED_call(NOT_IMPLEMENTED_arg)
for i in (a,):
if (
# Rule 1
i % 2 == 0
# Rule 2
and i % 3 == 0
):
while (
# Just a comment
NOT_IMPLEMENTED_call()
):
# Another
NOT_IMPLEMENTED_call(NOT_IMPLEMENTED_arg)
xxxxxxxxxxxxxxxx = NOT_IMPLEMENTED_call(NOT_IMPLEMENTED_arg)
return (
'Utterly failed doctest test for %s\n File "%s", line %s, in %s\n\n%s'

View file

@ -353,10 +353,10 @@ last_call()
- 5,
-]
+[1, 2, 3]
+[NOT_YET_IMPLEMENTED_ExprStarred]
+[NOT_YET_IMPLEMENTED_ExprStarred]
+[NOT_YET_IMPLEMENTED_ExprStarred, 4, 5]
+[4, NOT_YET_IMPLEMENTED_ExprStarred, 5]
+[*NOT_YET_IMPLEMENTED_ExprStarred]
+[*NOT_YET_IMPLEMENTED_ExprStarred]
+[*NOT_YET_IMPLEMENTED_ExprStarred, 4, 5]
+[4, *NOT_YET_IMPLEMENTED_ExprStarred, 5]
[
- 4,
- *a,
@ -367,7 +367,7 @@ last_call()
element,
another,
- *more,
+ NOT_YET_IMPLEMENTED_ExprStarred,
+ *NOT_YET_IMPLEMENTED_ExprStarred,
]
-{i for i in (1, 2, 3)}
-{(i**2) for i in (1, 2, 3)}
@ -512,7 +512,7 @@ last_call()
+(i for i in [])
+(i for i in [])
+(i for i in [])
+(NOT_YET_IMPLEMENTED_ExprStarred,)
+(*NOT_YET_IMPLEMENTED_ExprStarred,)
{
"id": "1",
"type": "type",
@ -544,8 +544,8 @@ last_call()
- .order_by(models.Customer.id.asc())
- .all()
+e = NOT_IMPLEMENTED_call(NOT_IMPLEMENTED_arg)
+f = 1, NOT_YET_IMPLEMENTED_ExprStarred
+g = 1, NOT_YET_IMPLEMENTED_ExprStarred
+f = 1, *NOT_YET_IMPLEMENTED_ExprStarred
+g = 1, *NOT_YET_IMPLEMENTED_ExprStarred
+what_is_up_with_those_new_coord_names = (
+ (coord_names + NOT_IMPLEMENTED_call(NOT_IMPLEMENTED_arg))
+ + NOT_IMPLEMENTED_call(NOT_IMPLEMENTED_arg)
@ -756,15 +756,15 @@ NOT_IMPLEMENTED_true if NOT_IMPLEMENTED_cond else NOT_IMPLEMENTED_false
[]
[1, 2, 3, 4, 5, 6, 7, 8, 9, (10 or A), (11 or B), (12 or C)]
[1, 2, 3]
[NOT_YET_IMPLEMENTED_ExprStarred]
[NOT_YET_IMPLEMENTED_ExprStarred]
[NOT_YET_IMPLEMENTED_ExprStarred, 4, 5]
[4, NOT_YET_IMPLEMENTED_ExprStarred, 5]
[*NOT_YET_IMPLEMENTED_ExprStarred]
[*NOT_YET_IMPLEMENTED_ExprStarred]
[*NOT_YET_IMPLEMENTED_ExprStarred, 4, 5]
[4, *NOT_YET_IMPLEMENTED_ExprStarred, 5]
[
this_is_a_very_long_variable_which_will_force_a_delimiter_split,
element,
another,
NOT_YET_IMPLEMENTED_ExprStarred,
*NOT_YET_IMPLEMENTED_ExprStarred,
]
{NOT_IMPLEMENTED_set_value for value in NOT_IMPLEMENTED_set}
{NOT_IMPLEMENTED_set_value for value in NOT_IMPLEMENTED_set}
@ -856,7 +856,7 @@ SomeName
(i for i in [])
(i for i in [])
(i for i in [])
(NOT_YET_IMPLEMENTED_ExprStarred,)
(*NOT_YET_IMPLEMENTED_ExprStarred,)
{
"id": "1",
"type": "type",
@ -871,8 +871,8 @@ b = (1,)
c = 1
d = (1,) + a + (2,)
e = NOT_IMPLEMENTED_call(NOT_IMPLEMENTED_arg)
f = 1, NOT_YET_IMPLEMENTED_ExprStarred
g = 1, NOT_YET_IMPLEMENTED_ExprStarred
f = 1, *NOT_YET_IMPLEMENTED_ExprStarred
g = 1, *NOT_YET_IMPLEMENTED_ExprStarred
what_is_up_with_those_new_coord_names = (
(coord_names + NOT_IMPLEMENTED_call(NOT_IMPLEMENTED_arg))
+ NOT_IMPLEMENTED_call(NOT_IMPLEMENTED_arg)

View file

@ -352,7 +352,7 @@ d={'a':1,
# fmt: off
- a , b = *hello
- 'unformatted'
+ a, b = NOT_YET_IMPLEMENTED_ExprStarred
+ a, b = *NOT_YET_IMPLEMENTED_ExprStarred
+ "unformatted"
# fmt: on
@ -607,7 +607,7 @@ def import_as_names():
def testlist_star_expr():
# fmt: off
a, b = NOT_YET_IMPLEMENTED_ExprStarred
a, b = *NOT_YET_IMPLEMENTED_ExprStarred
"unformatted"
# fmt: on

View file

@ -74,7 +74,7 @@ async def test_async_with():
```diff
--- Black
+++ Ruff
@@ -1,62 +1,54 @@
@@ -1,62 +1,55 @@
# Make sure a leading comment is not removed.
-def some_func( unformatted, args ): # fmt: skip
- print("I am some_func")
@ -155,7 +155,8 @@ async def test_async_with():
-with give_me_context( unformatted, args ): # fmt: skip
- print("Do something")
+NOT_YET_IMPLEMENTED_StmtWith # fmt: skip
+with NOT_IMPLEMENTED_call(NOT_IMPLEMENTED_arg): # fmt: skip
+ NOT_IMPLEMENTED_call(NOT_IMPLEMENTED_arg)
async def test_async_with():
@ -216,7 +217,8 @@ async def test_async_for():
NOT_YET_IMPLEMENTED_StmtTry
NOT_YET_IMPLEMENTED_StmtWith # fmt: skip
with NOT_IMPLEMENTED_call(NOT_IMPLEMENTED_arg): # fmt: skip
NOT_IMPLEMENTED_call(NOT_IMPLEMENTED_arg)
async def test_async_with():

View file

@ -65,12 +65,13 @@ with hmm_but_this_should_get_two_preceding_newlines():
```diff
--- Black
+++ Ruff
@@ -2,17 +2,9 @@
@@ -2,17 +2,11 @@
a,
**kwargs,
) -> A:
- with cache_dir():
- if something:
+ with NOT_IMPLEMENTED_call():
if something:
- result = CliRunner().invoke(
- black.main, [str(src1), str(src2), "--diff", "--check"]
- )
@ -80,13 +81,13 @@ with hmm_but_this_should_get_two_preceding_newlines():
- very_long_argument_name2=-very.long.value.for_the_argument,
- **kwargs,
- )
+ NOT_YET_IMPLEMENTED_StmtWith
+ result = NOT_IMPLEMENTED_call(NOT_IMPLEMENTED_arg)
+ NOT_IMPLEMENTED_call(NOT_IMPLEMENTED_arg) # negate top
+ return NOT_IMPLEMENTED_call(NOT_IMPLEMENTED_arg)
def g():
@@ -21,45 +13,30 @@
@@ -21,45 +15,31 @@
def inner():
pass
@ -136,8 +137,8 @@ with hmm_but_this_should_get_two_preceding_newlines():
-
-with hmm_but_this_should_get_two_preceding_newlines():
- pass
+NOT_YET_IMPLEMENTED_StmtWith
+with NOT_IMPLEMENTED_call():
pass
```
## Ruff Output
@ -147,7 +148,9 @@ def f(
a,
**kwargs,
) -> A:
NOT_YET_IMPLEMENTED_StmtWith
with NOT_IMPLEMENTED_call():
if something:
result = NOT_IMPLEMENTED_call(NOT_IMPLEMENTED_arg)
NOT_IMPLEMENTED_call(NOT_IMPLEMENTED_arg) # negate top
return NOT_IMPLEMENTED_call(NOT_IMPLEMENTED_arg)
@ -184,7 +187,8 @@ else:
def foo():
pass
NOT_YET_IMPLEMENTED_StmtWith
with NOT_IMPLEMENTED_call():
pass
```
## Black Output

View file

@ -120,7 +120,7 @@ with open("/path/to/file.txt", mode="r") as read_file:
```diff
--- Black
+++ Ruff
@@ -1,78 +1,74 @@
@@ -1,78 +1,78 @@
-import random
+NOT_YET_IMPLEMENTED_StmtImport
@ -214,18 +214,22 @@ with open("/path/to/file.txt", mode="r") as read_file:
-with open("/path/to/file.txt", mode="w") as file:
- file.write("The new line above me is about to be removed!")
+NOT_YET_IMPLEMENTED_StmtWith
+with NOT_IMPLEMENTED_call(NOT_IMPLEMENTED_arg) as file:
+ NOT_IMPLEMENTED_call(NOT_IMPLEMENTED_arg)
-with open("/path/to/file.txt", mode="w") as file:
- file.write("The new lines above me is about to be removed!")
+NOT_YET_IMPLEMENTED_StmtWith
+with NOT_IMPLEMENTED_call(NOT_IMPLEMENTED_arg) as file:
+ NOT_IMPLEMENTED_call(NOT_IMPLEMENTED_arg)
-with open("/path/to/file.txt", mode="r") as read_file:
- with open("/path/to/output_file.txt", mode="w") as write_file:
- write_file.writelines(read_file.readlines())
+NOT_YET_IMPLEMENTED_StmtWith
+with NOT_IMPLEMENTED_call(NOT_IMPLEMENTED_arg) as read_file:
+ with NOT_IMPLEMENTED_call(NOT_IMPLEMENTED_arg) as write_file:
+ NOT_IMPLEMENTED_call(NOT_IMPLEMENTED_arg)
```
## Ruff Output
@ -298,13 +302,17 @@ while True:
NOT_IMPLEMENTED_call(NOT_IMPLEMENTED_arg)
NOT_YET_IMPLEMENTED_StmtWith
with NOT_IMPLEMENTED_call(NOT_IMPLEMENTED_arg) as file:
NOT_IMPLEMENTED_call(NOT_IMPLEMENTED_arg)
NOT_YET_IMPLEMENTED_StmtWith
with NOT_IMPLEMENTED_call(NOT_IMPLEMENTED_arg) as file:
NOT_IMPLEMENTED_call(NOT_IMPLEMENTED_arg)
NOT_YET_IMPLEMENTED_StmtWith
with NOT_IMPLEMENTED_call(NOT_IMPLEMENTED_arg) as read_file:
with NOT_IMPLEMENTED_call(NOT_IMPLEMENTED_arg) as write_file:
NOT_IMPLEMENTED_call(NOT_IMPLEMENTED_arg)
```
## Black Output

View file

@ -0,0 +1,132 @@
---
source: crates/ruff_python_formatter/tests/fixtures.rs
input_file: crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/with.py
---
## Input
```py
with aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:
...
# trailing
with a, a: # after colon
...
# trailing
with (
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,
):
...
# trailing
with (
a # a
, # comma
b # c
): # colon
...
with (
a # a
as # as
b # b
, # comma
c # c
): # colon
... # body
# body trailing own
with (a,): # magic trailing comma
...
with (a): # should remove brackets
...
# TODO: black doesn't wrap this, but maybe we want to anyway?
# if we do want to wrap, do we prefer to wrap the entire WithItem or to let the
# WithItem allow the `aa + bb` content expression to be wrapped
with aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb as c:
...
# currently unparsable by black: https://github.com/psf/black/issues/3678
with (name_2 for name_0 in name_4):
pass
with (a, *b):
pass
```
## Output
```py
with (
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,
):
...
# trailing
with a, a: # after colon
...
# trailing
with (
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,
):
...
# trailing
with (
(
a # a # comma
),
b, # c
): # colon
...
with (
(
a # a # as
) as b, # b # comma
c, # c
): # colon
... # body
# body trailing own
with (
a,
): # magic trailing comma
...
with a: # should remove brackets
...
# TODO: black doesn't wrap this, but maybe we want to anyway?
# if we do want to wrap, do we prefer to wrap the entire WithItem or to let the
# WithItem allow the `aa + bb` content expression to be wrapped
with (
(
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
) as c,
):
...
# currently unparsable by black: https://github.com/psf/black/issues/3678
with (i for i in []):
pass
with (a, *NOT_YET_IMPLEMENTED_ExprStarred):
pass
```