Skip to content
Permalink
Browse files

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

Fixes #997.
  • Loading branch information...
msullivan authored and JelleZijlstra committed Oct 3, 2019
1 parent c5637a7 commit d9e71a75ccfefa3d9156a64c03313a0d4ad981e5
Showing with 84 additions and 16 deletions.
  1. +30 −3 black.py
  2. +4 −0 tests/data/comments6.py
  3. +42 −0 tests/data/comments7.py
  4. +7 −10 tests/data/expression.diff
  5. +1 −3 tests/data/expression.py
@@ -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):
@@ -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
@@ -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:
@@ -99,5 +99,9 @@ def func(
a[-1], # type: ignore
)

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


result = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" # aaa
@@ -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 (
@@ -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",
)
@@ -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]
@@ -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
@@ -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]
@@ -374,9 +374,7 @@ def gen():
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(

0 comments on commit d9e71a7

Please sign in to comment.
You can’t perform that action at this time.