bpo-39999: Improve compatibility of the ast module. (GH-19056)

* Re-add removed classes Suite, slice, Param, AugLoad and AugStore.
* Add docstrings for dummy classes.
* Add docstrings for attribute aliases.
* Set __module__ to "ast" instead of "_ast".
This commit is contained in:
Serhiy Storchaka 2020-03-22 20:33:34 +02:00 committed by GitHub
parent 044cf94f61
commit bace59d8b8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 49 additions and 22 deletions

View File

@ -593,12 +593,19 @@ Deprecated
(Contributed by Victor Stinner in :issue:`39353`.) (Contributed by Victor Stinner in :issue:`39353`.)
* :mod:`ast` classes ``Index`` and ``ExtSlice`` are considered deprecated * :mod:`ast` classes ``slice``, ``Index`` and ``ExtSlice`` are considered deprecated
and will be removed in future Python versions. ``value`` itself should be and will be removed in future Python versions. ``value`` itself should be
used instead of ``Index(value)``. ``Tuple(slices, Load())`` should be used instead of ``Index(value)``. ``Tuple(slices, Load())`` should be
used instead of ``ExtSlice(slices)``. used instead of ``ExtSlice(slices)``.
(Contributed by Serhiy Storchaka in :issue:`32892`.) (Contributed by Serhiy Storchaka in :issue:`32892`.)
* :mod:`ast` classes ``Suite``, ``Param``, ``AugLoad`` and ``AugStore``
are considered deprecated and will be removed in future Python versions.
They were not generated by the parser and not accepted by the code
generator in Python 3.
(Contributed by Batuhan Taskaya in :issue:`39639` and :issue:`39969`
and Serhiy Storchaka in :issue:`39988`.)
* The :c:func:`PyEval_InitThreads` and :c:func:`PyEval_ThreadsInitialized` * The :c:func:`PyEval_InitThreads` and :c:func:`PyEval_ThreadsInitialized`
functions are now deprecated and will be removed in Python 3.11. Calling functions are now deprecated and will be removed in Python 3.11. Calling
:c:func:`PyEval_InitThreads` now does nothing. The :term:`GIL` is initialized :c:func:`PyEval_InitThreads` now does nothing. The :term:`GIL` is initialized
@ -704,11 +711,6 @@ Removed
defining ``COUNT_ALLOCS`` macro. defining ``COUNT_ALLOCS`` macro.
(Contributed by Victor Stinner in :issue:`39489`.) (Contributed by Victor Stinner in :issue:`39489`.)
* The ``ast.Suite``, ``ast.Param``, ``ast.AugLoad`` and ``ast.AugStore``
node classes have been removed due to no longer being needed.
(Contributed by Batuhan Taskaya in :issue:`39639` and :issue:`39969`
and Serhiy Storchaka in :issue:`39988`.)
Porting to Python 3.9 Porting to Python 3.9
===================== =====================

View File

