diff --git a/Grammar/python.gram b/Grammar/python.gram index f3ef990923eec3..bf4f70d9e34e80 100644 --- a/Grammar/python.gram +++ b/Grammar/python.gram @@ -1500,7 +1500,10 @@ invalid_kvpair: invalid_starred_expression_unpacking: | a='*' expression '=' b=expression { RAISE_SYNTAX_ERROR_KNOWN_RANGE(a, b, "cannot assign to iterable argument unpacking") } invalid_starred_expression: - | '*' { RAISE_SYNTAX_ERROR("Invalid star expression") } + | a='*' { + RAISE_SYNTAX_ERROR_KNOWN_LOCATION( + a, + "invalid star expression") } invalid_fstring_replacement_field: | '{' a='=' { RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "f-string: valid expression required before '='") } diff --git a/Lib/test/test_syntax.py b/Lib/test/test_syntax.py index 0ee17849e28121..c532ceb5cc7f9e 100644 --- a/Lib/test/test_syntax.py +++ b/Lib/test/test_syntax.py @@ -2320,22 +2320,22 @@ >>> A[*(1:2)] Traceback (most recent call last): ... - SyntaxError: Invalid star expression + SyntaxError: invalid star expression >>> A[*(1:2)] = 1 Traceback (most recent call last): ... - SyntaxError: Invalid star expression + SyntaxError: invalid star expression >>> del A[*(1:2)] Traceback (most recent call last): ... - SyntaxError: Invalid star expression + SyntaxError: invalid star expression A[*:] and A[:*] >>> A[*:] Traceback (most recent call last): ... - SyntaxError: Invalid star expression + SyntaxError: invalid star expression >>> A[:*] Traceback (most recent call last): ... @@ -2346,7 +2346,7 @@ >>> A[*] Traceback (most recent call last): ... - SyntaxError: Invalid star expression + SyntaxError: invalid star expression A[**] @@ -2623,23 +2623,23 @@ def f(x: *b) >>> f(**x, *) Traceback (most recent call last): - SyntaxError: Invalid star expression + SyntaxError: invalid star expression >>> f(x, *:) Traceback (most recent call last): - SyntaxError: Invalid star expression + SyntaxError: invalid star expression >>> f(x, *) Traceback (most recent call last): - SyntaxError: Invalid star expression + SyntaxError: invalid star expression >>> f(x = 5, *) Traceback (most recent call last): - SyntaxError: Invalid star expression + SyntaxError: invalid star expression >>> f(x = 5, *:) Traceback (most recent call last): - SyntaxError: Invalid star expression + SyntaxError: invalid star expression """ import re @@ -3146,6 +3146,14 @@ def test_multiline_compiler_error_points_to_the_end(self): lineno=3 ) + def test_carret_location_invalid_star_expr(self): + with self.assertRaises(SyntaxError) as cm: + compile("A[*]", "", "exec") + e = cm.exception + self.assertEqual(e.msg, "invalid star expression") + self.assertEqual(e.text.strip(), "A[*]") + self.assertEqual(e.offset, 3) + @support.cpython_only def test_syntax_error_on_deeply_nested_blocks(self): # This raises a SyntaxError, it used to raise a SystemError. Context diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-05-05-19-42-11.gh-issue-133357.moEEdA.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-05-05-19-42-11.gh-issue-133357.moEEdA.rst new file mode 100644 index 00000000000000..7b79c3fc8d9f40 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2025-05-05-19-42-11.gh-issue-133357.moEEdA.rst @@ -0,0 +1,2 @@ +Fix the location of the :exc:`SyntaxError` carret on invalid starred +expressions. diff --git a/Parser/parser.c b/Parser/parser.c index 509fac7df6e371..764b44fb0b58c2 100644 --- a/Parser/parser.c +++ b/Parser/parser.c @@ -26067,13 +26067,13 @@ invalid_starred_expression_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> invalid_starred_expression[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*'")); - Token * _literal; + Token * a; if ( - (_literal = _PyPegen_expect_token(p, 16)) // token='*' + (a = _PyPegen_expect_token(p, 16)) // token='*' ) { D(fprintf(stderr, "%*c+ invalid_starred_expression[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*'")); - _res = RAISE_SYNTAX_ERROR ( "Invalid star expression" ); + _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "invalid star expression" ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; p->level--;