mirror of
https://github.com/python/cpython.git
synced 2025-12-04 00:30:19 +00:00
bpo-46417: Add _PyType_GetSubclasses() function (GH-30761)
Add a new _PyType_GetSubclasses() function to get type's subclasses. _PyType_GetSubclasses(type) returns a list which holds strong refererences to subclasses. It is safer than iterating on type->tp_subclasses which yields weak references and can be modified in the loop. _PyType_GetSubclasses(type) now holds a reference to the tp_subclasses dict while creating the list of subclasses. set_collection_flag_recursive() of _abc.c now uses _PyType_GetSubclasses().
This commit is contained in:
parent
57d1855682
commit
8ee07dda13
3 changed files with 75 additions and 54 deletions
|
|
@ -4,6 +4,7 @@
|
|||
#endif
|
||||
|
||||
#include "Python.h"
|
||||
#include "pycore_object.h" // _PyType_GetSubclasses()
|
||||
#include "pycore_moduleobject.h" // _PyModule_GetState()
|
||||
#include "clinic/_abc.c.h"
|
||||
|
||||
|
|
@ -493,21 +494,20 @@ set_collection_flag_recursive(PyTypeObject *child, unsigned long flag)
|
|||
{
|
||||
return;
|
||||
}
|
||||
|
||||
child->tp_flags &= ~COLLECTION_FLAGS;
|
||||
child->tp_flags |= flag;
|
||||
PyObject *grandchildren = child->tp_subclasses;
|
||||
|
||||
PyObject *grandchildren = _PyType_GetSubclasses(child);
|
||||
if (grandchildren == NULL) {
|
||||
return;
|
||||
}
|
||||
assert(PyDict_CheckExact(grandchildren));
|
||||
Py_ssize_t i = 0;
|
||||
while (PyDict_Next(grandchildren, &i, NULL, &grandchildren)) {
|
||||
assert(PyWeakref_CheckRef(grandchildren));
|
||||
PyObject *grandchild = PyWeakref_GET_OBJECT(grandchildren);
|
||||
if (PyType_Check(grandchild)) {
|
||||
set_collection_flag_recursive((PyTypeObject *)grandchild, flag);
|
||||
}
|
||||
|
||||
for (Py_ssize_t i = 0; i < PyList_GET_SIZE(grandchildren); i++) {
|
||||
PyObject *grandchild = PyList_GET_ITEM(grandchildren, i);
|
||||
set_collection_flag_recursive((PyTypeObject *)grandchild, flag);
|
||||
}
|
||||
Py_DECREF(grandchildren);
|
||||
}
|
||||
|
||||
/*[clinic input]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue