[Python-checkins] CVS: python/dist/src/Objects abstract.c,2.84,2.85

Neil Schemenauer nascheme@users.sourceforge.net
Wed, 17 Oct 2001 20:18:45 -0700


Update of /cvsroot/python/python/dist/src/Objects
In directory usw-pr-cvs1:/tmp/cvs-serv13453

Modified Files:
	abstract.c 
Log Message:
Fix error checking done by abstract_issubclass and abstract_isinstance.
isinstance() now allows any object as the first argument and a class, a
type or something with a __bases__ tuple attribute for the second
argument.  This closes SF patch #464992.


Index: abstract.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/abstract.c,v
retrieving revision 2.84
retrieving revision 2.85
diff -C2 -d -r2.84 -r2.85
*** abstract.c	2001/10/07 20:53:45	2.84
--- abstract.c	2001/10/18 03:18:43	2.85
***************
*** 1741,1783 ****
  /* isinstance(), issubclass() */
  
! static int
! abstract_issubclass(PyObject *derived, PyObject *cls, int first)
  {
  	static PyObject *__bases__ = NULL;
  	PyObject *bases;
- 	int i, n;
- 	int r = 0;
  
  	if (__bases__ == NULL) {
  		__bases__ = PyString_FromString("__bases__");
  		if (__bases__ == NULL)
! 			return -1;
  	}
  
! 	if (first) {
! 		bases = PyObject_GetAttr(cls, __bases__);
! 		if (bases == NULL || !PyTuple_Check(bases)) {
! 			Py_XDECREF(bases);
! 			PyErr_SetString(PyExc_TypeError,
! 					"issubclass() arg 2 must be a class");
! 			return -1;
! 		}
! 		Py_DECREF(bases);
  	}
  
  	if (derived == cls)
  		return 1;
  
! 	bases = PyObject_GetAttr(derived, __bases__);
! 	if (bases == NULL || !PyTuple_Check(bases)) {
! 	        Py_XDECREF(bases);
! 		PyErr_SetString(PyExc_TypeError,
! 				"issubclass() arg 1 must be a class");
! 		return -1;
! 	}
  
  	n = PyTuple_GET_SIZE(bases);
  	for (i = 0; i < n; i++) {
! 		r = abstract_issubclass(PyTuple_GET_ITEM(bases, i), cls, 0);
  		if (r != 0)
  			break;
--- 1741,1784 ----
  /* isinstance(), issubclass() */
  
! static PyObject *
! abstract_get_bases(PyObject *cls)
  {
  	static PyObject *__bases__ = NULL;
  	PyObject *bases;
  
  	if (__bases__ == NULL) {
  		__bases__ = PyString_FromString("__bases__");
  		if (__bases__ == NULL)
! 			return NULL;
  	}
  
! 	bases = PyObject_GetAttr(cls, __bases__);
! 	if (bases == NULL || !PyTuple_Check(bases)) {
! 	        Py_XDECREF(bases);
! 		return NULL;
  	}
  
+ 	return bases;
+ }
+ 
+ 
+ static int
+ abstract_issubclass(PyObject *derived, PyObject *cls)
+ {
+ 	PyObject *bases;
+ 	int i, n;
+ 	int r = 0;
+ 
+ 
  	if (derived == cls)
  		return 1;
  
! 	bases = abstract_get_bases(derived);
! 	if (bases == NULL)
! 		return 0;
  
  	n = PyTuple_GET_SIZE(bases);
  	for (i = 0; i < n; i++) {
! 		r = abstract_issubclass(PyTuple_GET_ITEM(bases, i), cls);
  		if (r != 0)
  			break;
***************
*** 1796,1805 ****
  	int retval = 0;
  
!         if (PyClass_Check(cls)) {
! 		if (PyInstance_Check(inst)) {
! 			PyObject *inclass =
! 				(PyObject*)((PyInstanceObject*)inst)->in_class;
! 			retval = PyClass_IsSubclass(inclass, cls);
! 		}
  	}
  	else if (PyType_Check(cls)) {
--- 1797,1804 ----
  	int retval = 0;
  
! 	if (PyClass_Check(cls) && PyInstance_Check(inst)) {
! 		PyObject *inclass =
! 			(PyObject*)((PyInstanceObject*)inst)->in_class;
! 		retval = PyClass_IsSubclass(inclass, cls);
  	}
  	else if (PyType_Check(cls)) {
***************
*** 1820,1824 ****
  		return retval;
  	}
! 	else if (!PyInstance_Check(inst)) {
  		if (__class__ == NULL) {
  			__class__ = PyString_FromString("__class__");
--- 1819,1830 ----
  		return retval;
  	}
! 	else {
! 		PyObject *cls_bases = abstract_get_bases(cls);
! 		if (cls_bases == NULL) {
! 			PyErr_SetString(PyExc_TypeError, 
! 				"isinstance() arg 2 must be a class or type");
! 			return -1;
! 		} 
! 		Py_DECREF(cls_bases);
  		if (__class__ == NULL) {
  			__class__ = PyString_FromString("__class__");
***************
*** 1827,1848 ****
  		}
  		icls = PyObject_GetAttr(inst, __class__);
! 		if (icls != NULL) {
! 			retval = abstract_issubclass(icls, cls, 1);
  			Py_DECREF(icls);
- 			if (retval < 0 &&
- 			    !PyErr_ExceptionMatches(PyExc_TypeError))
- 				return -1;
  		}
- 		else
- 			retval = -1;
  	}
- 	else
- 		retval = -1;
  
- 	if (retval < 0) {
- 		PyErr_SetString(PyExc_TypeError,
- 				"isinstance() arg 2 must be a class or type "
- 				"or tuple of those");
- 	}
  	return retval;
  }
--- 1833,1846 ----
  		}
  		icls = PyObject_GetAttr(inst, __class__);
! 		if (icls == NULL) {
! 			PyErr_Clear();
! 			retval = 0;
! 		}
! 		else {
! 			retval = abstract_issubclass(icls, cls);
  			Py_DECREF(icls);
  		}
  	}
  
  	return retval;
  }
***************
*** 1854,1858 ****
  
  	if (!PyClass_Check(derived) || !PyClass_Check(cls)) {
! 		retval = abstract_issubclass(derived, cls, 1);
  	}
  	else {
--- 1852,1875 ----
  
  	if (!PyClass_Check(derived) || !PyClass_Check(cls)) {
! 		PyObject *derived_bases;
! 		PyObject *cls_bases;
! 	       
! 		derived_bases = abstract_get_bases(derived);
! 		if (derived_bases == NULL) {
! 			PyErr_SetString(PyExc_TypeError, 
! 					"issubclass() arg 1 must be a class");
! 			return -1;
! 		}
! 		Py_DECREF(derived_bases);
! 
! 		cls_bases = abstract_get_bases(cls);
! 		if (cls_bases == NULL) {
! 			PyErr_SetString(PyExc_TypeError, 
! 					"issubclass() arg 2 must be a class");
! 			return -1;
! 		}
! 		Py_DECREF(cls_bases);
! 
! 		retval = abstract_issubclass(derived, cls);
  	}
  	else {