diff --git a/CHANGES.md b/CHANGES.md index d9800a6979c..63c7a2cf30d 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -10,6 +10,7 @@ `.gitignore` rules like `git` does) (#2225) - Restored compatibility with Click 8.0 on Python 3.6 when LANG=C used (#2227) - Add extra uvloop install + import support if in python env (#2258) +- Fix --experimental-string-processing crash when matching parens are not found (#2283) ### _Blackd_ diff --git a/src/black/trans.py b/src/black/trans.py index 7ecc31d6d31..169b675be3d 100644 --- a/src/black/trans.py +++ b/src/black/trans.py @@ -25,7 +25,7 @@ from black.mode import Feature from black.nodes import syms, replace_child, parent_type from black.nodes import is_empty_par, is_empty_lpar, is_empty_rpar -from black.nodes import CLOSING_BRACKETS, STANDALONE_COMMENT +from black.nodes import OPENING_BRACKETS, CLOSING_BRACKETS, STANDALONE_COMMENT from black.lines import Line, append_leaves from black.brackets import BracketMatchError from black.comments import contains_pragma_comment @@ -1398,6 +1398,11 @@ class StringParenWrapper(CustomSplitMapMixin, BaseStringSplitter): def do_splitter_match(self, line: Line) -> TMatchResult: LL = line.leaves + if line.leaves[-1].type in OPENING_BRACKETS: + return TErr( + "Cannot wrap parens around a line that ends in an opening bracket." + ) + string_idx = ( self._return_match(LL) or self._else_match(LL) @@ -1665,9 +1670,10 @@ def do_transform(self, line: Line, string_idx: int) -> Iterator[TResult[Line]]: right_leaves.pop() if old_parens_exist: - assert ( - right_leaves and right_leaves[-1].type == token.RPAR - ), "Apparently, old parentheses do NOT exist?!" + assert right_leaves and right_leaves[-1].type == token.RPAR, ( + "Apparently, old parentheses do NOT exist?!" + f" (left_leaves={left_leaves}, right_leaves={right_leaves})" + ) old_rpar_leaf = right_leaves.pop() append_leaves(string_line, line, right_leaves) diff --git a/tests/data/long_strings__regression.py b/tests/data/long_strings__regression.py index 2e7f2483b63..231d88651b6 100644 --- a/tests/data/long_strings__regression.py +++ b/tests/data/long_strings__regression.py @@ -396,6 +396,16 @@ def xxxxxxx_xxxxxx(xxxx): " it has now" ) + +def _legacy_listen_examples(): + text += ( + " \"listen for the '%(event_name)s' event\"\n" + "\n # ... (event logic logic logic) ...\n" + % { + "since": since, + } + ) + # output @@ -886,3 +896,13 @@ def xxxxxxx_xxxxxx(xxxx): " it goes over 88 characters which" " it has now" ) + + +def _legacy_listen_examples(): + text += ( + " \"listen for the '%(event_name)s' event\"\n" + "\n # ... (event logic logic logic) ...\n" + % { + "since": since, + } + )