Insert newline after nested function or class statements (#7946)

**Summary** Insert a newline after nested function and class
definitions, unless there is a trailing own line comment.

We need to e.g. format
```python
if platform.system() == "Linux":
    if sys.version > (3, 10):
        def f():
            print("old")
    else:
        def f():
            print("new")
    f()
```
as
```python
if platform.system() == "Linux":
    if sys.version > (3, 10):

        def f():
            print("old")

    else:

        def f():
            print("new")

    f()
```
even though `f()` is directly preceded by an if statement, not a
function or class definition. See the comments and fixtures for trailing
own line comment handling.

**Test Plan** I checked that the new content of `newlines.py` matches
black's formatting.

---------

Co-authored-by: Charlie Marsh <charlie.r.marsh@gmail.com>
This commit is contained in:
konsti 2023-10-18 11:45:58 +02:00 committed by GitHub
parent dda4ceda71
commit 0c3123e07e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 430 additions and 77 deletions

View file

@ -73,7 +73,7 @@ with hmm_but_this_should_get_two_preceding_newlines():
elif os.name == "nt":
try:
import msvcrt
@@ -54,12 +53,10 @@
@@ -54,7 +53,6 @@
class IHopeYouAreHavingALovelyDay:
def __call__(self):
print("i_should_be_followed_by_only_one_newline")
@ -81,11 +81,6 @@ with hmm_but_this_should_get_two_preceding_newlines():
else:
def foo():
pass
-
with hmm_but_this_should_get_two_preceding_newlines():
pass
```
## Ruff Output
@ -151,6 +146,7 @@ else:
def foo():
pass
with hmm_but_this_should_get_two_preceding_newlines():
pass
```

View file

@ -7,6 +7,7 @@ input_file: crates/ruff_python_formatter/resources/test/fixtures/ruff/newlines.p
###
# Blank lines around functions
###
import sys
x = 1
@ -165,13 +166,107 @@ def f():
# comment
x = 1
```
def f():
if True:
def double(s):
return s + s
print("below function")
if True:
class A:
x = 1
print("below class")
if True:
def double(s):
return s + s
#
print("below comment function")
if True:
class A:
x = 1
#
print("below comment class")
if True:
def double(s):
return s + s
#
print("below comment function 2")
if True:
def double(s):
return s + s
#
def outer():
def inner():
pass
print("below nested functions")
if True:
def double(s):
return s + s
print("below function")
if True:
class A:
x = 1
print("below class")
def outer():
def inner():
pass
print("below nested functions")
class Path:
if sys.version_info >= (3, 11):
def joinpath(self): ...
# The .open method comes from pathlib.pyi and should be kept in sync.
@overload
def open(self): ...
def fakehttp():
class FakeHTTPConnection:
if mock_close:
def close(self):
pass
FakeHTTPConnection.fakedata = fakedata
if True:
if False:
def x():
def y():
pass
#comment
print()
# NOTE: Please keep this the last block in this file. This tests that we don't insert
# empty line(s) at the end of the file due to nested function
if True:
def nested_trailing_function():
pass```
## Output
```py
###
# Blank lines around functions
###
import sys
x = 1
@ -339,6 +434,118 @@ def f():
# comment
x = 1
def f():
if True:
def double(s):
return s + s
print("below function")
if True:
class A:
x = 1
print("below class")
if True:
def double(s):
return s + s
#
print("below comment function")
if True:
class A:
x = 1
#
print("below comment class")
if True:
def double(s):
return s + s
#
print("below comment function 2")
if True:
def double(s):
return s + s
#
def outer():
def inner():
pass
print("below nested functions")
if True:
def double(s):
return s + s
print("below function")
if True:
class A:
x = 1
print("below class")
def outer():
def inner():
pass
print("below nested functions")
class Path:
if sys.version_info >= (3, 11):
def joinpath(self):
...
# The .open method comes from pathlib.pyi and should be kept in sync.
@overload
def open(self):
...
def fakehttp():
class FakeHTTPConnection:
if mock_close:
def close(self):
pass
FakeHTTPConnection.fakedata = fakedata
if True:
if False:
def x():
def y():
pass
# comment
print()
# NOTE: Please keep this the last block in this file. This tests that we don't insert
# empty line(s) at the end of the file due to nested function
if True:
def nested_trailing_function():
pass
```

View file

@ -410,6 +410,7 @@ else:
pass
# 3
if True:
print("a") # 1
elif True:

View file

@ -311,6 +311,7 @@ finally:
pass
# d
try:
pass # a
except ZeroDivisionError: