Skip to content

Commit cde8b1b

Browse files
committed
Two new built-in functions: issubclass() and isinstance(). Both take
classes as their second arguments. The former takes a class as the first argument and returns true iff first is second, or is a subclass of second. The latter takes any object as the first argument and returns true iff first is an instance of the second, or any subclass of second. Also, change all occurances of pointer compares against PyExc_IndexError with PyErr_ExceptionMatches() calls.
1 parent 21c5c8f commit cde8b1b

File tree

1 file changed

+59
-5
lines changed

1 file changed

+59
-5
lines changed

Python/bltinmodule.c

Lines changed: 59 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ builtin_filter(self, args)
169169
if ((item = (*sqf->sq_item)(seq, i)) == NULL) {
170170
if (i < len)
171171
goto Fail_1;
172-
if (PyErr_Occurred() == PyExc_IndexError) {
172+
if (PyErr_ExceptionMatches(PyExc_IndexError)) {
173173
PyErr_Clear();
174174
break;
175175
}
@@ -726,8 +726,9 @@ builtin_map(self, args)
726726
if (item == NULL) {
727727
if (i < sqp->len)
728728
goto Fail_0;
729-
if (PyErr_Occurred() ==
730-
PyExc_IndexError) {
729+
if (PyErr_ExceptionMatches(
730+
PyExc_IndexError))
731+
{
731732
PyErr_Clear();
732733
Py_INCREF(Py_None);
733734
item = Py_None;
@@ -1067,7 +1068,7 @@ min_max(args, sign)
10671068
for (i = 0; ; i++) {
10681069
x = (*sq->sq_item)(v, i); /* Implies INCREF */
10691070
if (x == NULL) {
1070-
if (PyErr_Occurred() == PyExc_IndexError) {
1071+
if (PyErr_ExceptionMatches(PyExc_IndexError)) {
10711072
PyErr_Clear();
10721073
break;
10731074
}
@@ -1415,7 +1416,7 @@ builtin_reduce(self, args)
14151416
}
14161417

14171418
if ((op2 = (*sqf->sq_item)(seq, i)) == NULL) {
1418-
if (PyErr_Occurred() == PyExc_IndexError) {
1419+
if (PyErr_ExceptionMatches(PyExc_IndexError)) {
14191420
PyErr_Clear();
14201421
break;
14211422
}
@@ -1613,6 +1614,57 @@ builtin_vars(self, args)
16131614
return d;
16141615
}
16151616

1617+
static PyObject *
1618+
builtin_isinstance(self, args)
1619+
PyObject *self;
1620+
PyObject *args;
1621+
{
1622+
PyObject *inst;
1623+
PyObject *cls;
1624+
int retval;
1625+
1626+
if (!PyArg_ParseTuple(args, "OO", &inst, &cls))
1627+
return NULL;
1628+
if (!PyClass_Check(cls)) {
1629+
PyErr_SetString(PyExc_TypeError,
1630+
"second argument must be a class");
1631+
return NULL;
1632+
}
1633+
1634+
if (!PyInstance_Check(inst))
1635+
retval = 0;
1636+
else {
1637+
PyObject *inclass =
1638+
(PyObject*)((PyInstanceObject*)inst)->in_class;
1639+
retval = PyClass_IsSubclass(inclass, cls);
1640+
}
1641+
return PyInt_FromLong(retval);
1642+
}
1643+
1644+
1645+
static PyObject *
1646+
builtin_issubclass(self, args)
1647+
PyObject *self;
1648+
PyObject *args;
1649+
{
1650+
PyObject *derived;
1651+
PyObject *cls;
1652+
int retval;
1653+
1654+
if (!PyArg_ParseTuple(args, "OO", &derived, &cls))
1655+
return NULL;
1656+
if (!PyClass_Check(derived) || !PyClass_Check(cls)) {
1657+
PyErr_SetString(PyExc_TypeError, "arguments must be classes");
1658+
return NULL;
1659+
}
1660+
/* shortcut */
1661+
if (!(retval = (derived == cls)))
1662+
retval = PyClass_IsSubclass(derived, cls);
1663+
1664+
return PyInt_FromLong(retval);
1665+
}
1666+
1667+
16161668
static PyMethodDef builtin_methods[] = {
16171669
{"__import__", builtin___import__, 1},
16181670
{"abs", builtin_abs, 1},
@@ -1641,6 +1693,8 @@ static PyMethodDef builtin_methods[] = {
16411693
{"input", builtin_input, 1},
16421694
{"intern", builtin_intern, 1},
16431695
{"int", builtin_int, 1},
1696+
{"isinstance", builtin_isinstance, 1},
1697+
{"issubclass", builtin_issubclass, 1},
16441698
{"len", builtin_len, 1},
16451699
{"list", builtin_list, 1},
16461700
{"locals", builtin_locals, 1},

0 commit comments

Comments
 (0)