@ -489,6 +489,7 @@ class NodeTransformer(NodeVisitor):
# It will be removed in future. # It will be removed in future.
def _getter(self): def _getter(self):
"""Deprecated. Use value instead."""
return self.value return self.value
def _setter(self, value): def _setter(self, value):
@ -499,6 +500,9 @@ Constant.s = property(_getter, _setter)
class _ABC(type): class _ABC(type):
def __init__(cls, *args):
cls.__doc__ = """Deprecated AST node class. Use ast.Constant instead"""
def __instancecheck__(cls, inst): def __instancecheck__(cls, inst):
if not isinstance(inst, Constant): if not isinstance(inst, Constant):
return False return False
@ -564,15 +568,21 @@ _const_node_type_names = {
type(...): 'Ellipsis', type(...): 'Ellipsis',
} }
class Index(AST): class slice(AST):
"""Deprecated AST node class."""
class Index(slice):
"""Deprecated AST node class. Use the index value directly instead."""
def __new__(cls, value, **kwargs): def __new__(cls, value, **kwargs):
return value return value
class ExtSlice(AST): class ExtSlice(slice):
"""Deprecated AST node class. Use ast.Tuple instead."""
def __new__(cls, dims=(), **kwargs): def __new__(cls, dims=(), **kwargs):
return Tuple(list(dims), Load(), **kwargs) return Tuple(list(dims), Load(), **kwargs)
def _dims_getter(self): def _dims_getter(self):
"""Deprecated. Use elts instead."""
return self.elts return self.elts
def _dims_setter(self, value): def _dims_setter(self, value):
@ -580,6 +590,18 @@ def _dims_setter(self, value):
Tuple.dims = property(_dims_getter, _dims_setter) Tuple.dims = property(_dims_getter, _dims_setter)
class Suite(mod):
"""Deprecated AST node class. Unused in Python 3."""
class AugLoad(expr_context):
"""Deprecated AST node class. Unused in Python 3."""
class AugStore(expr_context):
"""Deprecated AST node class. Unused in Python 3."""
class Param(expr_context):
"""Deprecated AST node class. Unused in Python 3."""
# Large float and imaginary literals get turned into infinities in the AST. # Large float and imaginary literals get turned into infinities in the AST.
# We unparse those infinities to INFSTR. # We unparse those infinities to INFSTR.

View File

@ -283,7 +283,7 @@ class AST_Tests(unittest.TestCase):
x.vararg x.vararg
with self.assertRaises(TypeError): with self.assertRaises(TypeError):
# "_ast.AST constructor takes 0 positional arguments" # "ast.AST constructor takes 0 positional arguments"
ast.AST(2) ast.AST(2)
def test_AST_garbage_collection(self): def test_AST_garbage_collection(self):
@ -573,7 +573,7 @@ class AST_Tests(unittest.TestCase):
m = ast.Module([ast.Expr(ast.expr(**pos), **pos)], []) m = ast.Module([ast.Expr(ast.expr(**pos), **pos)], [])
with self.assertRaises(TypeError) as cm: with self.assertRaises(TypeError) as cm:
compile(m, "<test>", "exec") compile(m, "<test>", "exec")
self.assertIn("but got <_ast.expr", str(cm.exception)) self.assertIn("but got <ast.expr", str(cm.exception))
def test_invalid_identifier(self): def test_invalid_identifier(self):
m = ast.Module([ast.Expr(ast.Name(42, ast.Load()))], []) m = ast.Module([ast.Expr(ast.Name(42, ast.Load()))], [])

View File

@ -1 +0,0 @@
Remove ``ast.Suite`` node class because it's no longer used. Patch by Batuhan Taskaya.

View File

@ -0,0 +1 @@
Deprecated ``ast.Suite`` node class because it's no longer used. Patch by Batuhan Taskaya.

View File

@ -1,2 +1,2 @@
Remove ``ast.Param`` node class because it's no longer used. Patch by Deprecated ``ast.Param`` node class because it's no longer used. Patch by
Batuhan Taskaya. Batuhan Taskaya.

View File

@ -1,2 +1,2 @@
Removed ``ast.AugLoad`` and ``ast.AugStore`` node classes because they are Deprecated ``ast.AugLoad`` and ``ast.AugStore`` node classes because they are
no longer used. no longer used.

View File

@ -0,0 +1,3 @@
``__module__`` of the AST node classes is now set to "ast" instead of
"_ast". Added docstrings for dummy AST node classes and deprecated
attributes.

View File

