@@ -1914,6 +1914,15 @@ abstract_issubclass(PyObject *derived, PyObject *cls)
19141914 if (derived == cls )
19151915 return 1 ;
19161916
1917+ if (PyTuple_Check (cls )) {
1918+ /* Not a general sequence -- that opens up the road to
1919+ recursion and stack overflow. */
1920+ n = PyTuple_GET_SIZE (cls );
1921+ for (i = 0 ; i < n ; i ++ ) {
1922+ if (derived == PyTuple_GET_ITEM (cls , i ))
1923+ return 1 ;
1924+ }
1925+ }
19171926 bases = abstract_get_bases (derived );
19181927 if (bases == NULL ) {
19191928 if (PyErr_Occurred ())
@@ -1932,6 +1941,20 @@ abstract_issubclass(PyObject *derived, PyObject *cls)
19321941 return r ;
19331942}
19341943
1944+ static int
1945+ check_class (PyObject * cls , const char * error )
1946+ {
1947+ PyObject * bases = abstract_get_bases (cls );
1948+ if (bases == NULL ) {
1949+ /* Do not mask errors. */
1950+ if (!PyErr_Occurred ())
1951+ PyErr_SetString (PyExc_TypeError , error );
1952+ return 0 ;
1953+ }
1954+ Py_DECREF (bases );
1955+ return -1 ;
1956+ }
1957+
19351958int
19361959PyObject_IsInstance (PyObject * inst , PyObject * cls )
19371960{
@@ -1962,16 +1985,10 @@ PyObject_IsInstance(PyObject *inst, PyObject *cls)
19621985 return retval ;
19631986 }
19641987 else {
1965- PyObject * cls_bases = abstract_get_bases (cls );
1966- if (cls_bases == NULL ) {
1967- /* Do not mask errors. */
1968- if (!PyErr_Occurred ())
1969- PyErr_SetString (PyExc_TypeError ,
1970- "isinstance() arg 2 must be a class, type,"
1971- " or tuple of classes and types" );
1988+ if (!check_class (cls ,
1989+ "isinstance() arg 2 must be a class, type,"
1990+ " or tuple of classes and types" ))
19721991 return -1 ;
1973- }
1974- Py_DECREF (cls_bases );
19751992 if (__class__ == NULL ) {
19761993 __class__ = PyString_FromString ("__class__" );
19771994 if (__class__ == NULL )
@@ -1997,28 +2014,25 @@ PyObject_IsSubclass(PyObject *derived, PyObject *cls)
19972014 int retval ;
19982015
19992016 if (!PyClass_Check (derived ) || !PyClass_Check (cls )) {
2000- PyObject * derived_bases ;
2001- PyObject * cls_bases ;
2002-
2003- derived_bases = abstract_get_bases (derived );
2004- if (derived_bases == NULL ) {
2005- /* Do not mask errors */
2006- if (!PyErr_Occurred ())
2007- PyErr_SetString (PyExc_TypeError ,
2008- "issubclass() arg 1 must be a class" );
2017+ if (!check_class (derived , "issubclass() arg 1 must be a class" ))
20092018 return -1 ;
2019+
2020+ if (PyTuple_Check (cls )) {
2021+ int i ;
2022+ int n = PyTuple_GET_SIZE (cls );
2023+ for (i = 0 ; i < n ; ++ i ) {
2024+ if (!check_class (PyTuple_GET_ITEM (cls , i ),
2025+ "issubclass() arg 2 must be a class"
2026+ " or tuple of classes" ))
2027+ return -1 ;
2028+ }
20102029 }
2011- Py_DECREF (derived_bases );
2012-
2013- cls_bases = abstract_get_bases (cls );
2014- if (cls_bases == NULL ) {
2015- /* Do not mask errors */
2016- if (!PyErr_Occurred ())
2017- PyErr_SetString (PyExc_TypeError ,
2018- "issubclass() arg 2 must be a class" );
2019- return -1 ;
2030+ else {
2031+ if (!check_class (cls ,
2032+ "issubclass() arg 2 must be a class"
2033+ " or tuple of classes" ))
2034+ return -1 ;
20202035 }
2021- Py_DECREF (cls_bases );
20222036
20232037 retval = abstract_issubclass (derived , cls );
20242038 }
0 commit comments