Improves performance on large commented logical lines (#606)
Fixes #509
This commit is contained in:
parent
5bc62a4a82
commit
e4e59f87a8
63
black.py
63
black.py
@ -5,6 +5,7 @@
|
|||||||
from enum import Enum, Flag
|
from enum import Enum, Flag
|
||||||
from functools import lru_cache, partial, wraps
|
from functools import lru_cache, partial, wraps
|
||||||
import io
|
import io
|
||||||
|
import itertools
|
||||||
import keyword
|
import keyword
|
||||||
import logging
|
import logging
|
||||||
from multiprocessing import Manager
|
from multiprocessing import Manager
|
||||||
@ -1025,7 +1026,9 @@ class Line:
|
|||||||
|
|
||||||
depth: int = 0
|
depth: int = 0
|
||||||
leaves: List[Leaf] = Factory(list)
|
leaves: List[Leaf] = Factory(list)
|
||||||
comments: List[Tuple[Index, Leaf]] = Factory(list)
|
# The LeafID keys of comments must remain ordered by the corresponding leaf's index
|
||||||
|
# in leaves
|
||||||
|
comments: Dict[LeafID, List[Leaf]] = Factory(dict)
|
||||||
bracket_tracker: BracketTracker = Factory(BracketTracker)
|
bracket_tracker: BracketTracker = Factory(BracketTracker)
|
||||||
inside_brackets: bool = False
|
inside_brackets: bool = False
|
||||||
should_explode: bool = False
|
should_explode: bool = False
|
||||||
@ -1232,43 +1235,35 @@ def append_comment(self, comment: Leaf) -> bool:
|
|||||||
if comment.type != token.COMMENT:
|
if comment.type != token.COMMENT:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
after = len(self.leaves) - 1
|
if not self.leaves:
|
||||||
if after == -1:
|
|
||||||
comment.type = STANDALONE_COMMENT
|
comment.type = STANDALONE_COMMENT
|
||||||
comment.prefix = ""
|
comment.prefix = ""
|
||||||
return False
|
return False
|
||||||
|
|
||||||
else:
|
else:
|
||||||
self.comments.append((after, comment))
|
leaf_id = id(self.leaves[-1])
|
||||||
|
if leaf_id not in self.comments:
|
||||||
|
self.comments[leaf_id] = [comment]
|
||||||
|
else:
|
||||||
|
self.comments[leaf_id].append(comment)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def comments_after(self, leaf: Leaf, _index: int = -1) -> Iterator[Leaf]:
|
def comments_after(self, leaf: Leaf) -> List[Leaf]:
|
||||||
"""Generate comments that should appear directly after `leaf`.
|
"""Generate comments that should appear directly after `leaf`."""
|
||||||
|
return self.comments.get(id(leaf), [])
|
||||||
Provide a non-negative leaf `_index` to speed up the function.
|
|
||||||
"""
|
|
||||||
if not self.comments:
|
|
||||||
return
|
|
||||||
|
|
||||||
if _index == -1:
|
|
||||||
for _index, _leaf in enumerate(self.leaves):
|
|
||||||
if leaf is _leaf:
|
|
||||||
break
|
|
||||||
|
|
||||||
else:
|
|
||||||
return
|
|
||||||
|
|
||||||
for index, comment_after in self.comments:
|
|
||||||
if _index == index:
|
|
||||||
yield comment_after
|
|
||||||
|
|
||||||
def remove_trailing_comma(self) -> None:
|
def remove_trailing_comma(self) -> None:
|
||||||
"""Remove the trailing comma and moves the comments attached to it."""
|
"""Remove the trailing comma and moves the comments attached to it."""
|
||||||
comma_index = len(self.leaves) - 1
|
# Remember, the LeafID keys of self.comments are ordered by the
|
||||||
for i in range(len(self.comments)):
|
# corresponding leaf's index in self.leaves
|
||||||
comment_index, comment = self.comments[i]
|
# If id(self.leaves[-2]) is in self.comments, the order doesn't change.
|
||||||
if comment_index == comma_index:
|
# Otherwise, we insert it into self.comments, and it becomes the last entry.
|
||||||
self.comments[i] = (comma_index - 1, comment)
|
# However, since we delete id(self.leaves[-1]) from self.comments, the invariant
|
||||||
|
# is maintained
|
||||||
|
self.comments.setdefault(id(self.leaves[-2]), []).extend(
|
||||||
|
self.comments.get(id(self.leaves[-1]), [])
|
||||||
|
)
|
||||||
|
self.comments.pop(id(self.leaves[-1]), None)
|
||||||
self.leaves.pop()
|
self.leaves.pop()
|
||||||
|
|
||||||
def is_complex_subscript(self, leaf: Leaf) -> bool:
|
def is_complex_subscript(self, leaf: Leaf) -> bool:
|
||||||
@ -1300,7 +1295,7 @@ def __str__(self) -> str:
|
|||||||
res = f"{first.prefix}{indent}{first.value}"
|
res = f"{first.prefix}{indent}{first.value}"
|
||||||
for leaf in leaves:
|
for leaf in leaves:
|
||||||
res += str(leaf)
|
res += str(leaf)
|
||||||
for _, comment in self.comments:
|
for comment in itertools.chain.from_iterable(self.comments.values()):
|
||||||
res += str(comment)
|
res += str(comment)
|
||||||
return res + "\n"
|
return res + "\n"
|
||||||
|
|
||||||
@ -2395,10 +2390,10 @@ def append_to_line(leaf: Leaf) -> Iterator[Line]:
|
|||||||
current_line = Line(depth=line.depth, inside_brackets=line.inside_brackets)
|
current_line = Line(depth=line.depth, inside_brackets=line.inside_brackets)
|
||||||
current_line.append(leaf)
|
current_line.append(leaf)
|
||||||
|
|
||||||
for index, leaf in enumerate(line.leaves):
|
for leaf in line.leaves:
|
||||||
yield from append_to_line(leaf)
|
yield from append_to_line(leaf)
|
||||||
|
|
||||||
for comment_after in line.comments_after(leaf, index):
|
for comment_after in line.comments_after(leaf):
|
||||||
yield from append_to_line(comment_after)
|
yield from append_to_line(comment_after)
|
||||||
|
|
||||||
lowest_depth = min(lowest_depth, leaf.bracket_depth)
|
lowest_depth = min(lowest_depth, leaf.bracket_depth)
|
||||||
@ -2441,10 +2436,10 @@ def append_to_line(leaf: Leaf) -> Iterator[Line]:
|
|||||||
current_line = Line(depth=line.depth, inside_brackets=line.inside_brackets)
|
current_line = Line(depth=line.depth, inside_brackets=line.inside_brackets)
|
||||||
current_line.append(leaf)
|
current_line.append(leaf)
|
||||||
|
|
||||||
for index, leaf in enumerate(line.leaves):
|
for leaf in line.leaves:
|
||||||
yield from append_to_line(leaf)
|
yield from append_to_line(leaf)
|
||||||
|
|
||||||
for comment_after in line.comments_after(leaf, index):
|
for comment_after in line.comments_after(leaf):
|
||||||
yield from append_to_line(comment_after)
|
yield from append_to_line(comment_after)
|
||||||
|
|
||||||
if current_line:
|
if current_line:
|
||||||
@ -3436,7 +3431,7 @@ def enumerate_with_length(
|
|||||||
return # Multiline strings, we can't continue.
|
return # Multiline strings, we can't continue.
|
||||||
|
|
||||||
comment: Optional[Leaf]
|
comment: Optional[Leaf]
|
||||||
for comment in line.comments_after(leaf, index):
|
for comment in line.comments_after(leaf):
|
||||||
length += len(comment.value)
|
length += len(comment.value)
|
||||||
|
|
||||||
yield index, leaf, length
|
yield index, leaf, length
|
||||||
|
Loading…
Reference in New Issue
Block a user