Format StmtFor (#5163)

<!--
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

format StmtFor

still trying to learn how to help out with the formatter. trying
something slightly more advanced than [break](#5158)

mostly copied form StmtWhile

## Test Plan

snapshots
This commit is contained in:
David Szotten 2023-06-21 22:00:31 +01:00 committed by GitHub
parent e71f044f0d
commit 1eccbbb60e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 392 additions and 134 deletions

View file

@ -0,0 +1,34 @@
for x in y: # trailing test comment
pass # trailing last statement comment
# trailing for body comment
# leading else comment
else: # trailing else comment
pass
# trailing else body comment
for aVeryLongNameThatSpillsOverToTheNextLineBecauseItIsExtremelyLongAndGoesOnAndOnAndOnAndOnAndOnAndOnAndOnAndOnAndOn in anotherVeryLongNameThatSpillsOverToTheNextLineBecauseItIsExtremelyLongAndGoesOnAndOnAndOnAndOnAndOnAndOnAndOnAndOnAndOn: # trailing comment
pass
else:
...
for (
x,
y,
) in z: # comment
...
# remove brackets around x,y but keep them around z,w
for (x, y) in (z, w):
...
# type comment
for x in (): # type: int
...

View file

@ -19,12 +19,14 @@ lambda x=lambda y={1: 3}: y['x':lambda y: {1: 2}]: x
```diff
--- Black
+++ Ruff
@@ -1,4 +1,3 @@
@@ -1,4 +1,6 @@
-for ((x in {}) or {})["a"] in x:
- pass
+for ((NOT_IMPLEMENTED_left < NOT_IMPLEMENTED_right) or {})[
+ "NOT_YET_IMPLEMENTED_STRING"
+] in x:
pass
-pem_spam = lambda l, spam={"x": 3}: not spam.get(l.strip())
-lambda x=lambda y={1: 3}: y["x" : lambda y: {1: 2}]: x
+NOT_YET_IMPLEMENTED_StmtFor
+pem_spam = lambda x: True
+lambda x: True
```
@ -32,7 +34,10 @@ lambda x=lambda y={1: 3}: y['x':lambda y: {1: 2}]: x
## Ruff Output
```py
NOT_YET_IMPLEMENTED_StmtFor
for ((NOT_IMPLEMENTED_left < NOT_IMPLEMENTED_right) or {})[
"NOT_YET_IMPLEMENTED_STRING"
] in x:
pass
pem_spam = lambda x: True
lambda x: True
```

View file

@ -84,7 +84,7 @@ if True:
```diff
--- Black
+++ Ruff
@@ -1,99 +1,56 @@
@@ -1,61 +1,40 @@
-import core, time, a
+NOT_YET_IMPLEMENTED_StmtImport
@ -164,12 +164,10 @@ if True:
+NOT_YET_IMPLEMENTED_StmtAssert
# looping over a 1-tuple should also not get wrapped
-for x in (1,):
- pass
-for (x,) in (1,), (2,), (3,):
- pass
+NOT_YET_IMPLEMENTED_StmtFor
+NOT_YET_IMPLEMENTED_StmtFor
for x in (1,):
@@ -63,37 +42,17 @@
for (x,) in (1,), (2,), (3,):
pass
-[
- 1,
@ -257,8 +255,10 @@ y = {
NOT_YET_IMPLEMENTED_StmtAssert
# looping over a 1-tuple should also not get wrapped
NOT_YET_IMPLEMENTED_StmtFor
NOT_YET_IMPLEMENTED_StmtFor
for x in (1,):
pass
for (x,) in (1,), (2,), (3,):
pass
[1, 2, 3]

View file

@ -61,7 +61,7 @@ def func():
```diff
--- Black
+++ Ruff
@@ -3,46 +3,15 @@
@@ -3,46 +3,17 @@
# %%
def func():
@ -97,7 +97,9 @@ def func():
- )
- # This should be left alone (after)
- )
+ NOT_YET_IMPLEMENTED_StmtFor
+ for exc in exc_value.NOT_IMPLEMENTED_attr:
+ if NOT_IMPLEMENTED_left < NOT_IMPLEMENTED_right:
+ NOT_IMPLEMENTED_call()
# everything is fine if the expression isn't nested
- traceback.TracebackException.from_exception(
@ -128,7 +130,9 @@ def func():
# Capture each of the exceptions in the MultiError along with each of their causes and contexts
if NOT_IMPLEMENTED_call():
embedded = []
NOT_YET_IMPLEMENTED_StmtFor
for exc in exc_value.NOT_IMPLEMENTED_attr:
if NOT_IMPLEMENTED_left < NOT_IMPLEMENTED_right:
NOT_IMPLEMENTED_call()
# everything is fine if the expression isn't nested
NOT_IMPLEMENTED_call()

View file

@ -86,7 +86,7 @@ if __name__ == "__main__":
```diff
--- Black
+++ Ruff
@@ -1,33 +1,20 @@
@@ -1,6 +1,6 @@
while True:
- if something.changed:
- do.stuff() # trailing comment
@ -95,38 +95,40 @@ if __name__ == "__main__":
# Comment belongs to the `if` block.
# This one belongs to the `while` block.
# Should this one, too? I guess so.
@@ -8,26 +8,20 @@
# This one is properly standalone now.
-
-for i in range(100):
- # first we do this
- if i % 33 == 0:
- break
- # then we do this
-for i in range(100):
+for i in NOT_IMPLEMENTED_call():
# first we do this
- if i % 33 == 0:
+ if NOT_IMPLEMENTED_left < NOT_IMPLEMENTED_right:
break
# then we do this
- print(i)
- # and finally we loop around
+NOT_YET_IMPLEMENTED_StmtFor
+ NOT_IMPLEMENTED_call()
# and finally we loop around
-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_StmtWith
+NOT_YET_IMPLEMENTED_StmtTry
-except OSError:
- print("problems")
+NOT_YET_IMPLEMENTED_StmtTry
-
-import sys
+NOT_YET_IMPLEMENTED_StmtImport
# leading function comment
@@ -42,7 +29,7 @@
@@ -42,7 +36,7 @@
# leading 1
@deco1
# leading 2
@ -135,7 +137,7 @@ if __name__ == "__main__":
# leading 3
@deco3
def decorated1():
@@ -52,7 +39,7 @@
@@ -52,7 +46,7 @@
# leading 1
@deco1
# leading 2
@ -144,7 +146,7 @@ if __name__ == "__main__":
# leading function comment
def decorated1():
...
@@ -69,5 +56,5 @@
@@ -69,5 +63,5 @@
...
@ -167,7 +169,14 @@ while True:
# This one is properly standalone now.
NOT_YET_IMPLEMENTED_StmtFor
for i in NOT_IMPLEMENTED_call():
# first we do this
if NOT_IMPLEMENTED_left < NOT_IMPLEMENTED_right:
break
# then we do this
NOT_IMPLEMENTED_call()
# and finally we loop around
NOT_YET_IMPLEMENTED_StmtWith

View file

@ -352,12 +352,7 @@ last_call()
(1, 2, 3)
[]
[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]
[
-[
- 1,
- 2,
- 3,
@ -374,7 +369,12 @@ last_call()
- *a,
- 5,
-]
-[
+[1, 2, 3]
+[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,
@ -459,6 +459,9 @@ last_call()
- int,
- float,
- dict[str, int],
-]
-very_long_variable_name_filters: t.List[
- t.Tuple[str, t.Union[str, t.List[t.Optional[str]]]],
+ (
+ str,
+ int,
@ -466,9 +469,6 @@ last_call()
+ dict[str, int],
+ )
]
-very_long_variable_name_filters: t.List[
- t.Tuple[str, t.Union[str, t.List[t.Optional[str]]]],
-]
-xxxx_xxxxx_xxxx_xxx: Callable[..., List[SomeClass]] = classmethod( # type: ignore
- sync(async_xxxx_xxx_xxxx_xxxxx_xxxx_xxx.__func__)
-)
@ -570,7 +570,10 @@ last_call()
)
-what_is_up_with_those_new_coord_names = (coord_names | set(vars_to_create)) - set(
- vars_to_remove
-)
+what_is_up_with_those_new_coord_names = (
+ (coord_names | NOT_IMPLEMENTED_call())
+ - NOT_IMPLEMENTED_call()
)
-result = (
- session.query(models.Customer.id)
- .filter(
@ -588,10 +591,7 @@ last_call()
- models.Customer.id.asc(),
- )
- .all()
+what_is_up_with_those_new_coord_names = (
+ (coord_names | NOT_IMPLEMENTED_call())
+ - NOT_IMPLEMENTED_call()
)
-)
-Ø = set()
-authors.łukasz.say_thanks()
+result = NOT_IMPLEMENTED_call()
@ -601,7 +601,7 @@ last_call()
mapping = {
A: 0.25 * (10.0 / 12),
B: 0.1 * (10.0 / 12),
@@ -236,64 +219,38 @@
@@ -236,31 +219,29 @@
def gen():
@ -628,37 +628,31 @@ last_call()
- force=False
-), "Short message"
-assert parens is TooMany
-for (x,) in (1,), (2,), (3,):
- ...
-for y in ():
- ...
-for z in (i for i in (1, 2, 3)):
- ...
-for i in call():
- ...
-for j in 1 + (2 + 3):
- ...
+NOT_IMPLEMENTED_call()
+NOT_IMPLEMENTED_call()
+NOT_IMPLEMENTED_call()
+NOT_YET_IMPLEMENTED_StmtAssert
+NOT_YET_IMPLEMENTED_StmtAssert
+NOT_YET_IMPLEMENTED_StmtAssert
+NOT_YET_IMPLEMENTED_StmtFor
+NOT_YET_IMPLEMENTED_StmtFor
+NOT_YET_IMPLEMENTED_StmtFor
+NOT_YET_IMPLEMENTED_StmtFor
+NOT_YET_IMPLEMENTED_StmtFor
while this and that:
for (x,) in (1,), (2,), (3,):
...
-for (
- addr_family,
- addr_type,
- addr_proto,
- addr_canonname,
- addr_sockaddr,
for y in ():
...
-for z in (i for i in (1, 2, 3)):
+for z in (i for i in []):
...
-for i in call():
+for i in NOT_IMPLEMENTED_call():
...
for j in 1 + (2 + 3):
...
@@ -272,28 +253,16 @@
addr_proto,
addr_canonname,
addr_sockaddr,
-) in socket.getaddrinfo("google.com", "http"):
- pass
+) in NOT_IMPLEMENTED_call():
pass
-a = (
- aaaa.bbbb.cccc.dddd.eeee.ffff.gggg.hhhh.iiii.jjjj.kkkk.llll.mmmm.nnnn.oooo.pppp
- in qqqq.rrrr.ssss.tttt.uuuu.vvvv.xxxx.yyyy.zzzz
@ -675,7 +669,6 @@ last_call()
- aaaa.bbbb.cccc.dddd.eeee.ffff.gggg.hhhh.iiii.jjjj.kkkk.llll.mmmm.nnnn.oooo.pppp
- is not qqqq.rrrr.ssss.tttt.uuuu.vvvv.xxxx.yyyy.zzzz
-)
+NOT_YET_IMPLEMENTED_StmtFor
+a = NOT_IMPLEMENTED_left < NOT_IMPLEMENTED_right
+a = NOT_IMPLEMENTED_left < NOT_IMPLEMENTED_right
+a = NOT_IMPLEMENTED_left < NOT_IMPLEMENTED_right
@ -690,7 +683,7 @@ last_call()
):
return True
if (
@@ -327,24 +284,44 @@
@@ -327,24 +296,44 @@
):
return True
if (
@ -747,7 +740,7 @@ last_call()
):
return True
(
@@ -363,8 +340,9 @@
@@ -363,8 +352,9 @@
bbbb >> bbbb * bbbb
(
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
@ -1001,14 +994,26 @@ NOT_IMPLEMENTED_call()
NOT_YET_IMPLEMENTED_StmtAssert
NOT_YET_IMPLEMENTED_StmtAssert
NOT_YET_IMPLEMENTED_StmtAssert
NOT_YET_IMPLEMENTED_StmtFor
NOT_YET_IMPLEMENTED_StmtFor
NOT_YET_IMPLEMENTED_StmtFor
NOT_YET_IMPLEMENTED_StmtFor
NOT_YET_IMPLEMENTED_StmtFor
for (x,) in (1,), (2,), (3,):
...
for y in ():
...
for z in (i for i in []):
...
for i in NOT_IMPLEMENTED_call():
...
for j in 1 + (2 + 3):
...
while this and that:
...
NOT_YET_IMPLEMENTED_StmtFor
for (
addr_family,
addr_type,
addr_proto,
addr_canonname,
addr_sockaddr,
) in NOT_IMPLEMENTED_call():
pass
a = NOT_IMPLEMENTED_left < NOT_IMPLEMENTED_right
a = NOT_IMPLEMENTED_left < NOT_IMPLEMENTED_right
a = NOT_IMPLEMENTED_left < NOT_IMPLEMENTED_right

View file

@ -134,7 +134,7 @@ elif unformatted:
return True
# yapf: enable
elif b:
@@ -39,49 +21,27 @@
@@ -39,49 +21,29 @@
# Regression test for https://github.com/psf/black/issues/2567.
if True:
# fmt: off
@ -142,7 +142,9 @@ elif unformatted:
- # fmt: on
- print ( "This won't be formatted" )
- print ( "This won't be formatted either" )
+ NOT_YET_IMPLEMENTED_StmtFor
+ for _ in NOT_IMPLEMENTED_call():
+ # fmt: on
+ NOT_IMPLEMENTED_call()
+ NOT_IMPLEMENTED_call()
else:
- print("This will be formatted")
@ -220,7 +222,9 @@ def test_func():
# Regression test for https://github.com/psf/black/issues/2567.
if True:
# fmt: off
NOT_YET_IMPLEMENTED_StmtFor
for _ in NOT_IMPLEMENTED_call():
# fmt: on
NOT_IMPLEMENTED_call()
NOT_IMPLEMENTED_call()
else:
NOT_IMPLEMENTED_call()

View file

@ -222,7 +222,7 @@ d={'a':1,
# Comment 1
# Comment 2
@@ -18,30 +16,51 @@
@@ -18,30 +16,53 @@
# fmt: off
def func_no_args():
@ -241,7 +241,9 @@ d={'a':1,
+ NOT_YET_IMPLEMENTED_StmtRaise
+ if False:
+ ...
+ NOT_YET_IMPLEMENTED_StmtFor
+ for i in NOT_IMPLEMENTED_call():
+ NOT_IMPLEMENTED_call()
+ continue
+ NOT_IMPLEMENTED_call()
+ return None
+
@ -296,7 +298,7 @@ d={'a':1,
def spaces_types(
@@ -51,76 +70,71 @@
@@ -51,76 +72,71 @@
d: dict = {},
e: bool = True,
f: int = -1,
@ -397,7 +399,7 @@ d={'a':1,
# fmt: off
# hey, that won't work
@@ -130,13 +144,15 @@
@@ -130,13 +146,15 @@
def on_and_off_broken():
@ -418,7 +420,7 @@ d={'a':1,
# fmt: on
# fmt: off
# ...but comments still get reformatted even though they should not be
@@ -145,80 +161,21 @@
@@ -145,80 +163,21 @@
def long_lines():
if True:
@ -430,11 +432,13 @@ d={'a':1,
- implicit_default=True,
- )
- )
- # fmt: off
+ NOT_IMPLEMENTED_call()
# fmt: off
- a = (
- unnecessary_bracket()
- )
- # fmt: on
+ a = NOT_IMPLEMENTED_call()
# fmt: on
- _type_comment_re = re.compile(
- r"""
- ^
@ -455,11 +459,9 @@ d={'a':1,
- )
- $
- """,
+ NOT_IMPLEMENTED_call()
# fmt: off
- # fmt: off
- re.MULTILINE|re.VERBOSE
+ a = NOT_IMPLEMENTED_call()
# fmt: on
- # fmt: on
- )
+ _type_comment_re = NOT_IMPLEMENTED_call()
@ -537,7 +539,9 @@ def func_no_args():
NOT_YET_IMPLEMENTED_StmtRaise
if False:
...
NOT_YET_IMPLEMENTED_StmtFor
for i in NOT_IMPLEMENTED_call():
NOT_IMPLEMENTED_call()
continue
NOT_IMPLEMENTED_call()
return None

View file

@ -75,7 +75,7 @@ async def test_async_with():
```diff
--- Black
+++ Ruff
@@ -1,62 +1,46 @@
@@ -1,62 +1,47 @@
# Make sure a leading comment is not removed.
-def some_func( unformatted, args ): # fmt: skip
- print("I am some_func")
@ -99,13 +99,13 @@ async def test_async_with():
- def some_method( self, unformatted, args ): # fmt: skip
- print("I am some_method")
- return 0
-
+NOT_YET_IMPLEMENTED_StmtClassDef
- async def some_async_method( self, unformatted, args ): # fmt: skip
- print("I am some_async_method")
- await asyncio.sleep(1)
+NOT_YET_IMPLEMENTED_StmtClassDef
-
# Make sure a leading comment is not removed.
-if unformatted_call( args ): # fmt: skip
- print("First branch")
@ -130,7 +130,8 @@ async def test_async_with():
-for i in some_iter( unformatted, args ): # fmt: skip
- print("Do something")
+NOT_YET_IMPLEMENTED_StmtFor # fmt: skip
+for i in NOT_IMPLEMENTED_call(): # fmt: skip
+ NOT_IMPLEMENTED_call()
async def test_async_for():
@ -193,7 +194,8 @@ while NOT_IMPLEMENTED_call(): # fmt: skip
NOT_IMPLEMENTED_call()
NOT_YET_IMPLEMENTED_StmtFor # fmt: skip
for i in NOT_IMPLEMENTED_call(): # fmt: skip
NOT_IMPLEMENTED_call()
async def test_async_for():

View file

@ -126,7 +126,7 @@ def __await__(): return (yield)
def func_no_args():
@@ -14,39 +13,46 @@
@@ -14,39 +13,48 @@
b
c
if True:
@ -136,9 +136,10 @@ def __await__(): return (yield)
...
- for i in range(10):
- print(i)
- continue
+ for i in NOT_IMPLEMENTED_call():
+ NOT_IMPLEMENTED_call()
continue
- exec("new-style exec", {}, {})
+ NOT_YET_IMPLEMENTED_StmtFor
+ NOT_IMPLEMENTED_call()
return None
@ -189,7 +190,7 @@ def __await__(): return (yield)
def spaces_types(
@@ -56,70 +62,26 @@
@@ -56,70 +64,26 @@
d: dict = {},
e: bool = True,
f: int = -1,
@ -269,7 +270,7 @@ def __await__(): return (yield)
def trailing_comma():
@@ -135,14 +97,8 @@
@@ -135,14 +99,8 @@
a,
**kwargs,
) -> A:
@ -309,7 +310,9 @@ def func_no_args():
NOT_YET_IMPLEMENTED_StmtRaise
if False:
...
NOT_YET_IMPLEMENTED_StmtFor
for i in NOT_IMPLEMENTED_call():
NOT_IMPLEMENTED_call()
continue
NOT_IMPLEMENTED_call()
return None

View file

@ -32,25 +32,28 @@ for (((((k, v))))) in d.items():
```diff
--- Black
+++ Ruff
@@ -1,27 +1,13 @@
@@ -1,27 +1,22 @@
# Only remove tuple brackets after `for`
-for k, v in d.items():
- print(k, v)
+NOT_YET_IMPLEMENTED_StmtFor
+for k, v in NOT_IMPLEMENTED_call():
+ NOT_IMPLEMENTED_call()
# Don't touch tuple brackets after `in`
-for module in (core, _unicodefun):
for module in (core, _unicodefun):
- if hasattr(module, "_verify_python3_env"):
- module._verify_python3_env = lambda: None
+NOT_YET_IMPLEMENTED_StmtFor
+ if NOT_IMPLEMENTED_call():
+ module.NOT_IMPLEMENTED_attr = lambda x: True
# Brackets remain for long for loop lines
-for (
- why_would_anyone_choose_to_name_a_loop_variable_with_a_name_this_long,
- i_dont_know_but_we_should_still_check_the_behaviour_if_they_do,
for (
why_would_anyone_choose_to_name_a_loop_variable_with_a_name_this_long,
i_dont_know_but_we_should_still_check_the_behaviour_if_they_do,
-) in d.items():
- print(k, v)
+NOT_YET_IMPLEMENTED_StmtFor
+) in NOT_IMPLEMENTED_call():
+ NOT_IMPLEMENTED_call()
-for (
- k,
@ -59,30 +62,41 @@ for (((((k, v))))) in d.items():
- dfkasdjfldsjflkdsjflkdsjfdslkfjldsjfgkjdshgkljjdsfldgkhsdofudsfudsofajdslkfjdslkfjldisfjdffjsdlkfjdlkjjkdflskadjldkfjsalkfjdasj.items()
-):
- print(k, v)
+NOT_YET_IMPLEMENTED_StmtFor
+for k, v in NOT_IMPLEMENTED_call():
+ NOT_IMPLEMENTED_call()
# Test deeply nested brackets
-for k, v in d.items():
- print(k, v)
+NOT_YET_IMPLEMENTED_StmtFor
+for k, v in NOT_IMPLEMENTED_call():
+ NOT_IMPLEMENTED_call()
```
## Ruff Output
```py
# Only remove tuple brackets after `for`
NOT_YET_IMPLEMENTED_StmtFor
for k, v in NOT_IMPLEMENTED_call():
NOT_IMPLEMENTED_call()
# Don't touch tuple brackets after `in`
NOT_YET_IMPLEMENTED_StmtFor
for module in (core, _unicodefun):
if NOT_IMPLEMENTED_call():
module.NOT_IMPLEMENTED_attr = lambda x: True
# Brackets remain for long for loop lines
NOT_YET_IMPLEMENTED_StmtFor
for (
why_would_anyone_choose_to_name_a_loop_variable_with_a_name_this_long,
i_dont_know_but_we_should_still_check_the_behaviour_if_they_do,
) in NOT_IMPLEMENTED_call():
NOT_IMPLEMENTED_call()
NOT_YET_IMPLEMENTED_StmtFor
for k, v in NOT_IMPLEMENTED_call():
NOT_IMPLEMENTED_call()
# Test deeply nested brackets
NOT_YET_IMPLEMENTED_StmtFor
for k, v in NOT_IMPLEMENTED_call():
NOT_IMPLEMENTED_call()
```
## Black Output

View file

@ -121,7 +121,7 @@ with open("/path/to/file.txt", mode="r") as read_file:
```diff
--- Black
+++ Ruff
@@ -1,78 +1,68 @@
@@ -1,78 +1,72 @@
-import random
+NOT_YET_IMPLEMENTED_StmtImport
@ -159,18 +159,22 @@ with open("/path/to/file.txt", mode="r") as read_file:
-for i in range(5):
- print(f"{i}) The line above me should be removed!")
+NOT_YET_IMPLEMENTED_StmtFor
+for i in NOT_IMPLEMENTED_call():
+ NOT_IMPLEMENTED_call()
-for i in range(5):
- print(f"{i}) The lines above me should be removed!")
+NOT_YET_IMPLEMENTED_StmtFor
+for i in NOT_IMPLEMENTED_call():
+ NOT_IMPLEMENTED_call()
-for i in range(5):
- for j in range(7):
- print(f"{i}) The lines above me should be removed!")
+NOT_YET_IMPLEMENTED_StmtFor
+for i in NOT_IMPLEMENTED_call():
+ for j in NOT_IMPLEMENTED_call():
+ NOT_IMPLEMENTED_call()
-if random.randint(0, 3) == 0:
@ -254,13 +258,17 @@ def foo4():
NOT_YET_IMPLEMENTED_StmtClassDef
NOT_YET_IMPLEMENTED_StmtFor
for i in NOT_IMPLEMENTED_call():
NOT_IMPLEMENTED_call()
NOT_YET_IMPLEMENTED_StmtFor
for i in NOT_IMPLEMENTED_call():
NOT_IMPLEMENTED_call()
NOT_YET_IMPLEMENTED_StmtFor
for i in NOT_IMPLEMENTED_call():
for j in NOT_IMPLEMENTED_call():
NOT_IMPLEMENTED_call()
if NOT_IMPLEMENTED_left < NOT_IMPLEMENTED_right:

View file

@ -0,0 +1,87 @@
---
source: crates/ruff_python_formatter/src/lib.rs
expression: snapshot
---
## Input
```py
for x in y: # trailing test comment
pass # trailing last statement comment
# trailing for body comment
# leading else comment
else: # trailing else comment
pass
# trailing else body comment
for aVeryLongNameThatSpillsOverToTheNextLineBecauseItIsExtremelyLongAndGoesOnAndOnAndOnAndOnAndOnAndOnAndOnAndOnAndOn in anotherVeryLongNameThatSpillsOverToTheNextLineBecauseItIsExtremelyLongAndGoesOnAndOnAndOnAndOnAndOnAndOnAndOnAndOnAndOn: # trailing comment
pass
else:
...
for (
x,
y,
) in z: # comment
...
# remove brackets around x,y but keep them around z,w
for (x, y) in (z, w):
...
# type comment
for x in (): # type: int
...
```
## Output
```py
for x in y: # trailing test comment
pass # trailing last statement comment
# trailing for body comment
# leading else comment
else: # trailing else comment
pass
# trailing else body comment
for (
aVeryLongNameThatSpillsOverToTheNextLineBecauseItIsExtremelyLongAndGoesOnAndOnAndOnAndOnAndOnAndOnAndOnAndOnAndOn
) in (
anotherVeryLongNameThatSpillsOverToTheNextLineBecauseItIsExtremelyLongAndGoesOnAndOnAndOnAndOnAndOnAndOnAndOnAndOnAndOn
): # trailing comment
pass
else:
...
for (
x,
y,
) in z: # comment
...
# remove brackets around x,y but keep them around z,w
for x, y in (z, w):
...
# type comment
for x in (): # type: int
...
```

View file

@ -1,12 +1,91 @@
use crate::{not_yet_implemented, FormatNodeRule, PyFormatter};
use crate::comments::{leading_alternate_branch_comments, trailing_comments};
use crate::expression::expr_tuple::TupleParentheses;
use crate::expression::parentheses::Parenthesize;
use crate::prelude::*;
use crate::{FormatNodeRule, PyFormatter};
use ruff_formatter::{write, Buffer, FormatResult};
use rustpython_parser::ast::StmtFor;
use ruff_python_ast::node::AstNode;
use rustpython_parser::ast::{Expr, Ranged, Stmt, StmtFor};
#[derive(Debug)]
struct ExprTupleWithoutParentheses<'a>(&'a Expr);
impl Format<PyFormatContext<'_>> for ExprTupleWithoutParentheses<'_> {
fn fmt(&self, f: &mut Formatter<PyFormatContext<'_>>) -> FormatResult<()> {
match self.0 {
Expr::Tuple(expr_tuple) => expr_tuple
.format()
.with_options(TupleParentheses::StripInsideForLoop)
.fmt(f),
other => other.format().with_options(Parenthesize::IfBreaks).fmt(f),
}
}
}
#[derive(Default)]
pub struct FormatStmtFor;
impl FormatNodeRule<StmtFor> for FormatStmtFor {
fn fmt_fields(&self, item: &StmtFor, f: &mut PyFormatter) -> FormatResult<()> {
write!(f, [not_yet_implemented(item)])
let StmtFor {
range: _,
target,
iter,
body,
orelse,
type_comment: _,
} = item;
let comments = f.context().comments().clone();
let dangling_comments = comments.dangling_comments(item.as_any_node_ref());
let body_start = body.first().map_or(iter.end(), Stmt::start);
let or_else_comments_start =
dangling_comments.partition_point(|comment| comment.slice().end() < body_start);
let (trailing_condition_comments, or_else_comments) =
dangling_comments.split_at(or_else_comments_start);
write!(
f,
[
text("for"),
space(),
ExprTupleWithoutParentheses(target.as_ref()),
space(),
text("in"),
space(),
iter.format().with_options(Parenthesize::IfBreaks),
text(":"),
trailing_comments(trailing_condition_comments),
block_indent(&body.format())
]
)?;
if orelse.is_empty() {
debug_assert!(or_else_comments.is_empty());
} else {
// Split between leading comments before the `else` keyword and end of line comments at the end of
// the `else:` line.
let trailing_start =
or_else_comments.partition_point(|comment| comment.line_position().is_own_line());
let (leading, trailing) = or_else_comments.split_at(trailing_start);
write!(
f,
[
leading_alternate_branch_comments(leading, body.last()),
text("else:"),
trailing_comments(trailing),
block_indent(&orelse.format())
]
)?;
}
Ok(())
}
fn fmt_dangling_comments(&self, _node: &StmtFor, _f: &mut PyFormatter) -> FormatResult<()> {
// Handled in `fmt_fields`
Ok(())
}
}