Add issue "f-string: expecting }".

This commit is contained in:
Dave Halter
2017-08-26 11:53:59 +02:00
parent 296ecc6728
commit 1893f77e15
4 changed files with 20 additions and 8 deletions

View File

@@ -845,9 +845,8 @@ class _FStringRule(SyntaxRule):
message_backslash = "f-string expression part cannot include a backslash" # f'{"\"}' or f'{"\\"}' message_backslash = "f-string expression part cannot include a backslash" # f'{"\"}' or f'{"\\"}'
message_comment = "f-string expression part cannot include '#'" # f'{#}' message_comment = "f-string expression part cannot include '#'" # f'{#}'
"f-string: unterminated string" # f'{"}' "f-string: unterminated string" # f'{"}'
"f-string: mismatched '(', '{', or '['"
message_conversion = "f-string: invalid conversion character: expected 's', 'r', or 'a'" message_conversion = "f-string: invalid conversion character: expected 's', 'r', or 'a'"
"f-string: expecting '}'" # f'{' message_incomplete = "f-string: expecting '}'" # f'{'
@classmethod @classmethod
def _load_grammar(cls): def _load_grammar(cls):
@@ -865,6 +864,8 @@ class _FStringRule(SyntaxRule):
for child in parsed.children: for child in parsed.children:
if child.type == 'expression': if child.type == 'expression':
self._check_expression(child) self._check_expression(child)
elif child.type == 'error_node':
self.add_issue(child, message=self.message_incomplete)
def _check_python_expr(self, python_expr): def _check_python_expr(self, python_expr):
value = python_expr.value value = python_expr.value

View File

@@ -5,7 +5,7 @@ from parso.utils import split_lines
from parso.python.tokenize import Token from parso.python.tokenize import Token
from parso.python import token from parso.python import token
from parso import parser from parso import parser
from parso.tree import TypedLeaf from parso.tree import TypedLeaf, ErrorNode, ErrorLeaf
version36 = PythonVersionInfo(3, 6) version36 = PythonVersionInfo(3, 6)
@@ -189,3 +189,18 @@ class Parser(parser.BaseParser):
# TODO this is so ugly. # TODO this is so ugly.
leaf_type = TokenNamespace.token_map[type].lower() leaf_type = TokenNamespace.token_map[type].lower()
return TypedLeaf(leaf_type, value, start_pos, prefix) return TypedLeaf(leaf_type, value, start_pos, prefix)
def error_recovery(self, pgen_grammar, stack, arcs, typ, value, start_pos, prefix,
add_token_callback):
if not self._error_recovery:
return super(Parser, self).error_recovery(
pgen_grammar, stack, arcs, typ, value, start_pos, prefix,
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)
add_token_callback(typ, value, start_pos, prefix)

View File

@@ -135,11 +135,6 @@ class Parser(BaseParser):
def error_recovery(self, pgen_grammar, stack, arcs, typ, value, start_pos, prefix, def error_recovery(self, pgen_grammar, stack, arcs, typ, value, start_pos, prefix,
add_token_callback): add_token_callback):
"""
This parser is written in a dynamic way, meaning that this parser
allows using different grammars (even non-Python). However, error
recovery is purely written for Python.
"""
def get_symbol_and_nodes(stack): def get_symbol_and_nodes(stack):
for dfa, state, (type_, nodes) in stack: for dfa, state, (type_, nodes) in stack:
symbol = pgen_grammar.number2symbol[type_] symbol = pgen_grammar.number2symbol[type_]

View File

@@ -146,6 +146,7 @@ FAILING_EXAMPLES = [
'f"{#}"', 'f"{#}"',
"f'{1!b}'", "f'{1!b}'",
"f'{1:{5:{3}}}'", "f'{1:{5:{3}}}'",
"f'{'",
] ]
GLOBAL_NONLOCAL_ERROR = [ GLOBAL_NONLOCAL_ERROR = [