diff options
author | Victor Stinner <vstinner@python.org> | 2022-01-21 22:29:10 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-01-21 22:29:10 (GMT) |
commit | 8ee07dda139f3fa1d7c58a29532a98efc790568d (patch) | |
tree | b55c7db28a923d035a718d80ee4f06bcb1066631 /Modules/_abc.c | |
parent | 57d1855682dbeb9233ef3a531f9535c6442e9992 (diff) | |
download | cpython-8ee07dda139f3fa1d7c58a29532a98efc790568d.zip cpython-8ee07dda139f3fa1d7c58a29532a98efc790568d.tar.gz cpython-8ee07dda139f3fa1d7c58a29532a98efc790568d.tar.bz2 |
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().
Diffstat (limited to 'Modules/_abc.c')
-rw-r--r-- | Modules/_abc.c | 18 |
1 files changed, 9 insertions, 9 deletions
diff --git a/Modules/_abc.c b/Modules/_abc.c index b7465c3..a043961 100644 --- a/Modules/_abc.c +++ b/Modules/_abc.c @@ -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] |