[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 {