Skip to content

Commit d00aaf3

Browse files
bpo-40715: Reject dict unpacking on dict comprehensions (GH-20292)
Co-authored-by: Lysandros Nikolaou <[email protected]> Co-authored-by: Pablo Galindo <[email protected]> (cherry picked from commit b8a65ec) Co-authored-by: Batuhan Taskaya <[email protected]>
1 parent 7178b1b commit d00aaf3

File tree

3 files changed

+308
-208
lines changed

3 files changed

+308
-208
lines changed

Grammar/python.gram

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -499,14 +499,16 @@ setcomp[expr_ty]:
499499
| '{' a=expression b=for_if_clauses '}' { _Py_SetComp(a, b, EXTRA) }
500500
| invalid_comprehension
501501
dict[expr_ty]:
502-
| '{' a=[kvpairs] '}' { _Py_Dict(CHECK(_PyPegen_get_keys(p, a)),
503-
CHECK(_PyPegen_get_values(p, a)), EXTRA) }
502+
| '{' a=[double_starred_kvpairs] '}' {
503+
_Py_Dict(CHECK(_PyPegen_get_keys(p, a)), CHECK(_PyPegen_get_values(p, a)), EXTRA) }
504504
dictcomp[expr_ty]:
505505
| '{' a=kvpair b=for_if_clauses '}' { _Py_DictComp(a->key, a->value, b, EXTRA) }
506-
kvpairs[asdl_seq*]: a=','.kvpair+ [','] { a }
507-
kvpair[KeyValuePair*]:
506+
| invalid_dict_comprehension
507+
double_starred_kvpairs[asdl_seq*]: a=','.double_starred_kvpair+ [','] { a }
508+
double_starred_kvpair[KeyValuePair*]:
508509
| '**' a=bitwise_or { _PyPegen_key_value_pair(p, NULL, a) }
509-
| a=expression ':' b=expression { _PyPegen_key_value_pair(p, a, b) }
510+
| kvpair
511+
kvpair[KeyValuePair*]: a=expression ':' b=expression { _PyPegen_key_value_pair(p, a, b) }
510512
for_if_clauses[asdl_seq*]:
511513
| for_if_clause+
512514
for_if_clause[comprehension_ty]:
@@ -657,6 +659,9 @@ invalid_block:
657659
invalid_comprehension:
658660
| ('[' | '(' | '{') a=starred_expression for_if_clauses {
659661
RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "iterable unpacking cannot be used in comprehension") }
662+
invalid_dict_comprehension:
663+
| '{' a='**' bitwise_or for_if_clauses '}' {
664+
RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "dict unpacking cannot be used in dict comprehension") }
660665
invalid_parameters:
661666
| param_no_default* (slash_with_default | param_with_default+) param_no_default {
662667
RAISE_SYNTAX_ERROR("non-default argument follows default argument") }

Lib/test/test_unpack_ex.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,11 @@
158158
...
159159
SyntaxError: iterable unpacking cannot be used in comprehension
160160
161+
>>> {**{} for a in [1]}
162+
Traceback (most recent call last):
163+
...
164+
SyntaxError: dict unpacking cannot be used in dict comprehension
165+
161166
# Pegen is better here.
162167
# Generator expression in function arguments
163168

0 commit comments

Comments
 (0)