Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove newline after code block open #3035

Merged
merged 27 commits into from Jun 11, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
df60609
black will remove newlines between `def` statement and its function c…
saroad2 Apr 25, 2022
13f2aaf
Test the new ability
saroad2 Apr 25, 2022
8d6c373
Add change to CHANGES.md
saroad2 Apr 25, 2022
b991571
Added a few test cases
saroad2 Apr 25, 2022
549a094
Added more tests
saroad2 Apr 25, 2022
c30a951
Update CHANGES.md according to suggestion
saroad2 Apr 25, 2022
17516d7
remove trailing newline in `def` statement is now a preview ability
saroad2 Apr 25, 2022
bb97364
Add myself to AUTHORS.md since it's my forth PR in *Black*
saroad2 Apr 25, 2022
466767d
Merge branch 'main' into remove_newline_after_def
saroad2 Apr 29, 2022
2922f44
Merge branch 'master' into remove_newline_after_def
saroad2 May 8, 2022
10a299c
Merge branch 'main' into remove_newline_after_def
saroad2 May 9, 2022
a9eaf0f
Merge branch 'main' into remove_newline_after_def
saroad2 May 18, 2022
f2a5b65
Merge branch 'main' into remove_newline_after_def
saroad2 May 18, 2022
700c51d
Move new test cases to preview directory
saroad2 May 18, 2022
fd1da5c
*Black* now removes newlines after EVERY open block statement
saroad2 May 18, 2022
c845c0c
Add unit tests for removing newlines
saroad2 May 18, 2022
f8bbdbb
Add new feature to future_style.md
saroad2 May 19, 2022
6fe0a98
Fix change in CHANGES.md
saroad2 May 19, 2022
4fd907a
Combine all new test cases to one case.
saroad2 May 19, 2022
b2a015c
trim down long description in the future_style.md document
saroad2 May 19, 2022
b6e720c
Merge branch 'main' into remove_newline_after_def
saroad2 May 25, 2022
e496d90
Rename `remove_def_trailing_newline` to `remove_block_trailing_newline`
saroad2 May 25, 2022
860941b
Update docs/the_black_code_style/future_style.md
saroad2 May 26, 2022
f44edba
Fix linting issue
saroad2 May 26, 2022
24b48ca
Add new preview feature test for `match`-`case` blocks
saroad2 May 26, 2022
92ce12c
Fix failing test
saroad2 May 26, 2022
ee5888b
Add `case` and `match` to code blocks list
saroad2 May 26, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions AUTHORS.md
Expand Up @@ -148,6 +148,7 @@ Multiple contributions by:
- [Rishikesh Jha](mailto:rishijha424@gmail.com)
- [Rupert Bedford](mailto:rupert@rupertb.com)
- Russell Davis
- [Sagi Shadur](mailto:saroad2@gmail.com)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This AUTHORS list is so out of date, gosh. Good for you adding yourself!

