diff --git a/Objects/typeobject.c b/Objects/typeobject.c --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -4302,9 +4302,8 @@ static int add_subclass(PyTypeObject *base, PyTypeObject *type) { - Py_ssize_t i; int result; - PyObject *list, *ref, *newobj; + PyObject *list, *newobj; list = base->tp_subclasses; if (list == NULL) { @@ -4314,13 +4313,6 @@ } assert(PyList_Check(list)); newobj = PyWeakref_NewRef((PyObject *)type, NULL); - i = PyList_GET_SIZE(list); - while (--i >= 0) { - ref = PyList_GET_ITEM(list, i); - assert(PyWeakref_CheckRef(ref)); - if (PyWeakref_GET_OBJECT(ref) == Py_None) - return PyList_SetItem(list, i, newobj); - } result = PyList_Append(list, newobj); Py_DECREF(newobj); return result; @@ -4342,8 +4334,15 @@ ref = PyList_GET_ITEM(list, i); assert(PyWeakref_CheckRef(ref)); if (PyWeakref_GET_OBJECT(ref) == (PyObject*)type) { + /* swap the item with the last one */ + Py_ssize_t j = PyList_GET_SIZE(list)-1; + if (i != j) { + PyObject *tmp = PyList_GET_ITEM(list, j); + PyList_SET_ITEM(list, j, ref) ; + PyList_SET_ITEM(list, i, tmp); + } /* this can't fail, right? */ - PySequence_DelItem(list, i); + PySequence_DelItem(list, j); return; } }