summaryrefslogtreecommitdiffstats
path: root/Modules/_abc.c
diff options
context:
space:
mode:
authorVictor Stinner <vstinner@python.org>2022-01-21 22:29:10 (GMT)
committerGitHub <noreply@github.com>2022-01-21 22:29:10 (GMT)
commit8ee07dda139f3fa1d7c58a29532a98efc790568d (patch)
treeb55c7db28a923d035a718d80ee4f06bcb1066631 /Modules/_abc.c
parent57d1855682dbeb9233ef3a531f9535c6442e9992 (diff)
downloadcpython-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.c18
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]