diff --git a/Doc/deprecations/pending-removal-in-3.20.rst b/Doc/deprecations/pending-removal-in-3.20.rst index 12d7acf5ce05b4..64bfdaa53d82c0 100644 --- a/Doc/deprecations/pending-removal-in-3.20.rst +++ b/Doc/deprecations/pending-removal-in-3.20.rst @@ -43,3 +43,8 @@ Pending removal in Python 3.20 * Creating instances of abstract AST nodes (such as :class:`ast.AST` or :class:`!ast.expr`) is deprecated and will raise an error in Python 3.20. + * Classes ``slice``, ``Index``, ``ExtSlice``, ``Suite``, ``Param``, + ``AugLoad`` and ``AugStore``, will be removed in Python 3.20. 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.20. Use + the ``ast.Tuple.elts`` property instead. diff --git a/Doc/whatsnew/3.15.rst b/Doc/whatsnew/3.15.rst index 78e464f2a5a6d8..16741cb16764a9 100644 --- a/Doc/whatsnew/3.15.rst +++ b/Doc/whatsnew/3.15.rst @@ -1872,6 +1872,17 @@ New deprecations (Contributed by Nikita Sobolev in :gh:`136355`.) +* :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.20. 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.20. Use ``ast.Tuple.elts`` instead. + * :mod:`collections.abc` * The following statements now cause ``DeprecationWarning``\ s to be emitted diff --git a/Lib/ast.py b/Lib/ast.py index ba4ee0197b85d2..be206e7166e419 100644 --- a/Lib/ast.py +++ b/Lib/ast.py @@ -629,9 +629,13 @@ def __new__(cls, dims=(), **kwargs): def _dims_getter(self): """Deprecated. Use elts instead.""" + import warnings + warnings._deprecated(f"ast.Tuple.dims", remove=(3, 20)) return self.elts def _dims_setter(self, value): + import warnings + warnings._deprecated(f"ast.Tuple.dims", remove=(3, 20)) self.elts = value Tuple.dims = property(_dims_getter, _dims_setter) @@ -712,5 +716,24 @@ 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 + import warnings + warnings._deprecated(f"ast.{attr}", remove=(3, 20)) + 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 fcc6c93eb86981..3ecc3ab163c560 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..5821c9ecd8157f --- /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.20. + +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.20. Use the (non-deprecated) ``elts`` property of +``ast.Tuple`` objects instead. + +The deprecated global names are also no longer imported by +``from ast import *``.