summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Include/abstract.h7
-rw-r--r--Objects/abstract.c112
-rw-r--r--Python/bltinmodule.c102
3 files changed, 125 insertions, 96 deletions
diff --git a/Include/abstract.h b/Include/abstract.h
index 2c0e735..e0765e5 100644
--- a/Include/abstract.h
+++ b/Include/abstract.h
@@ -1074,6 +1074,13 @@ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
*/
+DL_IMPORT(int) PyObject_IsInstance(PyObject *object, PyObject *typeorclass);
+ /* isinstance(object, typeorclass) */
+
+DL_IMPORT(int) PyObject_IsSubclass(PyObject *object, PyObject *typeorclass);
+ /* issubclass(object, typeorclass) */
+
+
#ifdef __cplusplus
}
#endif
diff --git a/Objects/abstract.c b/Objects/abstract.c
index 1189ae8..3ccac71 100644
--- a/Objects/abstract.c
+++ b/Objects/abstract.c
@@ -1626,3 +1626,115 @@ PyObject_CallMethod(PyObject *o, char *name, char *format, ...)
return retval;
}
+
+
+/* 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;
+ }
+
+ Py_DECREF(bases);
+
+ return r;
+}
+
+int
+PyObject_IsInstance(PyObject *inst, PyObject *cls)
+{
+ PyObject *icls;
+ static PyObject *__class__ = NULL;
+ 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)) {
+ retval = ((PyObject *)(inst->ob_type) == cls);
+ }
+ else if (!PyInstance_Check(inst)) {
+ if (__class__ == NULL) {
+ __class__ = PyString_FromString("__class__");
+ if (__class__ == NULL)
+ return -1;
+ }
+ 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");
+ }
+ return retval;
+}
+
+int
+PyObject_IsSubclass(PyObject *derived, PyObject *cls)
+{
+ int retval;
+
+ if (!PyClass_Check(derived) || !PyClass_Check(cls)) {
+ retval = abstract_issubclass(derived, cls, 1);
+ }
+ else {
+ /* shortcut */
+ if (!(retval = (derived == cls)))
+ retval = PyClass_IsSubclass(derived, cls);
+ }
+
+ return retval;
+}
diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c
index e5db11e..ec680d1 100644
--- a/Python/bltinmodule.c
+++ b/Python/bltinmodule.c
@@ -2005,101 +2005,19 @@ static char vars_doc[] =
Without arguments, equivalent to locals().\n\
With an argument, equivalent to object.__dict__.";
-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;
- }
-
- Py_DECREF(bases);
-
- return r;
-}
-
static PyObject *
builtin_isinstance(PyObject *self, PyObject *args)
{
PyObject *inst;
PyObject *cls;
- PyObject *icls;
- static PyObject *__class__ = NULL;
- int retval = 0;
+ int retval;
if (!PyArg_ParseTuple(args, "OO:isinstance", &inst, &cls))
return NULL;
- 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)) {
- retval = ((PyObject *)(inst->ob_type) == cls);
- }
- else if (!PyInstance_Check(inst)) {
- if (__class__ == NULL) {
- __class__ = PyString_FromString("__class__");
- if (__class__ == NULL)
- return NULL;
- }
- 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 NULL;
- }
- else
- retval = -1;
- }
- else
- retval = -1;
-
- if (retval < 0) {
- PyErr_SetString(PyExc_TypeError,
- "isinstance() arg 2 must be a class or type");
+ retval = PyObject_IsInstance(inst, cls);
+ if (retval < 0)
return NULL;
- }
return PyInt_FromLong(retval);
}
@@ -2120,17 +2038,9 @@ builtin_issubclass(PyObject *self, PyObject *args)
if (!PyArg_ParseTuple(args, "OO:issubclass", &derived, &cls))
return NULL;
- if (!PyClass_Check(derived) || !PyClass_Check(cls)) {
- retval = abstract_issubclass(derived, cls, 1);
- if (retval < 0)
- return NULL;
- }
- else {
- /* shortcut */
- if (!(retval = (derived == cls)))
- retval = PyClass_IsSubclass(derived, cls);
- }
-
+ retval = PyObject_IsSubclass(derived, cls);
+ if (retval < 0)
+ return NULL;
return PyInt_FromLong(retval);
}