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

add option: allow_block_newline #3686

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
7 changes: 7 additions & 0 deletions src/black/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,11 @@ def validate_regex(
is_flag=True,
help="Don't use trailing commas as a reason to split lines.",
)
@click.option(
"--allow-block-newline",
is_flag=True,
help="Allow a single opening newline after a block opens.",
)
@click.option(
"--experimental-string-processing",
is_flag=True,
Expand Down Expand Up @@ -439,6 +444,7 @@ def main( # noqa: C901
skip_source_first_line: bool,
skip_string_normalization: bool,
skip_magic_trailing_comma: bool,
allow_block_newline: bool,
experimental_string_processing: bool,
preview: bool,
quiet: bool,
Expand Down Expand Up @@ -547,6 +553,7 @@ def main( # noqa: C901
skip_source_first_line=skip_source_first_line,
string_normalization=not skip_string_normalization,
magic_trailing_comma=not skip_magic_trailing_comma,
allow_block_newline=allow_block_newline,
experimental_string_processing=experimental_string_processing,
preview=preview,
python_cell_magics=set(python_cell_magics),
Expand Down
6 changes: 5 additions & 1 deletion src/black/lines.py
Original file line number Diff line number Diff line change
Expand Up @@ -636,7 +636,11 @@ def _maybe_empty_lines(self, current_line: Line) -> Tuple[int, int]:
):
return before, 1

if self.previous_line and self.previous_line.opens_block:
if (
not self.mode.allow_block_newline
and self.previous_line
and self.previous_line.opens_block
):
return 0, 0
return before, 0

Expand Down
2 changes: 2 additions & 0 deletions src/black/mode.py
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ class Mode:
is_ipynb: bool = False
skip_source_first_line: bool = False
magic_trailing_comma: bool = True
allow_block_newline: bool = False
experimental_string_processing: bool = False
python_cell_magics: Set[str] = field(default_factory=set)
preview: bool = False
Expand Down Expand Up @@ -220,6 +221,7 @@ def get_cache_key(self) -> str:
str(int(self.is_ipynb)),
str(int(self.skip_source_first_line)),
str(int(self.magic_trailing_comma)),
str(int(self.allow_block_newline)),
str(int(self.experimental_string_processing)),
str(int(self.preview)),
sha256((",".join(sorted(self.python_cell_magics))).encode()).hexdigest(),
Expand Down
4 changes: 4 additions & 0 deletions src/blackd/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
SKIP_SOURCE_FIRST_LINE = "X-Skip-Source-First-Line"
SKIP_STRING_NORMALIZATION_HEADER = "X-Skip-String-Normalization"
SKIP_MAGIC_TRAILING_COMMA = "X-Skip-Magic-Trailing-Comma"
ALLOW_BLOCK_NEWLINE = "X-Allow_Block_Newline"
PREVIEW = "X-Preview"
FAST_OR_SAFE_HEADER = "X-Fast-Or-Safe"
DIFF_HEADER = "X-Diff"
Expand All @@ -44,6 +45,7 @@
SKIP_SOURCE_FIRST_LINE,
SKIP_STRING_NORMALIZATION_HEADER,
SKIP_MAGIC_TRAILING_COMMA,
ALLOW_BLOCK_NEWLINE,
PREVIEW,
FAST_OR_SAFE_HEADER,
DIFF_HEADER,
Expand Down Expand Up @@ -113,6 +115,7 @@ async def handle(request: web.Request, executor: Executor) -> web.Response:
skip_magic_trailing_comma = bool(
request.headers.get(SKIP_MAGIC_TRAILING_COMMA, False)
)
allow_block_newline = bool(request.headers.get(ALLOW_BLOCK_NEWLINE, False))
skip_source_first_line = bool(
request.headers.get(SKIP_SOURCE_FIRST_LINE, False)
)
Expand All @@ -127,6 +130,7 @@ async def handle(request: web.Request, executor: Executor) -> web.Response:
skip_source_first_line=skip_source_first_line,
string_normalization=not skip_string_normalization,
magic_trailing_comma=not skip_magic_trailing_comma,
allow_block_newline=allow_block_newline,
preview=preview,
)
req_bytes = await request.content.read()
Expand Down
214 changes: 214 additions & 0 deletions tests/data/miscellaneous/allow_newline_after_code_block_open.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,214 @@
import random


def foo1():

print("Opening newline not removed with allow-block-newline")


def foo2():



print("allow-block-newline keeps one line")


def foo3():

print("Opening newline not removed with allow-block-newline")

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("Opening newline not removed with allow-block-newline")


for i in range(4):
print("no newline added here")

for i in range(5):

print("Opening newline not removed with allow-block-newline")


for i in range(6):



print("allow-block-newline keeps one line")


for i in range(7):

for j in range(7):

print("Opening newline not removed with allow-block-newline")


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

print("Opening newline not removed with allow-block-newline")


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




print("allow-block-newline keeps one line")


if random.randint(0, 5) == 0:
if random.uniform(0, 1) > 0.5:
print("no newlines added here")


while True:

print("Opening newline not removed with allow-block-newline")


while True:



print("allow-block-newline keeps one line")


while True:

while False:

print("Opening newline not removed with allow-block-newline")


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

file.write("Opening newline not removed with allow-block-newline")


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



file.write("The newlines 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("Opening newline not removed with allow-block-newline")


def foo2():

print("allow-block-newline keeps one line")


def foo3():

print("Opening newline not removed with allow-block-newline")

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("Opening newline not removed with allow-block-newline")


for i in range(4):
print("no newline added here")

for i in range(5):

print("Opening newline not removed with allow-block-newline")


for i in range(6):

print("allow-block-newline keeps one line")


for i in range(7):

for j in range(7):

print("Opening newline not removed with allow-block-newline")


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

print("Opening newline not removed with allow-block-newline")


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

print("allow-block-newline keeps one line")


if random.randint(0, 5) == 0:
if random.uniform(0, 1) > 0.5:
print("no newlines added here")


while True:

print("Opening newline not removed with allow-block-newline")


while True:

print("allow-block-newline keeps one line")


while True:

while False:

print("Opening newline not removed with allow-block-newline")


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

file.write("Opening newline not removed with allow-block-newline")


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

file.write("The newlines 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())
7 changes: 7 additions & 0 deletions tests/test_format.py
Original file line number Diff line number Diff line change
Expand Up @@ -203,3 +203,10 @@ def test_type_comment_syntax_error() -> None:
source, expected = read_data("type_comments", "type_comment_syntax_error")
assert_format(source, expected)
black.assert_equivalent(source, expected)


def test_optional_allow_block_newline() -> None:
"""test allow_block_newline=True"""
source, expected = read_data("miscellaneous", "allow_newline_after_code_block_open")
mode = black.Mode(allow_block_newline=True)
assert_format(source, expected, mode)