]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-133194: Add `CHECK_VERSION` to new PEP758 grammar (#133195)
authorsobolevn <mail@sobolevn.me>
Wed, 30 Apr 2025 10:39:26 +0000 (13:39 +0300)
committerGitHub <noreply@github.com>
Wed, 30 Apr 2025 10:39:26 +0000 (13:39 +0300)
Grammar/python.gram
Lib/test/test_ast/test_ast.py
Misc/NEWS.d/next/Core_and_Builtins/2025-04-30-13-09-20.gh-issue-133194.25_G5c.rst [new file with mode: 0644]
Parser/parser.c

index 940063e5c7ba1e0b56211b2e4ee92edc09866211..fc9912fd57313bc853bed62752f1d17354e2999d 100644 (file)
@@ -442,7 +442,11 @@ try_stmt[stmt_ty]:
 except_block[excepthandler_ty]:
     | invalid_except_stmt_indent
     | 'except' e=expressions ':' b=block {
-        _PyAST_ExceptHandler(e,  NULL, b, EXTRA) }
+        CHECK_VERSION(
+            excepthandler_ty, 
+            14, 
+            "except expressions without parentheses", 
+            _PyAST_ExceptHandler(e,  NULL, b, EXTRA)) }
     | 'except' e=expression 'as' t=NAME  ':' b=block {
         _PyAST_ExceptHandler(e, ((expr_ty) t)->v.Name.id, b, EXTRA) }
     | 'except' ':' b=block { _PyAST_ExceptHandler(NULL, NULL, b, EXTRA) }
@@ -450,7 +454,11 @@ except_block[excepthandler_ty]:
 except_star_block[excepthandler_ty]:
     | invalid_except_star_stmt_indent
     | 'except' '*' e=expressions ':' b=block {
-        _PyAST_ExceptHandler(e, NULL, b, EXTRA) }
+        CHECK_VERSION(
+            excepthandler_ty, 
+            14, 
+            "except expressions without parentheses", 
+            _PyAST_ExceptHandler(e,  NULL, b, EXTRA)) }
     | 'except' '*' e=expression 'as' t=NAME ':' b=block {
         _PyAST_ExceptHandler(e, ((expr_ty) t)->v.Name.id, b, EXTRA) }
     | invalid_except_star_stmt
index eeac7c21eda98faa44c55453a6a4d98bfb82d81b..2a1b47345abd3956a9c5c2455344e34f374412b8 100644 (file)
@@ -675,6 +675,28 @@ class AST_Tests(unittest.TestCase):
         with self.assertRaises(SyntaxError):
             ast.parse('(x := 0)', feature_version=(3, 7))
 
+    def test_pep758_except_without_parens(self):
+        code = textwrap.dedent("""
+            try:
+                ...
+            except ValueError, TypeError:
+                ...
+        """)
+        ast.parse(code, feature_version=(3, 14))
+        with self.assertRaises(SyntaxError):
+            ast.parse(code, feature_version=(3, 13))
+
+    def test_pep758_except_star_without_parens(self):
+        code = textwrap.dedent("""
+            try:
+                ...
+            except* ValueError, TypeError:
+                ...
+        """)
+        ast.parse(code, feature_version=(3, 14))
+        with self.assertRaises(SyntaxError):
+            ast.parse(code, feature_version=(3, 13))
+
     def test_conditional_context_managers_parse_with_low_feature_version(self):
         # regression test for gh-115881
         ast.parse('with (x() if y else z()): ...', feature_version=(3, 8))
diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-04-30-13-09-20.gh-issue-133194.25_G5c.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-04-30-13-09-20.gh-issue-133194.25_G5c.rst
new file mode 100644 (file)
index 0000000..fa597db
--- /dev/null
@@ -0,0 +1,2 @@
+:func:`ast.parse` will no longer parse new :pep:`758` syntax with older
+*feature_version* passed.
index ff5d8baf9204b62a2cc76aa5d02ac5c3418d3738..03eda566f02226968fb4e9bd7e12648dcc2c8da5 100644 (file)
@@ -7140,7 +7140,7 @@ except_block_rule(Parser *p)
             UNUSED(_end_lineno); // Only used by EXTRA macro
             int _end_col_offset = _token->end_col_offset;
             UNUSED(_end_col_offset); // Only used by EXTRA macro
-            _res = _PyAST_ExceptHandler ( e , NULL , b , EXTRA );
+            _res = CHECK_VERSION ( excepthandler_ty , 14 , "except expressions without parentheses" , _PyAST_ExceptHandler ( e , NULL , b , EXTRA ) );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
                 p->level--;
@@ -7342,7 +7342,7 @@ except_star_block_rule(Parser *p)
             UNUSED(_end_lineno); // Only used by EXTRA macro
             int _end_col_offset = _token->end_col_offset;
             UNUSED(_end_col_offset); // Only used by EXTRA macro
-            _res = _PyAST_ExceptHandler ( e , NULL , b , EXTRA );
+            _res = CHECK_VERSION ( excepthandler_ty , 14 , "except expressions without parentheses" , _PyAST_ExceptHandler ( e , NULL , b , EXTRA ) );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
                 p->level--;