mirror of
https://github.com/python/cpython.git
synced 2026-05-04 09:31:02 +00:00
gh-116021: Deprecate support for instantiating abstract AST nodes (#137865)
Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com> Co-authored-by: Jelle Zijlstra <jelle.zijlstra@gmail.com>
This commit is contained in:
parent
b1d6231736
commit
bdedc4a20e
9 changed files with 173 additions and 14 deletions
61
Python/Python-ast.c
generated
61
Python/Python-ast.c
generated
|
|
@ -178,6 +178,7 @@ void _PyAST_Fini(PyInterpreterState *interp)
|
|||
Py_CLEAR(state->__module__);
|
||||
Py_CLEAR(state->_attributes);
|
||||
Py_CLEAR(state->_fields);
|
||||
Py_CLEAR(state->abstract_types);
|
||||
Py_CLEAR(state->alias_type);
|
||||
Py_CLEAR(state->annotation);
|
||||
Py_CLEAR(state->arg);
|
||||
|
|
@ -5269,6 +5270,19 @@ ast_type_init(PyObject *self, PyObject *args, PyObject *kw)
|
|||
return -1;
|
||||
}
|
||||
|
||||
int contains = PySet_Contains(state->abstract_types, (PyObject *)Py_TYPE(self));
|
||||
if (contains == -1) {
|
||||
return -1;
|
||||
}
|
||||
else if (contains == 1) {
|
||||
if (PyErr_WarnFormat(
|
||||
PyExc_DeprecationWarning, 1,
|
||||
"Instantiating abstract AST node class %T is deprecated. "
|
||||
"This will become an error in Python 3.20", self) < 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
Py_ssize_t i, numfields = 0;
|
||||
int res = -1;
|
||||
PyObject *key, *value, *fields, *attributes = NULL, *remaining_fields = NULL;
|
||||
|
|
@ -6100,6 +6114,13 @@ init_types(void *arg)
|
|||
if (!state->AST_type) {
|
||||
return -1;
|
||||
}
|
||||
state->abstract_types = PySet_New(NULL);
|
||||
if (!state->abstract_types) {
|
||||
return -1;
|
||||
}
|
||||
if (PySet_Add(state->abstract_types, state->AST_type) < 0) {
|
||||
return -1;
|
||||
}
|
||||
if (add_ast_fields(state) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -6110,6 +6131,7 @@ init_types(void *arg)
|
|||
" | FunctionType(expr* argtypes, expr returns)");
|
||||
if (!state->mod_type) return -1;
|
||||
if (add_attributes(state, state->mod_type, NULL, 0) < 0) return -1;
|
||||
if (PySet_Add(state->abstract_types, state->mod_type) < 0) return -1;
|
||||
state->Module_type = make_type(state, "Module", state->mod_type,
|
||||
Module_fields, 2,
|
||||
"Module(stmt* body, type_ignore* type_ignores)");
|
||||
|
|
@ -6159,6 +6181,7 @@ init_types(void *arg)
|
|||
if (!state->stmt_type) return -1;
|
||||
if (add_attributes(state, state->stmt_type, stmt_attributes, 4) < 0) return
|
||||
-1;
|
||||
if (PySet_Add(state->abstract_types, state->stmt_type) < 0) return -1;
|
||||
if (PyObject_SetAttr(state->stmt_type, state->end_lineno, Py_None) == -1)
|
||||
return -1;
|
||||
if (PyObject_SetAttr(state->stmt_type, state->end_col_offset, Py_None) ==
|
||||
|
|
@ -6348,6 +6371,7 @@ init_types(void *arg)
|
|||
if (!state->expr_type) return -1;
|
||||
if (add_attributes(state, state->expr_type, expr_attributes, 4) < 0) return
|
||||
-1;
|
||||
if (PySet_Add(state->abstract_types, state->expr_type) < 0) return -1;
|
||||
if (PyObject_SetAttr(state->expr_type, state->end_lineno, Py_None) == -1)
|
||||
return -1;
|
||||
if (PyObject_SetAttr(state->expr_type, state->end_col_offset, Py_None) ==
|
||||
|
|
@ -6494,6 +6518,8 @@ init_types(void *arg)
|
|||
"expr_context = Load | Store | Del");
|
||||
if (!state->expr_context_type) return -1;
|
||||
if (add_attributes(state, state->expr_context_type, NULL, 0) < 0) return -1;
|
||||
if (PySet_Add(state->abstract_types, state->expr_context_type) < 0) return
|
||||
-1;
|
||||
state->Load_type = make_type(state, "Load", state->expr_context_type, NULL,
|
||||
0,
|
||||
"Load");
|
||||
|
|
@ -6518,6 +6544,7 @@ init_types(void *arg)
|
|||
"boolop = And | Or");
|
||||
if (!state->boolop_type) return -1;
|
||||
if (add_attributes(state, state->boolop_type, NULL, 0) < 0) return -1;
|
||||
if (PySet_Add(state->abstract_types, state->boolop_type) < 0) return -1;
|
||||
state->And_type = make_type(state, "And", state->boolop_type, NULL, 0,
|
||||
"And");
|
||||
if (!state->And_type) return -1;
|
||||
|
|
@ -6535,6 +6562,7 @@ init_types(void *arg)
|
|||
"operator = Add | Sub | Mult | MatMult | Div | Mod | Pow | LShift | RShift | BitOr | BitXor | BitAnd | FloorDiv");
|
||||
if (!state->operator_type) return -1;
|
||||
if (add_attributes(state, state->operator_type, NULL, 0) < 0) return -1;
|
||||
if (PySet_Add(state->abstract_types, state->operator_type) < 0) return -1;
|
||||
state->Add_type = make_type(state, "Add", state->operator_type, NULL, 0,
|
||||
"Add");
|
||||
if (!state->Add_type) return -1;
|
||||
|
|
@ -6629,6 +6657,7 @@ init_types(void *arg)
|
|||
"unaryop = Invert | Not | UAdd | USub");
|
||||
if (!state->unaryop_type) return -1;
|
||||
if (add_attributes(state, state->unaryop_type, NULL, 0) < 0) return -1;
|
||||
if (PySet_Add(state->abstract_types, state->unaryop_type) < 0) return -1;
|
||||
state->Invert_type = make_type(state, "Invert", state->unaryop_type, NULL,
|
||||
0,
|
||||
"Invert");
|
||||
|
|
@ -6659,6 +6688,7 @@ init_types(void *arg)
|
|||
"cmpop = Eq | NotEq | Lt | LtE | Gt | GtE | Is | IsNot | In | NotIn");
|
||||
if (!state->cmpop_type) return -1;
|
||||
if (add_attributes(state, state->cmpop_type, NULL, 0) < 0) return -1;
|
||||
if (PySet_Add(state->abstract_types, state->cmpop_type) < 0) return -1;
|
||||
state->Eq_type = make_type(state, "Eq", state->cmpop_type, NULL, 0,
|
||||
"Eq");
|
||||
if (!state->Eq_type) return -1;
|
||||
|
|
@ -6732,6 +6762,8 @@ init_types(void *arg)
|
|||
if (!state->excepthandler_type) return -1;
|
||||
if (add_attributes(state, state->excepthandler_type,
|
||||
excepthandler_attributes, 4) < 0) return -1;
|
||||
if (PySet_Add(state->abstract_types, state->excepthandler_type) < 0) return
|
||||
-1;
|
||||
if (PyObject_SetAttr(state->excepthandler_type, state->end_lineno, Py_None)
|
||||
== -1)
|
||||
return -1;
|
||||
|
|
@ -6822,6 +6854,7 @@ init_types(void *arg)
|
|||
if (!state->pattern_type) return -1;
|
||||
if (add_attributes(state, state->pattern_type, pattern_attributes, 4) < 0)
|
||||
return -1;
|
||||
if (PySet_Add(state->abstract_types, state->pattern_type) < 0) return -1;
|
||||
state->MatchValue_type = make_type(state, "MatchValue",
|
||||
state->pattern_type, MatchValue_fields,
|
||||
1,
|
||||
|
|
@ -6872,6 +6905,8 @@ init_types(void *arg)
|
|||
"type_ignore = TypeIgnore(int lineno, string tag)");
|
||||
if (!state->type_ignore_type) return -1;
|
||||
if (add_attributes(state, state->type_ignore_type, NULL, 0) < 0) return -1;
|
||||
if (PySet_Add(state->abstract_types, state->type_ignore_type) < 0) return
|
||||
-1;
|
||||
state->TypeIgnore_type = make_type(state, "TypeIgnore",
|
||||
state->type_ignore_type,
|
||||
TypeIgnore_fields, 2,
|
||||
|
|
@ -6885,6 +6920,7 @@ init_types(void *arg)
|
|||
if (!state->type_param_type) return -1;
|
||||
if (add_attributes(state, state->type_param_type, type_param_attributes, 4)
|
||||
< 0) return -1;
|
||||
if (PySet_Add(state->abstract_types, state->type_param_type) < 0) return -1;
|
||||
state->TypeVar_type = make_type(state, "TypeVar", state->type_param_type,
|
||||
TypeVar_fields, 3,
|
||||
"TypeVar(identifier name, expr? bound, expr? default_value)");
|
||||
|
|
@ -17956,6 +17992,28 @@ obj2ast_type_param(struct ast_state *state, PyObject* obj, type_param_ty* out,
|
|||
}
|
||||
|
||||
|
||||
/* Helper for checking if a node class is abstract in the tests. */
|
||||
static PyObject *
|
||||
ast_is_abstract(PyObject *Py_UNUSED(module), PyObject *cls) {
|
||||
struct ast_state *state = get_ast_state();
|
||||
if (state == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
int contains = PySet_Contains(state->abstract_types, cls);
|
||||
if (contains == -1) {
|
||||
return NULL;
|
||||
}
|
||||
else if (contains == 1) {
|
||||
Py_RETURN_TRUE;
|
||||
}
|
||||
Py_RETURN_FALSE;
|
||||
}
|
||||
|
||||
static struct PyMethodDef astmodule_methods[] = {
|
||||
{"_is_abstract", ast_is_abstract, METH_O, NULL},
|
||||
{NULL} /* Sentinel */
|
||||
};
|
||||
|
||||
static int
|
||||
astmodule_exec(PyObject *m)
|
||||
{
|
||||
|
|
@ -18382,7 +18440,8 @@ static struct PyModuleDef _astmodule = {
|
|||
.m_name = "_ast",
|
||||
// The _ast module uses a per-interpreter state (PyInterpreterState.ast)
|
||||
.m_size = 0,
|
||||
.m_slots = astmodule_slots,
|
||||
.m_methods = astmodule_methods,
|
||||
.m_slots = astmodule_slots
|
||||
};
|
||||
|
||||
PyMODINIT_FUNC
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue