Skip to content

Commit b3b0d75

Browse files
authored
gh-140253: Improve the syntax error from an ill-positioned double-star subpattern (#140254)
1 parent 76fea55 commit b3b0d75

File tree

5 files changed

+671
-514
lines changed

5 files changed

+671
-514
lines changed

Grammar/python.gram

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -626,6 +626,7 @@ mapping_pattern[pattern_ty]:
626626
CHECK(asdl_pattern_seq*, _PyPegen_get_patterns(p, items)),
627627
NULL,
628628
EXTRA) }
629+
| invalid_mapping_pattern
629630

630631
items_pattern[asdl_seq*]:
631632
| ','.key_value_pattern+
@@ -1490,6 +1491,10 @@ invalid_class_pattern:
14901491
PyPegen_first_item(a, pattern_ty),
14911492
PyPegen_last_item(a, pattern_ty),
14921493
"positional patterns follow keyword patterns") }
1494+
invalid_mapping_pattern:
1495+
| '{' (items_pattern ',')? rest=double_star_pattern ',' items_pattern ','? '}' { RAISE_SYNTAX_ERROR_KNOWN_LOCATION(
1496+
rest,
1497+
"double star pattern must be the last (right-most) subpattern in the mapping pattern") }
14931498
invalid_class_argument_pattern[asdl_pattern_seq*]:
14941499
| [positional_patterns ','] keyword_patterns ',' a=positional_patterns { a }
14951500
invalid_if_stmt:

Lib/test/test_exceptions.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,16 @@ def testSyntaxErrorOffset(self):
252252
check('[\nfile\nfor str(file)\nin\n[]\n]', 3, 5)
253253
check('[file for\n str(file) in []]', 2, 2)
254254
check("ages = {'Alice'=22, 'Bob'=23}", 1, 9)
255-
check('match ...:\n case {**rest, "key": value}:\n ...', 2, 19)
255+
check(dedent("""\
256+
match ...:
257+
case {**rest1, "after": after}:
258+
...
259+
"""), 2, 11)
260+
check(dedent("""\
261+
match ...:
262+
case {"before": before, **rest2, "after": after}:
263+
...
264+
"""), 2, 29)
256265
check("[a b c d e f]", 1, 2)
257266
check("for x yfff:", 1, 7)
258267
check("f(a for a in b, c)", 1, 3, 1, 15)

Lib/test/test_syntax.py

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -370,12 +370,6 @@
370370
Traceback (most recent call last):
371371
SyntaxError: invalid syntax
372372
373-
>>> match ...:
374-
... case {**rest, "key": value}:
375-
... ...
376-
Traceback (most recent call last):
377-
SyntaxError: invalid syntax
378-
379373
>>> match ...:
380374
... case {**_}:
381375
... ...
@@ -2240,7 +2234,7 @@
22402234
Traceback (most recent call last):
22412235
SyntaxError: invalid character '£' (U+00A3)
22422236
2243-
Invalid pattern matching constructs:
2237+
Invalid pattern matching constructs:
22442238
22452239
>>> match ...:
22462240
... case 42 as _:
@@ -2302,6 +2296,24 @@
23022296
Traceback (most recent call last):
23032297
SyntaxError: positional patterns follow keyword patterns
23042298
2299+
>>> match ...:
2300+
... case {**double_star, "spam": "eggs"}:
2301+
... ...
2302+
Traceback (most recent call last):
2303+
SyntaxError: double star pattern must be the last (right-most) subpattern in the mapping pattern
2304+
2305+
>>> match ...:
2306+
... case {"foo": 1, **double_star, "spam": "eggs"}:
2307+
... ...
2308+
Traceback (most recent call last):
2309+
SyntaxError: double star pattern must be the last (right-most) subpattern in the mapping pattern
2310+
2311+
>>> match ...:
2312+
... case {"spam": "eggs", "b": {**d, "ham": "bacon"}}:
2313+
... ...
2314+
Traceback (most recent call last):
2315+
SyntaxError: double star pattern must be the last (right-most) subpattern in the mapping pattern
2316+
23052317
Uses of the star operator which should fail:
23062318
23072319
A[:*b]
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Wrong placement of a double-star pattern inside a mapping pattern now throws a specialized syntax error.
2+
Contributed by Bartosz Sławecki in :gh:`140253`.

0 commit comments

Comments
 (0)