@@ -603,21 +603,19 @@ _abc__abc_register_impl(PyObject *module, PyObject *self, PyObject *subclass)
603603 return NULL ;
604604 }
605605
606- if (!PyTuple_Check (mro )) {
607- PyErr_SetString (PyExc_TypeError , "__mro__ is not tuple" );
606+ if (!PyTuple_CheckExact (mro )) {
607+ PyErr_SetString (PyExc_TypeError , "__mro__ must be an exact tuple" );
608608 goto error ;
609609 }
610610
611611 for (Py_ssize_t pos = 0 ; pos < PyTuple_GET_SIZE (mro ); pos ++ ) {
612612 PyObject * base_class = PyTuple_GET_ITEM (mro , pos ); // borrowed
613613 PyObject * base_class_data ;
614614
615- if (PyObject_GetOptionalAttr (base_class , & _Py_ID (_abc_impl ),
616- & base_class_data ) < 0 ) {
617- goto error ;
618- }
619-
620- if (PyErr_Occurred ()) {
615+ if (PyObject_GetOptionalAttr (base_class ,
616+ & _Py_ID (_abc_impl ),
617+ & base_class_data ) < 0 )
618+ {
621619 goto error ;
622620 }
623621
@@ -627,8 +625,11 @@ _abc__abc_register_impl(PyObject *module, PyObject *self, PyObject *subclass)
627625 }
628626
629627 _abc_data * base_class_state = _abc_data_CAST (base_class_data );
630- if (_add_to_weak_set (base_class_state , & base_class_state -> _abc_registry , subclass ) < 0 ) {
631- Py_DECREF (base_class_data );
628+ int res = _add_to_weak_set (base_class_state ,
629+ & base_class_state -> _abc_registry ,
630+ subclass );
631+ Py_DECREF (base_class_data );
632+ if (res < 0 ) {
632633 goto error ;
633634 }
634635 }
@@ -763,7 +764,6 @@ _abc__abc_subclasscheck_impl(PyObject *module, PyObject *self,
763764
764765 PyObject * ok , * subclasses = NULL , * result = NULL ;
765766 _abcmodule_state * state = NULL ;
766- Py_ssize_t pos ;
767767 int incache ;
768768 _abc_data * impl = _get_impl (module , self );
769769 if (impl == NULL ) {
@@ -850,45 +850,6 @@ _abc__abc_subclasscheck_impl(PyObject *module, PyObject *self,
850850 goto end ;
851851 }
852852
853- /* 6. Check if it's a subclass of a subclass (recursive).
854- >>> class Ancestor: __subclasses__ = lambda: [Other]
855- >>> class Other: pass
856- >>> isinstance(Other, Ancestor) is True
857-
858- Do not iterate over cls.__subclasses__() because it returns the entire class tree,
859- not just direct children, which leads to O(n^2) lookup.
860- */
861- PyObject * dict = _PyType_GetDict (cls ); // borrowed
862- PyObject * subclasses_own_method = PyDict_GetItemString (dict , "__subclasses__" ); // borrowed
863- if (subclasses_own_method ) {
864- subclasses = PyObject_CallNoArgs (subclasses_own_method );
865- if (subclasses == NULL ) {
866- goto end ;
867- }
868- if (!PyList_Check (subclasses )) {
869- PyErr_SetString (PyExc_TypeError , "__subclasses__() must return a list" );
870- goto end ;
871- }
872- for (pos = 0 ; pos < PyList_GET_SIZE (subclasses ); pos ++ ) {
873- PyObject * scls = PyList_GetItemRef (subclasses , pos );
874- if (scls == NULL ) {
875- goto end ;
876- }
877- int r = PyObject_IsSubclass (subclass , scls );
878- Py_DECREF (scls );
879- if (r > 0 ) {
880- if (_add_to_weak_set (impl , & impl -> _abc_cache , subclass ) < 0 ) {
881- goto end ;
882- }
883- result = Py_True ;
884- goto end ;
885- }
886- if (r < 0 ) {
887- goto end ;
888- }
889- }
890- }
891-
892853 /* No dice; update negative cache. */
893854 if (_add_to_weak_set (impl , & impl -> _abc_negative_cache , subclass ) < 0 ) {
894855 goto end ;
0 commit comments