mirror of
https://github.com/astral-sh/ruff.git
synced 2025-07-24 13:34:40 +00:00
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:
parent
e71f044f0d
commit
1eccbbb60e
14 changed files with 392 additions and 134 deletions
34
crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/for.py
vendored
Normal file
34
crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/for.py
vendored
Normal 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
|
||||
...
|
|
@ -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
|
||||
```
|
||||
|
|
|
@ -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]
|
||||
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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():
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
...
|
||||
```
|
||||
|
||||
|
|
@ -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(())
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue