From 457ce60fc70f1c9290023f46fb82b6a490dff32e Mon Sep 17 00:00:00 2001 From: Pablo Galindo Date: Wed, 9 Jun 2021 22:20:01 +0100 Subject: bpo-44368: Ensure we don't raise incorrect custom syntax errors with soft keywords (GH-26630) --- Lib/test/test_exceptions.py | 1 + Lib/test/test_syntax.py | 20 +++++++++++++++++++- Parser/pegen.c | 15 +++++++++++---- 3 files changed, 31 insertions(+), 5 deletions(-) diff --git a/Lib/test/test_exceptions.py b/Lib/test/test_exceptions.py index b242c08..9cb5466 100644 --- a/Lib/test/test_exceptions.py +++ b/Lib/test/test_exceptions.py @@ -215,6 +215,7 @@ 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, 16) + check('match ...:\n case {**rest, "key": value}:\n ...', 2, 19) # Errors thrown by compile.c check('class foo:return 1', 1, 11) diff --git a/Lib/test/test_syntax.py b/Lib/test/test_syntax.py index 5d3ce4c..72e4ab1 100644 --- a/Lib/test/test_syntax.py +++ b/Lib/test/test_syntax.py @@ -267,7 +267,7 @@ Traceback (most recent call last): SyntaxError: invalid syntax. Perhaps you forgot a comma? # Make sure soft keywords constructs don't raise specialized -# errors regarding missing commas +# errors regarding missing commas or other spezialiced errors >>> match x: ... y = 3 @@ -280,6 +280,24 @@ SyntaxError: invalid syntax Traceback (most recent call last): SyntaxError: invalid syntax +>>> match x: +... case $: +... ... +Traceback (most recent call last): +SyntaxError: invalid syntax + +>>> match ...: +... case {**rest, "key": value}: +... ... +Traceback (most recent call last): +SyntaxError: invalid syntax + +>>> match ...: +... case {**_}: +... ... +Traceback (most recent call last): +SyntaxError: invalid syntax + From compiler_complex_args(): >>> def f(None=1): diff --git a/Parser/pegen.c b/Parser/pegen.c index e651819..82f840c 100644 --- a/Parser/pegen.c +++ b/Parser/pegen.c @@ -936,10 +936,9 @@ _PyPegen_get_last_nonnwhitespace_token(Parser *p) return token; } -expr_ty -_PyPegen_name_token(Parser *p) +static expr_ty +_PyPegen_name_from_token(Parser *p, Token* t) { - Token *t = _PyPegen_expect_token(p, NAME); if (t == NULL) { return NULL; } @@ -957,6 +956,14 @@ _PyPegen_name_token(Parser *p) t->end_col_offset, p->arena); } + +expr_ty +_PyPegen_name_token(Parser *p) +{ + Token *t = _PyPegen_expect_token(p, NAME); + return _PyPegen_name_from_token(p, t); +} + void * _PyPegen_string_token(Parser *p) { @@ -974,7 +981,7 @@ expr_ty _PyPegen_soft_keyword_token(Parser *p) { PyBytes_AsStringAndSize(t->bytes, &the_token, &size); for (char **keyword = p->soft_keywords; *keyword != NULL; keyword++) { if (strncmp(*keyword, the_token, size) == 0) { - return _PyPegen_name_token(p); + return _PyPegen_name_from_token(p, t); } } return NULL; -- cgit v0.12