Skip to content

Commit 457ce60

Browse files
authored
bpo-44368: Ensure we don't raise incorrect custom syntax errors with soft keywords (GH-26630)
1 parent 878d7e4 commit 457ce60

File tree

3 files changed

+31
-5
lines changed

3 files changed

+31
-5
lines changed

Lib/test/test_exceptions.py

+1
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,7 @@ def testSyntaxErrorOffset(self):
215215
check('[\nfile\nfor str(file)\nin\n[]\n]', 3, 5)
216216
check('[file for\n str(file) in []]', 2, 2)
217217
check("ages = {'Alice'=22, 'Bob'=23}", 1, 16)
218+
check('match ...:\n case {**rest, "key": value}:\n ...', 2, 19)
218219

219220
# Errors thrown by compile.c
220221
check('class foo:return 1', 1, 11)

Lib/test/test_syntax.py

+19-1
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,7 @@
267267
SyntaxError: invalid syntax. Perhaps you forgot a comma?
268268
269269
# Make sure soft keywords constructs don't raise specialized
270-
# errors regarding missing commas
270+
# errors regarding missing commas or other spezialiced errors
271271
272272
>>> match x:
273273
... y = 3
@@ -280,6 +280,24 @@
280280
Traceback (most recent call last):
281281
SyntaxError: invalid syntax
282282
283+
>>> match x:
284+
... case $:
285+
... ...
286+
Traceback (most recent call last):
287+
SyntaxError: invalid syntax
288+
289+
>>> match ...:
290+
... case {**rest, "key": value}:
291+
... ...
292+
Traceback (most recent call last):
293+
SyntaxError: invalid syntax
294+
295+
>>> match ...:
296+
... case {**_}:
297+
... ...
298+
Traceback (most recent call last):
299+
SyntaxError: invalid syntax
300+
283301
From compiler_complex_args():
284302
285303
>>> def f(None=1):

Parser/pegen.c

+11-4
Original file line numberDiff line numberDiff line change
@@ -936,10 +936,9 @@ _PyPegen_get_last_nonnwhitespace_token(Parser *p)
936936
return token;
937937
}
938938

939-
expr_ty
940-
_PyPegen_name_token(Parser *p)
939+
static expr_ty
940+
_PyPegen_name_from_token(Parser *p, Token* t)
941941
{
942-
Token *t = _PyPegen_expect_token(p, NAME);
943942
if (t == NULL) {
944943
return NULL;
945944
}
@@ -957,6 +956,14 @@ _PyPegen_name_token(Parser *p)
957956
t->end_col_offset, p->arena);
958957
}
959958

959+
960+
expr_ty
961+
_PyPegen_name_token(Parser *p)
962+
{
963+
Token *t = _PyPegen_expect_token(p, NAME);
964+
return _PyPegen_name_from_token(p, t);
965+
}
966+
960967
void *
961968
_PyPegen_string_token(Parser *p)
962969
{
@@ -974,7 +981,7 @@ expr_ty _PyPegen_soft_keyword_token(Parser *p) {
974981
PyBytes_AsStringAndSize(t->bytes, &the_token, &size);
975982
for (char **keyword = p->soft_keywords; *keyword != NULL; keyword++) {
976983
if (strncmp(*keyword, the_token, size) == 0) {
977-
return _PyPegen_name_token(p);
984+
return _PyPegen_name_from_token(p, t);
978985
}
979986
}
980987
return NULL;

0 commit comments

Comments
 (0)