mirror of
https://github.com/python/cpython.git
synced 2025-07-07 19:35:27 +00:00
gh-117486: Improve behavior for user-defined AST subclasses (#118212)
Now, such classes will no longer require changes in Python 3.13 in the normal case. The test suite for robotframework passes with no DeprecationWarnings under this PR. I also added a new DeprecationWarning for the case where `_field_types` exists but is incomplete, since that seems likely to indicate a user mistake.
This commit is contained in:
parent
040571f258
commit
e0422198fb
6 changed files with 94 additions and 33 deletions
31
Python/Python-ast.c
generated
31
Python/Python-ast.c
generated
|
@ -5178,14 +5178,9 @@ ast_type_init(PyObject *self, PyObject *args, PyObject *kw)
|
|||
goto cleanup;
|
||||
}
|
||||
if (field_types == NULL) {
|
||||
if (PyErr_WarnFormat(
|
||||
PyExc_DeprecationWarning, 1,
|
||||
"%.400s provides _fields but not _field_types. "
|
||||
"This will become an error in Python 3.15.",
|
||||
Py_TYPE(self)->tp_name
|
||||
) < 0) {
|
||||
res = -1;
|
||||
}
|
||||
// Probably a user-defined subclass of AST that lacks _field_types.
|
||||
// This will continue to work as it did before 3.13; i.e., attributes
|
||||
// that are not passed in simply do not exist on the instance.
|
||||
goto cleanup;
|
||||
}
|
||||
remaining_list = PySequence_List(remaining_fields);
|
||||
|
@ -5196,12 +5191,21 @@ ast_type_init(PyObject *self, PyObject *args, PyObject *kw)
|
|||
PyObject *name = PyList_GET_ITEM(remaining_list, i);
|
||||
PyObject *type = PyDict_GetItemWithError(field_types, name);
|
||||
if (!type) {
|
||||
if (!PyErr_Occurred()) {
|
||||
PyErr_SetObject(PyExc_KeyError, name);
|
||||
if (PyErr_Occurred()) {
|
||||
goto set_remaining_cleanup;
|
||||
}
|
||||
else {
|
||||
if (PyErr_WarnFormat(
|
||||
PyExc_DeprecationWarning, 1,
|
||||
"Field '%U' is missing from %.400s._field_types. "
|
||||
"This will become an error in Python 3.15.",
|
||||
name, Py_TYPE(self)->tp_name
|
||||
) < 0) {
|
||||
goto set_remaining_cleanup;
|
||||
}
|
||||
}
|
||||
goto set_remaining_cleanup;
|
||||
}
|
||||
if (_PyUnion_Check(type)) {
|
||||
else if (_PyUnion_Check(type)) {
|
||||
// optional field
|
||||
// do nothing, we'll have set a None default on the class
|
||||
}
|
||||
|
@ -5225,8 +5229,7 @@ ast_type_init(PyObject *self, PyObject *args, PyObject *kw)
|
|||
"This will become an error in Python 3.15.",
|
||||
Py_TYPE(self)->tp_name, name
|
||||
) < 0) {
|
||||
res = -1;
|
||||
goto cleanup;
|
||||
goto set_remaining_cleanup;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue