bpo-43017: Improve error message for unparenthesised tuples in comprehensions (GH24314)

This commit is contained in:
Pablo Galindo 2021-01-31 22:52:56 +00:00 committed by GitHub
parent 4090151816
commit 835f14ff8e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 490 additions and 398 deletions

View File

@ -507,7 +507,7 @@ strings[expr_ty] (memo): a=STRING+ { _PyPegen_concatenate_strings(p, a) }
list[expr_ty]: list[expr_ty]:
| '[' a=[star_named_expressions] ']' { _Py_List(a, Load, EXTRA) } | '[' a=[star_named_expressions] ']' { _Py_List(a, Load, EXTRA) }
listcomp[expr_ty]: listcomp[expr_ty]:
| '[' a=named_expression ~ b=for_if_clauses ']' { _Py_ListComp(a, b, EXTRA) } | '[' a=named_expression b=for_if_clauses ']' { _Py_ListComp(a, b, EXTRA) }
| invalid_comprehension | invalid_comprehension
tuple[expr_ty]: tuple[expr_ty]:
| '(' a=[y=star_named_expression ',' z=[star_named_expressions] { _PyPegen_seq_insert_in_front(p, y, z) } ] ')' { | '(' a=[y=star_named_expression ',' z=[star_named_expressions] { _PyPegen_seq_insert_in_front(p, y, z) } ] ')' {
@ -516,11 +516,11 @@ group[expr_ty]:
| '(' a=(yield_expr | named_expression) ')' { a } | '(' a=(yield_expr | named_expression) ')' { a }
| invalid_group | invalid_group
genexp[expr_ty]: genexp[expr_ty]:
| '(' a=named_expression ~ b=for_if_clauses ')' { _Py_GeneratorExp(a, b, EXTRA) } | '(' a=named_expression b=for_if_clauses ')' { _Py_GeneratorExp(a, b, EXTRA) }
| invalid_comprehension | invalid_comprehension
set[expr_ty]: '{' a=star_named_expressions '}' { _Py_Set(a, EXTRA) } set[expr_ty]: '{' a=star_named_expressions '}' { _Py_Set(a, EXTRA) }
setcomp[expr_ty]: setcomp[expr_ty]:
| '{' a=named_expression ~ b=for_if_clauses '}' { _Py_SetComp(a, b, EXTRA) } | '{' a=named_expression b=for_if_clauses '}' { _Py_SetComp(a, b, EXTRA) }
| invalid_comprehension | invalid_comprehension
dict[expr_ty]: dict[expr_ty]:
| '{' a=[double_starred_kvpairs] '}' { | '{' a=[double_starred_kvpairs] '}' {
@ -692,6 +692,8 @@ invalid_primary:
invalid_comprehension: invalid_comprehension:
| ('[' | '(' | '{') a=starred_expression for_if_clauses { | ('[' | '(' | '{') a=starred_expression for_if_clauses {
RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "iterable unpacking cannot be used in comprehension") } RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "iterable unpacking cannot be used in comprehension") }
| ('[' | '{') a=star_named_expression ',' [star_named_expressions] {
RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "did you forget parentheses around the comprehension target?") }
invalid_dict_comprehension: invalid_dict_comprehension:
| '{' a='**' bitwise_or for_if_clauses '}' { | '{' a='**' bitwise_or for_if_clauses '}' {
RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "dict unpacking cannot be used in dict comprehension") } RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "dict unpacking cannot be used in dict comprehension") }

View File

@ -101,7 +101,8 @@ class NamedExpressionInvalidTest(unittest.TestCase):
def test_named_expression_invalid_17(self): def test_named_expression_invalid_17(self):
code = "[i := 0, j := 1 for i, j in [(1, 2), (3, 4)]]" code = "[i := 0, j := 1 for i, j in [(1, 2), (3, 4)]]"
with self.assertRaisesRegex(SyntaxError, "invalid syntax"): with self.assertRaisesRegex(SyntaxError,
"did you forget parentheses around the comprehension target?"):
exec(code, {}, {}) exec(code, {}, {})
def test_named_expression_invalid_in_class_body(self): def test_named_expression_invalid_in_class_body(self):

View File

@ -235,6 +235,21 @@ SyntaxError: invalid syntax
Traceback (most recent call last): Traceback (most recent call last):
SyntaxError: invalid syntax SyntaxError: invalid syntax
Comprehensions creating tuples without parentheses
should produce a specialized error message:
>>> [x,y for x,y in range(100)]
Traceback (most recent call last):
SyntaxError: did you forget parentheses around the comprehension target?
>>> {x,y for x,y in range(100)}
Traceback (most recent call last):
SyntaxError: did you forget parentheses around the comprehension target?
>>> {x,y: None for x,y in range(100)}
Traceback (most recent call last):
SyntaxError: did you forget parentheses around the comprehension target?
From compiler_complex_args(): From compiler_complex_args():
>>> def f(None=1): >>> def f(None=1):

View File

@ -0,0 +1,2 @@
Improve error message in the parser when using un-parenthesised tuples in
comprehensions. Patch by Pablo Galindo.

File diff suppressed because it is too large Load Diff