From 68cc383d02f9083b2d5f663554c6d86394e83d8d Mon Sep 17 00:00:00 2001 From: Dave Halter Date: Sat, 26 Aug 2017 12:02:10 +0200 Subject: [PATCH] Do proper error recover for fstrings and fix another issue there. --- parso/python/errors.py | 6 ++++-- parso/python/fstring.py | 18 +++++++++++++----- test/failing_examples.py | 2 ++ 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/parso/python/errors.py b/parso/python/errors.py index 325c2ff..a091bbb 100644 --- a/parso/python/errors.py +++ b/parso/python/errors.py @@ -840,11 +840,11 @@ class _TryStmtRule(SyntaxRule): class _FStringRule(SyntaxRule): _fstring_grammar = None message_empty = "f-string: empty expression not allowed" # f'{}' - "f-string: single '}' is not allowed" # f'}' + message_single_closing = "f-string: single '}' is not allowed" # f'}' message_nested = "f-string: expressions nested too deeply" message_backslash = "f-string expression part cannot include a backslash" # f'{"\"}' or f'{"\\"}' message_comment = "f-string expression part cannot include '#'" # f'{#}' - "f-string: unterminated string" # f'{"}' + message_string = "f-string: unterminated string" # f'{"}' message_conversion = "f-string: invalid conversion character: expected 's', 'r', or 'a'" message_incomplete = "f-string: expecting '}'" # f'{' @@ -866,6 +866,8 @@ class _FStringRule(SyntaxRule): self._check_expression(child) elif child.type == 'error_node': self.add_issue(child, message=self.message_incomplete) + elif child.type == 'error_leaf': + self.add_issue(child, message=self.message_single_closing) def _check_python_expr(self, python_expr): value = python_expr.value diff --git a/parso/python/fstring.py b/parso/python/fstring.py index 7de632c..7596432 100644 --- a/parso/python/fstring.py +++ b/parso/python/fstring.py @@ -198,9 +198,17 @@ class Parser(parser.BaseParser): add_token_callback ) - dfa, state, (type_, nodes) = stack[1] - stack[0][2][1].append(ErrorNode(nodes)) - stack[1:] = [] - #error_leaf = tree.PythonErrorLeaf(tok_name[typ].lower(), value, start_pos, prefix) + if len(stack) == 1: + error_leaf = ErrorLeaf( + TokenNamespace.token_map[typ].lower(), + value, + start_pos, + prefix + ) + stack[0][2][1].append(error_leaf) + else: + dfa, state, (type_, nodes) = stack[1] + stack[0][2][1].append(ErrorNode(nodes)) + stack[1:] = [] - add_token_callback(typ, value, start_pos, prefix) + add_token_callback(typ, value, start_pos, prefix) diff --git a/test/failing_examples.py b/test/failing_examples.py index 7827db6..4426de0 100644 --- a/test/failing_examples.py +++ b/test/failing_examples.py @@ -147,6 +147,8 @@ FAILING_EXAMPLES = [ "f'{1!b}'", "f'{1:{5:{3}}}'", "f'{'", + "f'{'", + "f'}'", ] GLOBAL_NONLOCAL_ERROR = [