Skip to content

Commit 5ace049

Browse files
AleksMatcopybara-github
authored andcommitted
Internal change
PiperOrigin-RevId: 697698863
1 parent ea92658 commit 5ace049

File tree

3 files changed

+63
-16
lines changed

3 files changed

+63
-16
lines changed

patches/pyink.patch

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -780,16 +780,23 @@
780780
or self.bracket_tracker.any_open_for_or_lambda()
781781
):
782782
if self.is_comment:
783-
@@ -262,7 +278,7 @@ class Line:
783+
@@ -262,7 +278,14 @@ class Line:
784784
return True
785785
return False
786786

787787
- def contains_uncollapsable_type_comments(self) -> bool:
788+
+ def contains_pragma_comments(self) -> bool:
789+
+ for comments in self.comments.values():
790+
+ for comment in comments:
791+
+ if is_pragma_comment(comment, self.mode):
792+
+ return True
793+
+ return False
794+
+
788795
+ def contains_uncollapsable_pragma_comments(self) -> bool:
789796
ignored_ids = set()
790797
try:
791798
last_leaf = self.leaves[-1]
792-
@@ -287,11 +303,9 @@ class Line:
799+
@@ -287,11 +310,9 @@ class Line:
793800
comment_seen = False
794801
for leaf_id, comments in self.comments.items():
795802
for comment in comments:
@@ -804,7 +811,7 @@
804811
return True
805812

806813
comment_seen = True
807-
@@ -326,7 +340,7 @@ class Line:
814+
@@ -326,7 +347,7 @@ class Line:
808815
# line.
809816
for node in self.leaves[-2:]:
810817
for comment in self.comments.get(id(node), []):
@@ -813,7 +820,7 @@
813820
return True
814821

815822
return False
816-
@@ -481,7 +495,7 @@ class Line:
823+
@@ -481,7 +502,7 @@ class Line:
817824
if not self:
818825
return "\n"
819826

@@ -822,7 +829,7 @@
822829
leaves = iter(self.leaves)
823830
first = next(leaves)
824831
res = f"{first.prefix}{indent}{first.value}"
825-
@@ -553,7 +567,7 @@ class EmptyLineTracker:
832+
@@ -553,7 +574,7 @@ class EmptyLineTracker:
826833
lines (two on module-level).
827834
"""
828835
form_feed = (
@@ -831,7 +838,7 @@
831838
and bool(current_line.leaves)
832839
and "\f\n" in current_line.leaves[0].prefix
833840
)
834-
@@ -598,7 +612,7 @@ class EmptyLineTracker:
841+
@@ -598,7 +619,7 @@ class EmptyLineTracker:
835842

836843
def _maybe_empty_lines(self, current_line: Line) -> tuple[int, int]: # noqa: C901
837844
max_allowed = 1
@@ -840,7 +847,7 @@
840847
max_allowed = 1 if self.mode.is_pyi else 2
841848

842849
if current_line.leaves:
843-
@@ -615,7 +629,7 @@ class EmptyLineTracker:
850+
@@ -615,7 +636,7 @@ class EmptyLineTracker:
844851

845852
# Mutate self.previous_defs, remainder of this function should be pure
846853
previous_def = None
@@ -849,7 +856,7 @@
849856
previous_def = self.previous_defs.pop()
850857
if current_line.is_def or current_line.is_class:
851858
self.previous_defs.append(current_line)
852-
@@ -671,10 +685,25 @@ class EmptyLineTracker:
859+
@@ -671,10 +692,25 @@ class EmptyLineTracker:
853860
)
854861

855862
if (
@@ -877,7 +884,7 @@
877884
):
878885
return (before or 1), 0
879886

880-
@@ -691,8 +720,9 @@ class EmptyLineTracker:
887+
@@ -691,8 +727,9 @@ class EmptyLineTracker:
881888
return 0, 1
882889
return 0, 0
883890

@@ -889,7 +896,7 @@
889896
):
890897
if self.mode.is_pyi:
891898
return 0, 0
892-
@@ -701,7 +731,7 @@ class EmptyLineTracker:
899+
@@ -701,7 +738,7 @@ class EmptyLineTracker:
893900
comment_to_add_newlines: Optional[LinesBlock] = None
894901
if (
895902
self.previous_line.is_comment
@@ -898,7 +905,7 @@
898905
and before == 0
899906
):
900907
slc = self.semantic_leading_comment
901-
@@ -718,9 +748,9 @@ class EmptyLineTracker:
908+
@@ -718,9 +755,9 @@ class EmptyLineTracker:
902909

903910
if self.mode.is_pyi:
904911
if current_line.is_class or self.previous_line.is_class:
@@ -910,7 +917,7 @@
910917
newlines = 1
911918
elif current_line.is_stub_class and self.previous_line.is_stub_class:
912919
# No blank line between classes with an empty body
913-
@@ -749,7 +779,11 @@ class EmptyLineTracker:
920+
@@ -749,7 +786,11 @@ class EmptyLineTracker:
914921
newlines = 1 if current_line.depth else 2
915922
# If a user has left no space after a dummy implementation, don't insert
916923
# new lines. This is useful for instance for @overload or Protocols.
@@ -923,7 +930,7 @@
923930
newlines = 0
924931
if comment_to_add_newlines is not None:
925932
previous_block = comment_to_add_newlines.previous_block
926-
@@ -1020,7 +1054,7 @@ def can_omit_invisible_parens(
933+
@@ -1020,7 +1061,7 @@ def can_omit_invisible_parens(
927934
def _can_omit_opening_paren(line: Line, *, first: Leaf, line_length: int) -> bool:
928935
"""See `can_omit_invisible_parens`."""
929936
remainder = False
@@ -932,7 +939,7 @@
932939
_index = -1
933940
for _index, leaf, leaf_length in line.enumerate_with_length():
934941
if leaf.type in CLOSING_BRACKETS and leaf.opening_bracket is first:
935-
@@ -1044,7 +1078,7 @@ def _can_omit_opening_paren(line: Line,
942+
@@ -1044,7 +1085,7 @@ def _can_omit_opening_paren(line: Line,
936943

937944
def _can_omit_closing_paren(line: Line, *, last: Leaf, line_length: int) -> bool:
938945
"""See `can_omit_invisible_parens`."""

src/pyink/ink.py

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,13 @@
44
"""
55

