https://github.com/python/cpython/commit/806c997f55a5460c3dcabc022dcf275220b3d46e
commit: 806c997f55a5460c3dcabc022dcf275220b3d46e
branch: main
author: Jeff Epler <[email protected]>
committer: JelleZijlstra <[email protected]>
date: 2026-05-18T11:20:49-07:00
summary:

gh-140344: ast: Add deprecation warnings (#140345)

These were all deprecated in 3.9 (bace59d8b8) but without
a runtime deprecation warning. Add it now, so that these
items can be removed in 3.21 per PEP 387.

Co-authored-by: Jelle Zijlstra <[email protected]>

files:
A Doc/deprecations/pending-removal-in-3.21.rst
A Misc/NEWS.d/next/Library/2025-10-20-09-12-18.gh-issue-140344.WjbYg-.rst
M Doc/deprecations/index.rst
M Doc/whatsnew/3.16.rst
M Lib/ast.py
M Lib/test/test_ast/test_ast.py

diff --git a/Doc/deprecations/index.rst b/Doc/deprecations/index.rst
index eedcd2e9c9dd42..50e1b126fd1346 100644
--- a/Doc/deprecations/index.rst
+++ b/Doc/deprecations/index.rst
@@ -13,6 +13,8 @@ Deprecations
 
 .. include:: pending-removal-in-3.20.rst
 
+.. include:: pending-removal-in-3.21.rst
+
 .. include:: pending-removal-in-future.rst
 
 .. include:: soft-deprecations.rst
diff --git a/Doc/deprecations/pending-removal-in-3.21.rst 
b/Doc/deprecations/pending-removal-in-3.21.rst
new file mode 100644
index 00000000000000..5d0c56612094ff
--- /dev/null
+++ b/Doc/deprecations/pending-removal-in-3.21.rst
@@ -0,0 +1,10 @@
+Pending removal in Python 3.21
+------------------------------
+
+* :mod:`ast`:
+
+  * Classes ``slice``, ``Index``, ``ExtSlice``, ``Suite``, ``Param``,
+    ``AugLoad`` and ``AugStore``, will be removed in Python 3.21. These types
+    are not generated by the parser or accepted by the code generator.
+  * The ``dims`` property of ``ast.Tuple`` will be removed in Python 3.21. Use
+    the ``ast.Tuple.elts`` property instead.
diff --git a/Doc/whatsnew/3.16.rst b/Doc/whatsnew/3.16.rst
index 9383ce5665993e..2e5342e4f02053 100644
--- a/Doc/whatsnew/3.16.rst
+++ b/Doc/whatsnew/3.16.rst
@@ -184,9 +184,16 @@ tarfile
 Deprecated
 ==========
 
-* module_name:
-  TODO
-
+* :mod:`ast`:
+
+  * Classes ``slice``, ``Index``, ``ExtSlice``, ``Suite``, ``Param``,
+    ``AugLoad`` and ``AugStore``, deprecated since Python 3.9, are no longer
+    imported by ``from ast import *`` and issue a deprecation warning on
+    use. The classes are slated for removal in Python 3.21. These types are not
+    generated by the parser or accepted by the code generator.
+  * The ``dims`` property of ``ast.Tuple`` objects, deprecated since Python
+    3.9, now issues a deprecation warning on use. This property is slated for
+    removal in 3.21. Use ``ast.Tuple.elts`` instead.
 
 .. Add deprecations above alphabetically, not here at the end.
 
diff --git a/Lib/ast.py b/Lib/ast.py
index 4f88a554344cc9..f445b32040e5fb 100644
--- a/Lib/ast.py
+++ b/Lib/ast.py
@@ -21,7 +21,7 @@
 :license: Python License.
 """
 from _ast import *
-
+lazy import warnings
 
 def parse(source, filename='<unknown>', mode='exec', *,
           type_comments=False, feature_version=None, optimize=-1, module=None):
@@ -630,9 +630,11 @@ def __new__(cls, dims=(), **kwargs):
 
     def _dims_getter(self):
         """Deprecated. Use elts instead."""
+        warnings._deprecated(f"ast.Tuple.dims", remove=(3, 21))
         return self.elts
 
     def _dims_setter(self, value):
+        warnings._deprecated(f"ast.Tuple.dims", remove=(3, 21))
         self.elts = value
 
     Tuple.dims = property(_dims_getter, _dims_setter)
@@ -714,5 +716,23 @@ def main(args=None):
                color=can_colorize(file=sys.stdout),
                indent=args.indent, show_empty=args.show_empty))
 
+_deprecated = {
+        'slice': globals().pop("slice"),
+        'Index': globals().pop("Index"),
+        'ExtSlice': globals().pop("ExtSlice"),
+        'Suite': globals().pop("Suite"),
+        'AugLoad': globals().pop("AugLoad"),
+        'AugStore': globals().pop("AugStore"),
+        'Param': globals().pop("Param")
+}
+
+def __getattr__(attr):
+    try:
+        val = _deprecated[attr]
+    except KeyError:
+        raise AttributeError(f"module 'ast' has no attribute {attr!r}") from 
None
+    warnings._deprecated(f"ast.{attr}", remove=(3, 21))
+    return val
+
 if __name__ == '__main__':
     main()
diff --git a/Lib/test/test_ast/test_ast.py b/Lib/test/test_ast/test_ast.py
index af8b334da03e70..0112c9163fd0cd 100644
--- a/Lib/test/test_ast/test_ast.py
+++ b/Lib/test/test_ast/test_ast.py
@@ -523,6 +523,12 @@ def test_classattrs(self):
         self.assertIs(ast.Constant(None).value, None)
         self.assertIs(ast.Constant(...).value, ...)
 
+        with self.assertWarns(DeprecationWarning):
+            ast.Tuple().dims
+
+        with self.assertWarns(DeprecationWarning):
+            ast.Tuple().dims = 3
+
     def test_constant_subclasses(self):
         class N(ast.Constant):
             def __init__(self, *args, **kwargs):
@@ -1100,6 +1106,38 @@ def test_tstring(self):
         self.assertIsInstance(tree.body[0].value.values[0], ast.Constant)
         self.assertIsInstance(tree.body[0].value.values[1], ast.Interpolation)
 
+    def test_deprecated(self):
+        with self.assertWarns(DeprecationWarning):
+            ast.slice
+
+        with self.assertWarns(DeprecationWarning):
+            ast.Index
+
+        with self.assertWarns(DeprecationWarning):
+            ast.ExtSlice
+
+        with self.assertWarns(DeprecationWarning):
+            ast.Suite
+
+        with self.assertWarns(DeprecationWarning):
+            ast.AugLoad
+
+        with self.assertWarns(DeprecationWarning):
+            ast.AugStore
+
+        with self.assertWarns(DeprecationWarning):
+            ast.Param
+
+        namespace = {}
+        exec("from ast import *", namespace)
+        self.assertNotIn("slice", namespace)
+        self.assertNotIn("Index", namespace)
+        self.assertNotIn("ExtSlice", namespace)
+        self.assertNotIn("Suite", namespace)
+        self.assertNotIn("AugLoad", namespace)
+        self.assertNotIn("AugStore", namespace)
+        self.assertNotIn("Param", namespace)
+
     def test_filter_syntax_warnings_by_module(self):
         filename = support.findfile('test_import/data/syntax_warnings.py')
         with open(filename, 'rb') as f:
@@ -1139,8 +1177,9 @@ def iter_ast_classes():
         def do(cls):
             if cls.__module__ != 'ast':
                 return
-            if cls is ast.Index:
-                return
+            with warnings.catch_warnings(action="ignore", 
category=DeprecationWarning):
+                if cls is ast.Index:
+                    return
             # Don't attempt to create instances of abstract AST nodes
             if _ast._is_abstract(cls):
                 return
diff --git 
a/Misc/NEWS.d/next/Library/2025-10-20-09-12-18.gh-issue-140344.WjbYg-.rst 
b/Misc/NEWS.d/next/Library/2025-10-20-09-12-18.gh-issue-140344.WjbYg-.rst
new file mode 100644
index 00000000000000..ca3046941c6c93
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2025-10-20-09-12-18.gh-issue-140344.WjbYg-.rst
@@ -0,0 +1,11 @@
+The classes ``ast.slice``, ``ast.ExtSlice``, ``ast.Index``, ``ast.Suite``, 
``ast.AugLoad``,
+``ast.AugStore``, and ``ast.Param``, deprecated since Python 3.9, now issue
+deprecation warnings on use. They are now scheduled for removal in Python 3.21.
+
+The ``dims`` property of ``ast.Tuple`` objects, deprecated since Python 3.9,
+now issues a deprecation warning when accessed. The property is scheduled for
+removal in Python 3.21. Use the (non-deprecated) ``elts`` property of
+``ast.Tuple`` objects instead.
+
+The deprecated global names are also no longer imported by
+``from ast import *``.

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]

Reply via email to