Rewrite placement logic (#6040)

## Summary
This is a rewrite of the main comment placement logic. `place_comment`
now has three parts:

- place own line comments
  - between branches
  - after a branch
- place end-of-line comments
  - after colon
  - after a branch
- place comments for specific nodes (that include module level comments)

The rewrite fixed three bugs: `class A: # trailing comment` comments now
stay end-of-line, `try: # comment` remains end-of-line and deeply
indented try-else-finally comments remain with the right nested
statement.

It will be much easier to give more alternative branches nodes since
this is abstracted away by `is_node_with_body` and the first/last child
helpers. Adding new node types can now be done by adding an entry to the
`place_comment` match. The code went from 1526 lines before #6033 to
1213 lines now.

It thinks it easier to just read the new `placement.rs` rather than
reviewing the diff.

## Test Plan

The existing fixtures staying the same or improving plus new ones for
the bug fixes.
This commit is contained in:
konsti 2023-07-26 18:21:23 +02:00 committed by GitHub
parent 2cf00fee96
commit 13f9a16e33
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 541 additions and 673 deletions

View file

@ -74,7 +74,7 @@ async def test_async_with():
```diff
--- Black
+++ Ruff
@@ -1,62 +1,63 @@
@@ -1,62 +1,62 @@
# Make sure a leading comment is not removed.
-def some_func( unformatted, args ): # fmt: skip
+def some_func(unformatted, args): # fmt: skip
@ -134,15 +134,13 @@ async def test_async_with():
-try : # fmt: skip
+try:
+ # fmt: skip
+try: # fmt: skip
some_call()
-except UnformattedError as ex: # fmt: skip
- handle_exception()
-finally : # fmt: skip
+except UnformattedError as ex: # fmt: skip
+ handle_exception() # fmt: skip
+finally:
handle_exception()
-finally : # fmt: skip
+finally: # fmt: skip
finally_call()
@ -207,12 +205,11 @@ async def test_async_for():
print("Do something")
try:
# fmt: skip
try: # fmt: skip
some_call()
except UnformattedError as ex: # fmt: skip
handle_exception() # fmt: skip
finally:
handle_exception()
finally: # fmt: skip
finally_call()

View file

@ -32,14 +32,12 @@ def h():
```diff
--- Black
+++ Ruff
@@ -1,18 +1,26 @@
@@ -1,18 +1,25 @@
def f(): # type: ignore
...
-class x: # some comment
+
+class x:
+ # some comment
class x: # some comment
...
-class y: ... # comment
@ -71,8 +69,7 @@ def f(): # type: ignore
...
class x:
# some comment
class x: # some comment
...

View file

@ -41,8 +41,14 @@ class Test(aaaaaaaaaaaaaaa + bbbbbbbbbbbbbbbbbbbbbb + cccccccccccccccccccccccc +
class Test(aaaaaaaaaaaaaaa + bbbbbbbbbbbbbbbbbbbbbb * cccccccccccccccccccccccc + dddddddddddddddddddddd + eeeeeeeee, ffffffffffffffffff, gggggggggggggggggg):
pass
class Test(Aaaa): # trailing comment
class TestTrailingComment1(Aaaa): # trailing comment
pass
class TestTrailingComment2: # trailing comment
pass
```
## Output
@ -102,7 +108,11 @@ class Test(
pass
class Test(Aaaa): # trailing comment
class TestTrailingComment1(Aaaa): # trailing comment
pass
class TestTrailingComment2: # trailing comment
pass
```

View file

@ -94,13 +94,17 @@ def f():
# comment
if True:
def f2():
def f():
pass
# 1
else:
def f2():
elif True:
def f():
pass
# 2
else:
def f():
pass
# 3
if True: print("a") # 1
elif True: print("b") # 2
@ -199,13 +203,17 @@ def f():
if True:
def f2():
def f():
pass
# 1
else:
def f2():
elif True:
def f():
pass
# 2
else:
def f():
pass
# 3
if True:
print("a") # 1

View file

@ -112,19 +112,38 @@ except RuntimeError:
raise
try:
def f2():
def f():
pass
# a
except:
def f2():
def f():
pass
# b
else:
def f():
pass
# c
finally:
def f():
pass
# d
try: pass # a
except ZeroDivisionError: pass # b
except: pass # b
except: pass # c
else: pass # d
finally: pass # c
finally: pass # e
try: # 1 preceding: any, following: first in body, enclosing: try
print(1) # 2 preceding: last in body, following: fist in alt body, enclosing: try
except ZeroDivisionError: # 3 preceding: test, following: fist in alt body, enclosing: try
print(2) # 4 preceding: last in body, following: fist in alt body, enclosing: exc
except: # 5 preceding: last in body, following: fist in alt body, enclosing: try
print(2) # 6 preceding: last in body, following: fist in alt body, enclosing: exc
else: # 7 preceding: last in body, following: fist in alt body, enclosing: exc
print(3) # 8 preceding: last in body, following: fist in alt body, enclosing: try
finally: # 9 preceding: last in body, following: fist in alt body, enclosing: try
print(3) # 10 preceding: last in body, following: any, enclosing: try
```
## Output
@ -140,8 +159,7 @@ except KeyError: # should remove brackets and be a single line
...
try:
# try
try: # try
...
# end of body
# before except
@ -160,8 +178,7 @@ finally:
# with line breaks
try:
# try
try: # try
...
# end of body
@ -213,8 +230,7 @@ except:
# try/except*, mostly the same as try
try:
# try
try: # try
...
# end of body
# before except
@ -247,24 +263,43 @@ except RuntimeError:
raise
try:
def f2():
def f():
pass
# a
except:
def f2():
def f():
pass
# b
else:
def f():
pass
# c
finally:
def f():
pass
# d
try:
pass # a
except ZeroDivisionError:
pass # b
except:
pass # b
pass # c
else:
pass # d
finally:
pass # c
pass # e
try: # 1 preceding: any, following: first in body, enclosing: try
print(1) # 2 preceding: last in body, following: fist in alt body, enclosing: try
except ZeroDivisionError: # 3 preceding: test, following: fist in alt body, enclosing: try
print(2) # 4 preceding: last in body, following: fist in alt body, enclosing: exc
except: # 5 preceding: last in body, following: fist in alt body, enclosing: try
print(2) # 6 preceding: last in body, following: fist in alt body, enclosing: exc
else: # 7 preceding: last in body, following: fist in alt body, enclosing: exc
print(3) # 8 preceding: last in body, following: fist in alt body, enclosing: try
finally: # 9 preceding: last in body, following: fist in alt body, enclosing: try
print(3) # 10 preceding: last in body, following: any, enclosing: try
```