mirror of
https://github.com/davidhalter/parso.git
synced 2025-12-07 05:14:29 +08:00
Fix a few fstring error gatherings
This commit is contained in:
@@ -843,7 +843,7 @@ class _TryStmtRule(SyntaxRule):
|
||||
self.add_issue(default_except, message=self.message)
|
||||
|
||||
|
||||
@ErrorFinder.register_rule(type='string')
|
||||
@ErrorFinder.register_rule(type='fstring')
|
||||
class _FStringRule(SyntaxRule):
|
||||
_fstring_grammar = None
|
||||
message_empty = "f-string: empty expression not allowed" # f'{}'
|
||||
@@ -864,7 +864,25 @@ class _FStringRule(SyntaxRule):
|
||||
cls._fstring_grammar = parso.load_grammar(language='python-f-string')
|
||||
return cls._fstring_grammar
|
||||
|
||||
def _check_type(self, fstring_string):
|
||||
index = -1
|
||||
value = fstring_string.value
|
||||
while True:
|
||||
index = value.find('}', index + 1)
|
||||
if index == -1:
|
||||
break # No further } found, we're finished.
|
||||
elif index + 1 != len(value) and value[index + 1]:
|
||||
# It's }}, which is totally ok.
|
||||
index += 1
|
||||
else:
|
||||
self.add_issue(fstring_string, message=self.message_single_closing)
|
||||
|
||||
def is_issue(self, fstring):
|
||||
for fstring_content in fstring.children[1:-1]:
|
||||
if fstring_content.type == 'fstring_string':
|
||||
self._check_type(fstring_content)
|
||||
return
|
||||
print(fstring)
|
||||
if 'f' not in fstring.string_prefix.lower():
|
||||
return
|
||||
|
||||
|
||||
@@ -153,5 +153,5 @@ strings: (STRING | fstring)+
|
||||
fstring: FSTRING_START fstring_content* FSTRING_END
|
||||
fstring_content: FSTRING_STRING | fstring_expr
|
||||
fstring_conversion: '!' NAME
|
||||
fstring_expr: '{' testlist [ fstring_conversion ] [ fstring_format_spec ] '}'
|
||||
fstring_expr: '{' testlist_comp [ fstring_conversion ] [ fstring_format_spec ] '}'
|
||||
fstring_format_spec: ':' fstring_content*
|
||||
|
||||
@@ -166,7 +166,7 @@ def _create_token_collection(version_info):
|
||||
# Because of leftmost-then-longest match semantics, be sure to put the
|
||||
# longest operators first (e.g., if = came before ==, == would get
|
||||
# recognized as two instances of =).
|
||||
Operator = group(r"\*\*=?", r">>=?", r"<<=?", r"!=",
|
||||
Operator = group(r"\*\*=?", r">>=?", r"<<=?",
|
||||
r"//=?", r"->",
|
||||
r"[+\-*/%&@`|^=<>]=?",
|
||||
r"~")
|
||||
|
||||
@@ -141,7 +141,7 @@ FAILING_EXAMPLES = [
|
||||
|
||||
# f-strings
|
||||
'f"{}"',
|
||||
'f"{\\}"',
|
||||
r'f"{\}"',
|
||||
'f"{\'\\\'}"',
|
||||
'f"{#}"',
|
||||
"f'{1!b}'",
|
||||
|
||||
@@ -114,6 +114,20 @@ def _get_actual_exception(code):
|
||||
# Python 3.4/3.4 have a bit of a different warning than 3.5/3.6 in
|
||||
# certain places. But in others this error makes sense.
|
||||
return [wanted, "SyntaxError: can't use starred expression here"], line_nr
|
||||
elif wanted == 'SyntaxError: f-string: unterminated string':
|
||||
wanted = 'SyntaxError: EOL while scanning string literal'
|
||||
elif wanted == 'SyntaxError: f-string expression part cannot include a backslash':
|
||||
return [
|
||||
wanted,
|
||||
"SyntaxError: EOL while scanning string literal",
|
||||
"SyntaxError: unexpected character after line continuation character",
|
||||
], line_nr
|
||||
elif wanted == 'SyntaxError: f-string: empty expression not allowed':
|
||||
wanted = 'SyntaxError: invalid syntax'
|
||||
elif wanted == "SyntaxError: f-string expression part cannot include '#'":
|
||||
wanted = 'SyntaxError: invalid syntax'
|
||||
elif wanted == "SyntaxError: f-string: expecting '}'":
|
||||
wanted = 'SyntaxError: EOL while scanning string literal'
|
||||
return [wanted], line_nr
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user