@@ -16,6 +16,7 @@ _Py_IDENTIFIER(__abstractmethods__);
16
16
_Py_IDENTIFIER (__class__ );
17
17
_Py_IDENTIFIER (__dict__ );
18
18
_Py_IDENTIFIER (__bases__ );
19
+ _Py_IDENTIFIER (__mro__ );
19
20
_Py_IDENTIFIER (_abc_impl );
20
21
_Py_IDENTIFIER (__subclasscheck__ );
21
22
_Py_IDENTIFIER (__subclasshook__ );
@@ -568,7 +569,7 @@ _abc__abc_subclasscheck_impl(PyObject *module, PyObject *self,
568
569
PyObject * subclass )
569
570
/*[clinic end generated code: output=b56c9e4a530e3894 input=1d947243409d10b8]*/
570
571
{
571
- PyObject * ok , * mro , * subclasses = NULL , * result = NULL ;
572
+ PyObject * ok , * mro = NULL , * subclasses = NULL , * result = NULL ;
572
573
Py_ssize_t pos ;
573
574
int incache ;
574
575
_abc_data * impl = _get_impl (self );
@@ -637,20 +638,31 @@ _abc__abc_subclasscheck_impl(PyObject *module, PyObject *self,
637
638
}
638
639
Py_DECREF (ok );
639
640
640
- /* 4. Check if it's a direct subclass. */
641
- mro = ((PyTypeObject * )subclass )-> tp_mro ;
642
- assert (PyTuple_Check (mro ));
643
- for (pos = 0 ; pos < PyTuple_GET_SIZE (mro ); pos ++ ) {
644
- PyObject * mro_item = PyTuple_GET_ITEM (mro , pos );
645
- if (mro_item == NULL ) {
641
+ /* 4. Check if it's a direct subclass.
642
+ *
643
+ * if cls in getattr(subclass, '__mro__', ()):
644
+ * cls._abc_cache.add(subclass)
645
+ * return True
646
+ */
647
+ if (_PyObject_LookupAttrId (subclass , & PyId___mro__ , & mro ) < 0 ) {
648
+ goto end ;
649
+ }
650
+ if (mro != NULL ) {
651
+ if (!PyTuple_Check (mro )) {
652
+ // Python version supports non-tuple iterable. Keep it as
653
+ // implementation detail.
654
+ PyErr_SetString (PyExc_TypeError , "__mro__ is not a tuple" );
646
655
goto end ;
647
656
}
648
- if ((PyObject * )self == mro_item ) {
649
- if (_add_to_weak_set (& impl -> _abc_cache , subclass ) < 0 ) {
657
+ for (pos = 0 ; pos < PyTuple_GET_SIZE (mro ); pos ++ ) {
658
+ PyObject * mro_item = PyTuple_GET_ITEM (mro , pos );
659
+ if ((PyObject * )self == mro_item ) {
660
+ if (_add_to_weak_set (& impl -> _abc_cache , subclass ) < 0 ) {
661
+ goto end ;
662
+ }
663
+ result = Py_True ;
650
664
goto end ;
651
665
}
652
- result = Py_True ;
653
- goto end ;
654
666
}
655
667
}
656
668
@@ -690,7 +702,8 @@ _abc__abc_subclasscheck_impl(PyObject *module, PyObject *self,
690
702
result = Py_False ;
691
703
692
704
end :
693
- Py_XDECREF (impl );
705
+ Py_DECREF (impl );
706
+ Py_XDECREF (mro );
694
707
Py_XDECREF (subclasses );
695
708
Py_XINCREF (result );
696
709
return result ;
0 commit comments