[3.14] gh-133783: Fix __replace__ on AST nodes for optional attributes (GH-133797) (#133842)

gh-133783: Fix __replace__ on AST nodes for optional attributes (GH-133797)
(cherry picked from commit 7dddb4e667)

Co-authored-by: Jelle Zijlstra <jelle.zijlstra@gmail.com>
This commit is contained in:
Miss Islington (bot) 2025-05-10 18:44:07 +02:00 committed by GitHub
parent 13c94d0401
commit 856e5903ba
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 64 additions and 0 deletions

26
Python/Python-ast.c generated
View file

@ -5528,6 +5528,32 @@ ast_type_replace_check(PyObject *self,
Py_DECREF(unused);
}
}
// Discard fields from 'expecting' that default to None
PyObject *field_types = NULL;
if (PyObject_GetOptionalAttr((PyObject*)Py_TYPE(self),
&_Py_ID(_field_types),
&field_types) < 0)
{
Py_DECREF(expecting);
return -1;
}
if (field_types != NULL) {
Py_ssize_t pos = 0;
PyObject *field_name, *field_type;
while (PyDict_Next(field_types, &pos, &field_name, &field_type)) {
if (_PyUnion_Check(field_type)) {
// optional field
if (PySet_Discard(expecting, field_name) < 0) {
Py_DECREF(expecting);
Py_DECREF(field_types);
return -1;
}
}
}
Py_DECREF(field_types);
}
// Now 'expecting' contains the fields or attributes
// that would not be filled inside ast_type_replace().
Py_ssize_t m = PySet_GET_SIZE(expecting);