Skip to content

Commit 7bca930

Browse files
Fix crash on concatenated string + comment (fixes #1596) (#1677)
Co-authored-by: Jelle Zijlstra <[email protected]>
1 parent e3ccabb commit 7bca930

File tree

2 files changed

+50
-5
lines changed

2 files changed

+50
-5
lines changed

src/black/__init__.py

+23-5
Original file line numberDiff line numberDiff line change
@@ -2889,11 +2889,8 @@ class StringMerger(CustomSplitMapMixin, StringTransformer):
28892889
"""StringTransformer that merges strings together.
28902890
28912891
Requirements:
2892-
(A) The line contains adjacent strings such that at most one substring
2893-
has inline comments AND none of those inline comments are pragmas AND
2894-
the set of all substring prefixes is either of length 1 or equal to
2895-
{"", "f"} AND none of the substrings are raw strings (i.e. are prefixed
2896-
with 'r').
2892+
(A) The line contains adjacent strings such that ALL of the validation checks
2893+
listed in StringMerger.__validate_msg(...)'s docstring pass.
28972894
OR
28982895
(B) The line contains a string which uses line continuation backslashes.
28992896
@@ -3142,6 +3139,7 @@ def __validate_msg(line: Line, string_idx: int) -> TResult[None]:
31423139
* Ok(None), if ALL validation checks (listed below) pass.
31433140
OR
31443141
* Err(CannotTransform), if any of the following are true:
3142+
- The target string group does not contain ANY stand-alone comments.
31453143
- The target string is not in a string group (i.e. it has no
31463144
adjacent strings).
31473145
- The string group has more than one inline comment.
@@ -3150,6 +3148,26 @@ def __validate_msg(line: Line, string_idx: int) -> TResult[None]:
31503148
length greater than one and is not equal to {"", "f"}.
31513149
- The string group consists of raw strings.
31523150
"""
3151+
# We first check for "inner" stand-alone comments (i.e. stand-alone
3152+
# comments that have a string leaf before them AND after them).
3153+
for inc in [1, -1]:
3154+
i = string_idx
3155+
found_sa_comment = False
3156+
is_valid_index = is_valid_index_factory(line.leaves)
3157+
while is_valid_index(i) and line.leaves[i].type in [
3158+
token.STRING,
3159+
STANDALONE_COMMENT,
3160+
]:
3161+
if line.leaves[i].type == STANDALONE_COMMENT:
3162+
found_sa_comment = True
3163+
elif found_sa_comment:
3164+
return TErr(
3165+
"StringMerger does NOT merge string groups which contain "
3166+
"stand-alone comments."
3167+
)
3168+
3169+
i += inc
3170+
31533171
num_of_inline_string_comments = 0
31543172
set_of_prefixes = set()
31553173
num_of_strings = 0

tests/data/long_strings__regression.py

+27
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,19 @@ def who(self):
310310
passenger_association=passenger_association,
311311
)
312312

313+
xxxxxxx_xxxxxx_xxxxxxx = xxx(
314+
[
315+
xxxxxxxxxxxx(
316+
xxxxxx_xxxxxxx=(
317+
'((x.aaaaaaaaa = "xxxxxx.xxxxxxxxxxxxxxxxxxxxx") || (x.xxxxxxxxx = "xxxxxxxxxxxx")) && '
318+
# xxxxx xxxxxxxxxxxx xxxx xxx (xxxxxxxxxxxxxxxx) xx x xxxxxxxxx xx xxxxxx.
319+
"(x.bbbbbbbbbbbb.xxx != "
320+
'"xxx:xxx:xxx::cccccccccccc:xxxxxxx-xxxx/xxxxxxxxxxx/xxxxxxxxxxxxxxxxx") && '
321+
)
322+
)
323+
]
324+
)
325+
313326
if __name__ == "__main__":
314327
for i in range(4, 8):
315328
cmd = (
@@ -709,6 +722,20 @@ def who(self):
709722
)
710723

711724

725+
xxxxxxx_xxxxxx_xxxxxxx = xxx(
726+
[
727+
xxxxxxxxxxxx(
728+
xxxxxx_xxxxxxx=(
729+
'((x.aaaaaaaaa = "xxxxxx.xxxxxxxxxxxxxxxxxxxxx") || (x.xxxxxxxxx ='
730+
' "xxxxxxxxxxxx")) && '
731+
# xxxxx xxxxxxxxxxxx xxxx xxx (xxxxxxxxxxxxxxxx) xx x xxxxxxxxx xx xxxxxx.
732+
"(x.bbbbbbbbbbbb.xxx != "
733+
'"xxx:xxx:xxx::cccccccccccc:xxxxxxx-xxxx/xxxxxxxxxxx/xxxxxxxxxxxxxxxxx") && '
734+
)
735+
)
736+
]
737+
)
738+
712739
if __name__ == "__main__":
713740
for i in range(4, 8):
714741
cmd = (

0 commit comments

Comments
 (0)