66
from collections.abc import Collection, Iterator, Sequence
7+
import copy
78
import re
8-
from typing import Optional, Union
9+
from typing import Any, Optional, Union
910

1011
from blib2to3.pgen2.token import ASYNC, FSTRING_START, NEWLINE, STRING
11-
from blib2to3.pytree import type_repr
12+
from blib2to3.pytree import NL, type_repr
13+
from pyink.lines import Line
1214
from pyink.mode import Quote
1315
from pyink.nodes import LN, Leaf, Node, STANDALONE_COMMENT, Visitor, syms
1416
from pyink.strings import STRING_PREFIX_CHARS
@@ -95,6 +97,37 @@ def _match_to_unicode(match: re.Match[str]) -> str:
9597
return re.sub(r"[<>&]", _match_to_unicode, src)
9698

9799

100+
def deepcopy_line(line: Line) -> Line:
101+
"""Calculates a deep copy of a Line object.
102+
103+
Deep-copying a Line object is not trivial because it contains various
104+
dictionaries mapping id(NL) -> NL, where NL stands for Node or Leaf. Because
105+
all objects are copied, also the ids in dictionaries need to be updated.
106+
107+
The function first finds all NL objects and calculates the id mapping. Then
108+
it updates all dictionaries.
109+
110+
Args:
111+
line: The Line object to copy.
112+
113+
Returns:
114+
A deep copy of the Line object with updated references.
115+
"""
116+
memo: dict[int, Any] = {}
117+
line_copy = copy.deepcopy(line, memo=memo)
118+
119+
line_copy.comments = {
120+
id(memo[leaf_id]): comment_leaves
121+
for leaf_id, comment_leaves in line_copy.comments.items()
122+
}
123+
line_copy.bracket_tracker.delimiters = {
124+
id(memo[leaf_id]): priority
125+
for leaf_id, priority in line_copy.bracket_tracker.delimiters.items()
126+
}
127+
128+
return line_copy
129+
130+
98131
def convert_unchanged_lines(src_node: Node, lines: Collection[tuple[int, int]]):
99132
"""Converts unchanged lines to STANDALONE_COMMENT.
100133

src/pyink/lines.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,13 @@ def contains_implicit_multiline_string_with_comments(self) -> bool:
278278
return True
279279
return False
280280

281+
def contains_pragma_comments(self) -> bool:
282+
for comments in self.comments.values():
283+
for comment in comments:
284+
if is_pragma_comment(comment, self.mode):
285+
return True
286+
return False
287+
281288
def contains_uncollapsable_pragma_comments(self) -> bool:
282289
ignored_ids = set()
283290
try:

0 commit comments

Comments
 (0)