@ -774,7 +774,7 @@ static PyType_Slot AST_type_slots[] = {
}; };
static PyType_Spec AST_type_spec = { static PyType_Spec AST_type_spec = {
"_ast.AST", "ast.AST",
sizeof(AST_object), sizeof(AST_object),
0, 0,
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
@ -800,7 +800,7 @@ make_type(const char *type, PyObject* base, const char* const* fields, int num_f
type, base, type, base,
astmodulestate_global->_fields, fnames, astmodulestate_global->_fields, fnames,
astmodulestate_global->__module__, astmodulestate_global->__module__,
astmodulestate_global->_ast, astmodulestate_global->ast,
astmodulestate_global->__doc__, doc); astmodulestate_global->__doc__, doc);
Py_DECREF(fnames); Py_DECREF(fnames);
return result; return result;
@ -1302,7 +1302,7 @@ def generate_module_def(f, mod):
visitor_list.add(visitor) visitor_list.add(visitor)
state_strings = { state_strings = {
"_ast", "ast",
"_fields", "_fields",
"__doc__", "__doc__",
"__dict__", "__dict__",

12
Python/Python-ast.c generated
View File

@ -134,7 +134,6 @@ typedef struct {
PyObject *__dict__; PyObject *__dict__;
PyObject *__doc__; PyObject *__doc__;
PyObject *__module__; PyObject *__module__;
PyObject *_ast;
PyObject *_attributes; PyObject *_attributes;
PyObject *_fields; PyObject *_fields;
PyObject *alias_type; PyObject *alias_type;
@ -145,6 +144,7 @@ typedef struct {
PyObject *argtypes; PyObject *argtypes;
PyObject *arguments_type; PyObject *arguments_type;
PyObject *asname; PyObject *asname;
PyObject *ast;
PyObject *attr; PyObject *attr;
PyObject *bases; PyObject *bases;
PyObject *body; PyObject *body;
@ -354,7 +354,6 @@ static int astmodule_clear(PyObject *module)
Py_CLEAR(astmodulestate(module)->__dict__); Py_CLEAR(astmodulestate(module)->__dict__);
Py_CLEAR(astmodulestate(module)->__doc__); Py_CLEAR(astmodulestate(module)->__doc__);
Py_CLEAR(astmodulestate(module)->__module__); Py_CLEAR(astmodulestate(module)->__module__);
Py_CLEAR(astmodulestate(module)->_ast);
Py_CLEAR(astmodulestate(module)->_attributes); Py_CLEAR(astmodulestate(module)->_attributes);
Py_CLEAR(astmodulestate(module)->_fields); Py_CLEAR(astmodulestate(module)->_fields);
Py_CLEAR(astmodulestate(module)->alias_type); Py_CLEAR(astmodulestate(module)->alias_type);
@ -365,6 +364,7 @@ static int astmodule_clear(PyObject *module)
Py_CLEAR(astmodulestate(module)->argtypes); Py_CLEAR(astmodulestate(module)->argtypes);
Py_CLEAR(astmodulestate(module)->arguments_type); Py_CLEAR(astmodulestate(module)->arguments_type);
Py_CLEAR(astmodulestate(module)->asname); Py_CLEAR(astmodulestate(module)->asname);
Py_CLEAR(astmodulestate(module)->ast);
Py_CLEAR(astmodulestate(module)->attr); Py_CLEAR(astmodulestate(module)->attr);
Py_CLEAR(astmodulestate(module)->bases); Py_CLEAR(astmodulestate(module)->bases);
Py_CLEAR(astmodulestate(module)->body); Py_CLEAR(astmodulestate(module)->body);
@ -573,7 +573,6 @@ static int astmodule_traverse(PyObject *module, visitproc visit, void* arg)
Py_VISIT(astmodulestate(module)->__dict__); Py_VISIT(astmodulestate(module)->__dict__);
Py_VISIT(astmodulestate(module)->__doc__); Py_VISIT(astmodulestate(module)->__doc__);
Py_VISIT(astmodulestate(module)->__module__); Py_VISIT(astmodulestate(module)->__module__);
Py_VISIT(astmodulestate(module)->_ast);
Py_VISIT(astmodulestate(module)->_attributes); Py_VISIT(astmodulestate(module)->_attributes);
Py_VISIT(astmodulestate(module)->_fields); Py_VISIT(astmodulestate(module)->_fields);
Py_VISIT(astmodulestate(module)->alias_type); Py_VISIT(astmodulestate(module)->alias_type);
@ -584,6 +583,7 @@ static int astmodule_traverse(PyObject *module, visitproc visit, void* arg)
Py_VISIT(astmodulestate(module)->argtypes); Py_VISIT(astmodulestate(module)->argtypes);
Py_VISIT(astmodulestate(module)->arguments_type); Py_VISIT(astmodulestate(module)->arguments_type);
Py_VISIT(astmodulestate(module)->asname); Py_VISIT(astmodulestate(module)->asname);
Py_VISIT(astmodulestate(module)->ast);
Py_VISIT(astmodulestate(module)->attr); Py_VISIT(astmodulestate(module)->attr);
Py_VISIT(astmodulestate(module)->bases); Py_VISIT(astmodulestate(module)->bases);
Py_VISIT(astmodulestate(module)->body); Py_VISIT(astmodulestate(module)->body);
@ -688,7 +688,6 @@ static int init_identifiers(void)
if ((state->__dict__ = PyUnicode_InternFromString("__dict__")) == NULL) return 0; if ((state->__dict__ = PyUnicode_InternFromString("__dict__")) == NULL) return 0;
if ((state->__doc__ = PyUnicode_InternFromString("__doc__")) == NULL) return 0; if ((state->__doc__ = PyUnicode_InternFromString("__doc__")) == NULL) return 0;
if ((state->__module__ = PyUnicode_InternFromString("__module__")) == NULL) return 0; if ((state->__module__ = PyUnicode_InternFromString("__module__")) == NULL) return 0;
if ((state->_ast = PyUnicode_InternFromString("_ast")) == NULL) return 0;
if ((state->_attributes = PyUnicode_InternFromString("_attributes")) == NULL) return 0; if ((state->_attributes = PyUnicode_InternFromString("_attributes")) == NULL) return 0;
if ((state->_fields = PyUnicode_InternFromString("_fields")) == NULL) return 0; if ((state->_fields = PyUnicode_InternFromString("_fields")) == NULL) return 0;
if ((state->annotation = PyUnicode_InternFromString("annotation")) == NULL) return 0; if ((state->annotation = PyUnicode_InternFromString("annotation")) == NULL) return 0;
@ -696,6 +695,7 @@ static int init_identifiers(void)
if ((state->args = PyUnicode_InternFromString("args")) == NULL) return 0; if ((state->args = PyUnicode_InternFromString("args")) == NULL) return 0;
if ((state->argtypes = PyUnicode_InternFromString("argtypes")) == NULL) return 0; if ((state->argtypes = PyUnicode_InternFromString("argtypes")) == NULL) return 0;
if ((state->asname = PyUnicode_InternFromString("asname")) == NULL) return 0; if ((state->asname = PyUnicode_InternFromString("asname")) == NULL) return 0;
if ((state->ast = PyUnicode_InternFromString("ast")) == NULL) return 0;
if ((state->attr = PyUnicode_InternFromString("attr")) == NULL) return 0; if ((state->attr = PyUnicode_InternFromString("attr")) == NULL) return 0;
if ((state->bases = PyUnicode_InternFromString("bases")) == NULL) return 0; if ((state->bases = PyUnicode_InternFromString("bases")) == NULL) return 0;
if ((state->body = PyUnicode_InternFromString("body")) == NULL) return 0; if ((state->body = PyUnicode_InternFromString("body")) == NULL) return 0;
@ -1209,7 +1209,7 @@ static PyType_Slot AST_type_slots[] = {
}; };
static PyType_Spec AST_type_spec = { static PyType_Spec AST_type_spec = {
"_ast.AST", "ast.AST",
sizeof(AST_object), sizeof(AST_object),
0, 0,
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
@ -1235,7 +1235,7 @@ make_type(const char *type, PyObject* base, const char* const* fields, int num_f
type, base, type, base,
astmodulestate_global->_fields, fnames, astmodulestate_global->_fields, fnames,
astmodulestate_global->__module__, astmodulestate_global->__module__,
astmodulestate_global->_ast, astmodulestate_global->ast,
astmodulestate_global->__doc__, doc); astmodulestate_global->__doc__, doc);
Py_DECREF(fnames); Py_DECREF(fnames);
return result; return result;