- [Rémi Verschelde](mailto:rverschelde@gmail.com)
- [Sami Salonen](mailto:sakki@iki.fi)
- [Samuel Cormier-Iijima](mailto:samuel@cormier-iijima.com)
Expand Down
1 change: 1 addition & 0 deletions CHANGES.md
Expand Up @@ -21,6 +21,7 @@
- Remove redundant parentheses around awaited objects (#2991)
- Parentheses around return annotations are now managed (#2990)
- Remove unnecessary parentheses from `with` statements (#2926)
- Remove trailing newlines after code block open (#3035)

### _Blackd_

Expand Down
25 changes: 25 additions & 0 deletions docs/the_black_code_style/future_style.md
Expand Up @@ -49,3 +49,28 @@ plain strings. User-made splits are respected when they do not exceed the line l
limit. Line continuation backslashes are converted into parenthesized strings.
Unnecessary parentheses are stripped. The stability and status of this feature is
tracked in [this issue](https://github.com/psf/black/issues/2188).

### Removing trailing newlines after code block open
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh lovely, I've been worried lately our style documentation is out of date with the current state of affairs, but this quells my worries with this PR ^^


_Black_ will remove trailing newlines after code block openings. That means that the
following code:

```python
def my_func():

print("The line above me will be deleted!")

print("But the line above me won't!")
```

Will be changed to:

```python
def my_func():
print("The line above me will be deleted!")

print("But the line above me won't!")
```

This new feature will be applied to **all code blocks**: `def`, `class`, `if`, `for`,
`while`, `with`, `case` and `match`.
13 changes: 13 additions & 0 deletions src/black/lines.py
Expand Up @@ -168,6 +168,13 @@ def is_triple_quoted_string(self) -> bool:
and self.leaves[0].value.startswith(('"""', "'''"))
)

@property
def opens_block(self) -> bool:
"""Does this line open a new level of indentation."""
if len(self.leaves) == 0:
return False
return self.leaves[-1].type == token.COLON

def contains_standalone_comments(self, depth_limit: int = sys.maxsize) -> bool:
"""If so, needs to be split before emitting."""
for leaf in self.leaves:
Expand Down Expand Up @@ -513,6 +520,12 @@ def _maybe_empty_lines(self, current_line: Line) -> Tuple[int, int]:
):
return before, 1

if (
Preview.remove_block_trailing_newline in current_line.mode
and self.previous_line
and self.previous_line.opens_block
):
return 0, 0
return before, 0

def _maybe_empty_lines_for_class_or_def(
Expand Down
1 change: 1 addition & 0 deletions src/black/mode.py
Expand Up @@ -148,6 +148,7 @@ class Preview(Enum):
one_element_subscript = auto()
annotation_parens = auto()
long_docstring_quotes_on_newline = auto()
remove_block_trailing_newline = auto()


class Deprecated(UserWarning):
Expand Down
189 changes: 189 additions & 0 deletions tests/data/preview/remove_newline_after_code_block_open.py
@@ -0,0 +1,189 @@
import random


def foo1():

print("The newline above me should be deleted!")


def foo2():



print("All the newlines above me should be deleted!")


def foo3():

print("No newline above me!")

print("There is a newline above me, and that's OK!")


def foo4():

# There is a comment here

print("The newline above me should not be deleted!")


class Foo:
def bar(self):

print("The newline above me should be deleted!")


for i in range(5):

print(f"{i}) The line above me should be removed!")


for i in range(5):



print(f"{i}) The lines above me should be removed!")


for i in range(5):

for j in range(7):

print(f"{i}) The lines above me should be removed!")


if random.randint(0, 3) == 0:

print("The new line above me is about to be removed!")


if random.randint(0, 3) == 0:




print("The new lines above me is about to be removed!")


if random.randint(0, 3) == 0:
if random.uniform(0, 1) > 0.5:
print("Two lines above me are about to be removed!")


while True:

print("The newline above me should be deleted!")


while True:



print("The newlines above me should be deleted!")


while True:

while False:

print("The newlines above me should be deleted!")


with open("/path/to/file.txt", mode="w") as file:

file.write("The new line above me is about to be removed!")


with open("/path/to/file.txt", mode="w") as file:



file.write("The new lines above me is about to be removed!")


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())

# output

import random


def foo1():
print("The newline above me should be deleted!")


def foo2():
print("All the newlines above me should be deleted!")


def foo3():
print("No newline above me!")

print("There is a newline above me, and that's OK!")


def foo4():
# There is a comment here

print("The newline above me should not be deleted!")


class Foo:
def bar(self):
print("The newline above me should be deleted!")


for i in range(5):
print(f"{i}) The line above me should be removed!")


for i in range(5):
print(f"{i}) The lines above me should be removed!")


for i in range(5):
for j in range(7):
print(f"{i}) The lines above me should be removed!")


if random.randint(0, 3) == 0:
print("The new line above me is about to be removed!")


if random.randint(0, 3) == 0:
print("The new lines above me is about to be removed!")


if random.randint(0, 3) == 0:
if random.uniform(0, 1) > 0.5:
print("Two lines above me are about to be removed!")


while True:
print("The newline above me should be deleted!")


while True:
print("The newlines above me should be deleted!")


while True:
while False:
print("The newlines above me should be deleted!")


with open("/path/to/file.txt", mode="w") as file:
file.write("The new line above me is about to be removed!")


with open("/path/to/file.txt", mode="w") as file:
file.write("The new lines above me is about to be removed!")


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())
34 changes: 34 additions & 0 deletions tests/data/preview_310/remove_newline_after match.py
@@ -0,0 +1,34 @@
def http_status(status):

match status:

case 400:

return "Bad request"

case 401:

return "Unauthorized"

case 403:

return "Forbidden"

case 404:

return "Not found"

# output
def http_status(status):
match status:
case 400:
return "Bad request"

case 401:
return "Unauthorized"

case 403:
return "Forbidden"

case 404:
return "Not found"
1 change: 0 additions & 1 deletion tests/test_black.py
Expand Up @@ -1455,7 +1455,6 @@ def test_newline_comment_interaction(self) -> None:
black.assert_stable(source, output, mode=DEFAULT_MODE)

def test_bpo_2142_workaround(self) -> None:

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Haha, I like it!

# https://bugs.python.org/issue2142

source, _ = read_data("miscellaneous", "missing_final_newline")
Expand Down
7 changes: 7 additions & 0 deletions tests/test_format.py
Expand Up @@ -86,6 +86,13 @@ def test_preview_minimum_python_39_format(filename: str) -> None:
assert_format(source, expected, mode, minimum_version=(3, 9))


@pytest.mark.parametrize("filename", all_data_cases("preview_310"))
def test_preview_minimum_python_310_format(filename: str) -> None:
source, expected = read_data("preview_310", filename)
mode = black.Mode(preview=True)
assert_format(source, expected, mode, minimum_version=(3, 10))


@pytest.mark.parametrize("filename", SOURCES)
def test_source_is_formatted(filename: str) -> None:
check_file("", filename, DEFAULT_MODE, data=False)
Expand Down