gh-140253: Improve the syntax error from an ill-positioned double-star subpattern (#140254)

This commit is contained in:
Bartosz Sławecki 2025-10-22 20:29:14 +02:00 committed by GitHub
parent 76fea5596c
commit b3b0d75069
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 922 additions and 765 deletions

View file

@ -626,6 +626,7 @@ mapping_pattern[pattern_ty]:
CHECK(asdl_pattern_seq*, _PyPegen_get_patterns(p, items)),
NULL,
EXTRA) }
| invalid_mapping_pattern
items_pattern[asdl_seq*]:
| ','.key_value_pattern+
@ -1490,6 +1491,10 @@ invalid_class_pattern:
PyPegen_first_item(a, pattern_ty),
PyPegen_last_item(a, pattern_ty),
"positional patterns follow keyword patterns") }
invalid_mapping_pattern:
| '{' (items_pattern ',')? rest=double_star_pattern ',' items_pattern ','? '}' { RAISE_SYNTAX_ERROR_KNOWN_LOCATION(
rest,
"double star pattern must be the last (right-most) subpattern in the mapping pattern") }
invalid_class_argument_pattern[asdl_pattern_seq*]:
| [positional_patterns ','] keyword_patterns ',' a=positional_patterns { a }
invalid_if_stmt:

View file

@ -252,7 +252,16 @@ class ExceptionTests(unittest.TestCase):
check('[\nfile\nfor str(file)\nin\n[]\n]', 3, 5)
check('[file for\n str(file) in []]', 2, 2)
check("ages = {'Alice'=22, 'Bob'=23}", 1, 9)
check('match ...:\n case {**rest, "key": value}:\n ...', 2, 19)
check(dedent("""\
match ...:
case {**rest1, "after": after}:
...
"""), 2, 11)
check(dedent("""\
match ...:
case {"before": before, **rest2, "after": after}:
...
"""), 2, 29)
check("[a b c d e f]", 1, 2)
check("for x yfff:", 1, 7)
check("f(a for a in b, c)", 1, 3, 1, 15)

View file

@ -370,12 +370,6 @@ SyntaxError: invalid syntax
Traceback (most recent call last):
SyntaxError: invalid syntax
>>> match ...:
... case {**rest, "key": value}:
... ...
Traceback (most recent call last):
SyntaxError: invalid syntax
>>> match ...:
... case {**_}:
... ...
@ -2240,7 +2234,7 @@ Corner-cases that used to crash:
Traceback (most recent call last):
SyntaxError: invalid character '£' (U+00A3)
Invalid pattern matching constructs:
Invalid pattern matching constructs:
>>> match ...:
... case 42 as _:
@ -2302,6 +2296,24 @@ Corner-cases that used to crash:
Traceback (most recent call last):
SyntaxError: positional patterns follow keyword patterns
>>> match ...:
... case {**double_star, "spam": "eggs"}:
... ...
Traceback (most recent call last):
SyntaxError: double star pattern must be the last (right-most) subpattern in the mapping pattern
>>> match ...:
... case {"foo": 1, **double_star, "spam": "eggs"}:
... ...
Traceback (most recent call last):
SyntaxError: double star pattern must be the last (right-most) subpattern in the mapping pattern
>>> match ...:
... case {"spam": "eggs", "b": {**d, "ham": "bacon"}}:
... ...
Traceback (most recent call last):
SyntaxError: double star pattern must be the last (right-most) subpattern in the mapping pattern
Uses of the star operator which should fail:
A[:*b]

View file

@ -0,0 +1,2 @@
Wrong placement of a double-star pattern inside a mapping pattern now throws a specialized syntax error.
Contributed by Bartosz Sławecki in :gh:`140253`.

1643
Parser/parser.c generated

File diff suppressed because it is too large Load diff