Skip to content

Commit 21218b6

Browse files
yileiichard26
andauthored
Fix a string merging/split issue caused by standalone comments. (#3227)
Fixes #2734: a standalone comment causes strings to be merged into one far too long (and requiring two passes to do so). Co-authored-by: Richard Si <[email protected]>
1 parent 59acf8a commit 21218b6

4 files changed

Lines changed: 52 additions & 2 deletions

File tree

.github/workflows/diff_shades.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,4 +155,3 @@ jobs:
155155
if: always()
156156
run: >
157157
diff-shades show-failed --check --show-log ${{ matrix.target-analysis }}
158-
--check-allow 'sqlalchemy:test/orm/test_relationship_criteria.py'

CHANGES.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626
normalized as expected (#3168)
2727
- When using `--skip-magic-trailing-comma` or `-C`, trailing commas are stripped from
2828
subscript expressions with more than 1 element (#3209)
29+
- Fix a string merging/split issue when a comment is present in the middle of implicitly
30+
concatenated strings on its own line (#3227)
2931

3032
### _Blackd_
3133

src/black/trans.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -553,6 +553,9 @@ def make_naked(string: str, string_prefix: str) -> str:
553553

554554
next_str_idx += 1
555555

556+
# Take a note on the index of the non-STRING leaf.
557+
non_string_idx = next_str_idx
558+
556559
S_leaf = Leaf(token.STRING, S)
557560
if self.normalize_strings:
558561
S_leaf.value = normalize_string_quotes(S_leaf.value)
@@ -572,7 +575,18 @@ def make_naked(string: str, string_prefix: str) -> str:
572575
string_leaf = Leaf(token.STRING, S_leaf.value.replace(BREAK_MARK, ""))
573576

574577
if atom_node is not None:
575-
replace_child(atom_node, string_leaf)
578+
# If not all children of the atom node are merged (this can happen
579+
# when there is a standalone comment in the middle) ...
580+
if non_string_idx - string_idx < len(atom_node.children):
581+
# We need to replace the old STRING leaves with the new string leaf.
582+
first_child_idx = LL[string_idx].remove()
583+
for idx in range(string_idx + 1, non_string_idx):
584+
LL[idx].remove()
585+
if first_child_idx is not None:
586+
atom_node.insert_child(first_child_idx, string_leaf)
587+
else:
588+
# Else replace the atom node with the new string leaf.
589+
replace_child(atom_node, string_leaf)
576590

577591
# Build the final line ('new_line') that this method will later return.
578592
new_line = line.clone()

tests/data/preview/long_strings.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,25 @@
7272
zzz,
7373
)
7474

75+
inline_comments_func1(
76+
"if there are inline "
77+
"comments in the middle "
78+
# Here is the standard alone comment.
79+
"of the implicitly concatenated "
80+
"string, we should handle "
81+
"them correctly",
82+
xxx,
83+
)
84+
85+
inline_comments_func2(
86+
"what if the string is very very very very very very very very very very long and this part does "
87+
"not fit into a single line? "
88+
# Here is the standard alone comment.
89+
"then the string should still be properly handled by merging and splitting "
90+
"it into parts that fit in line length.",
91+
xxx,
92+
)
93+
7594
raw_string = r"This is a long raw string. When re-formatting this string, black needs to make sure it prepends the 'r' onto the new string."
7695

7796
fmt_string1 = "We also need to be sure to preserve any and all {} which may or may not be attached to the string in question.".format("method calls")
@@ -395,6 +414,22 @@ def foo():
395414
zzz,
396415
)
397416

417+
inline_comments_func1(
418+
"if there are inline comments in the middle "
419+
# Here is the standard alone comment.
420+
"of the implicitly concatenated string, we should handle them correctly",
421+
xxx,
422+
)
423+
424+
inline_comments_func2(
425+
"what if the string is very very very very very very very very very very long and"
426+
" this part does not fit into a single line? "
427+
# Here is the standard alone comment.
428+
"then the string should still be properly handled by merging and splitting "
429+
"it into parts that fit in line length.",
430+
xxx,
431+
)
432+
398433
raw_string = (
399434
r"This is a long raw string. When re-formatting this string, black needs to make"
400435
r" sure it prepends the 'r' onto the new string."

0 commit comments

Comments
 (0)