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

Don't break long lines when type: ignore is present #1040

Merged
merged 1 commit into from
Oct 3, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 30 additions & 3 deletions black.py
Original file line number Diff line number Diff line change
Expand Up @@ -1325,6 +1325,28 @@ def contains_uncollapsable_type_comments(self) -> bool:

return False

def contains_unsplittable_type_ignore(self) -> bool:
if not self.leaves:
return False

# If a 'type: ignore' is attached to the end of a line, we
# can't split the line, because we can't know which of the
# subexpressions the ignore was meant to apply to.
#
# We only want this to apply to actual physical lines from the
# original source, though: we don't want the presence of a
# 'type: ignore' at the end of a multiline expression to
# justify pushing it all onto one line. Thus we
# (unfortunately) need to check the actual source lines and
# only report an unsplittable 'type: ignore' if this line was
# one line in the original code.
if self.leaves[0].lineno == self.leaves[-1].lineno:
for comment in self.comments.get(id(self.leaves[-1]), []):
if is_type_comment(comment, " ignore"):
return True

return False

def contains_multiline_strings(self) -> bool:
for leaf in self.leaves:
if is_multiline_string(leaf):
Expand Down Expand Up @@ -2332,7 +2354,10 @@ def split_line(
if (
not line.contains_uncollapsable_type_comments()
and not line.should_explode
and is_line_short_enough(line, line_length=line_length, line_str=line_str)
and (
is_line_short_enough(line, line_length=line_length, line_str=line_str)
or line.contains_unsplittable_type_ignore()
)
):
yield line
return
Expand Down Expand Up @@ -2705,12 +2730,14 @@ def is_import(leaf: Leaf) -> bool:
)


def is_type_comment(leaf: Leaf) -> bool:
def is_type_comment(leaf: Leaf, suffix: str = "") -> bool:
"""Return True if the given leaf is a special comment.
Only returns true for type comments for now."""
t = leaf.type
v = leaf.value
return t in {token.COMMENT, t == STANDALONE_COMMENT} and v.startswith("# type:")
return t in {token.COMMENT, t == STANDALONE_COMMENT} and v.startswith(
"# type:" + suffix
)


def normalize_prefix(leaf: Leaf, *, inside_brackets: bool) -> None:
Expand Down
4 changes: 4 additions & 0 deletions tests/data/comments6.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,5 +99,9 @@ def func(
a[-1], # type: ignore
)

c = call(
"aaaaaaaa", "aaaaaaaa", "aaaaaaaa", "aaaaaaaa", "aaaaaaaa", "aaaaaaaa", "aaaaaaaa" # type: ignore
)


result = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" # aaa
42 changes: 42 additions & 0 deletions tests/data/comments7.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,25 @@

result = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" # aaa


def func():
c = call(
0.0123,
0.0456,
0.0789,
0.0123,
0.0789,
a[-1], # type: ignore
)

# The type: ignore exception only applies to line length, not
# other types of formatting.
c = call(
"aaaaaaaa", "aaaaaaaa", "aaaaaaaa", "aaaaaaaa", "aaaaaaaa", "aaaaaaaa", # type: ignore
"aaaaaaaa", "aaaaaaaa", "aaaaaaaa", "aaaaaaaa", "aaaaaaaa", "aaaaaaaa"
)


# output

from .config import (
Expand Down Expand Up @@ -71,3 +90,26 @@
result = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" # aaa

result = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" # aaa


def func():
c = call(
0.0123, 0.0456, 0.0789, 0.0123, 0.0789, a[-1] # type: ignore
)

# The type: ignore exception only applies to line length, not
# other types of formatting.
c = call(
"aaaaaaaa",
"aaaaaaaa",
"aaaaaaaa",
"aaaaaaaa",
"aaaaaaaa",
"aaaaaaaa", # type: ignore
"aaaaaaaa",
"aaaaaaaa",
"aaaaaaaa",
"aaaaaaaa",
"aaaaaaaa",
"aaaaaaaa",
)
17 changes: 7 additions & 10 deletions tests/data/expression.diff
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@
call(**self.screen_kwargs)
call(b, **self.screen_kwargs)
lukasz.langa.pl
@@ -94,23 +115,25 @@
@@ -94,23 +115,23 @@
1.0 .real
....__class__
list[str]
Expand All @@ -132,15 +132,12 @@
xxxx_xxxxx_xxxx_xxx: Callable[..., List[SomeClass]] = classmethod( # type: ignore
sync(async_xxxx_xxx_xxxx_xxxxx_xxxx_xxx.__func__)
)
-xxxx_xxx_xxxx_xxxxx_xxxx_xxx: Callable[..., List[SomeClass]] = classmethod( # type: ignore
- sync(async_xxxx_xxx_xxxx_xxxxx_xxxx_xxx.__func__)
-)
xxxx_xxx_xxxx_xxxxx_xxxx_xxx: Callable[
..., List[SomeClass]
xxxx_xxx_xxxx_xxxxx_xxxx_xxx: Callable[..., List[SomeClass]] = classmethod( # type: ignore
sync(async_xxxx_xxx_xxxx_xxxxx_xxxx_xxx.__func__)
)
-xxxx_xxx_xxxx_xxxxx_xxxx_xxx: Callable[
- ..., List[SomeClass]
-] = classmethod(sync(async_xxxx_xxx_xxxx_xxxxx_xxxx_xxx.__func__)) # type: ignore
+] = classmethod( # type: ignore
+ sync(async_xxxx_xxx_xxxx_xxxxx_xxxx_xxx.__func__)
+)
+xxxx_xxx_xxxx_xxxxx_xxxx_xxx: Callable[..., List[SomeClass]] = classmethod(
+ sync(async_xxxx_xxx_xxxx_xxxxx_xxxx_xxx.__func__)
+) # type: ignore
Expand All @@ -149,7 +146,7 @@
slice[0:1:2]
slice[:]
slice[:-1]
@@ -134,113 +157,171 @@
@@ -134,113 +155,171 @@
numpy[-(c + 1) :, d]
numpy[:, l[-2]]
numpy[:, ::-1]
Expand Down
4 changes: 1 addition & 3 deletions tests/data/expression.py
Original file line number Diff line number Diff line change
Expand Up @@ -374,9 +374,7 @@ async def f():
xxxx_xxxxx_xxxx_xxx: Callable[..., List[SomeClass]] = classmethod( # type: ignore
sync(async_xxxx_xxx_xxxx_xxxxx_xxxx_xxx.__func__)
)
xxxx_xxx_xxxx_xxxxx_xxxx_xxx: Callable[
..., List[SomeClass]
] = classmethod( # type: ignore
xxxx_xxx_xxxx_xxxxx_xxxx_xxx: Callable[..., List[SomeClass]] = classmethod( # type: ignore
sync(async_xxxx_xxx_xxxx_xxxxx_xxxx_xxx.__func__)
)
xxxx_xxx_xxxx_xxxxx_xxxx_xxx: Callable[..., List[SomeClass]] = classmethod(
Expand Down