Implement isinstance(x, (A, B, ...)). Note that we only allow tuples,

not other sequences (then we'd have to except strings, and we'd still
be susceptible to recursive attacks).
This commit is contained in:
Guido van Rossum 2001-10-07 20:54:12 +00:00
parent 1f733baa04
commit 03290ecbf1
2 changed files with 20 additions and 3 deletions

View File

@ -1805,6 +1805,20 @@ PyObject_IsInstance(PyObject *inst, PyObject *cls)
else if (PyType_Check(cls)) {
retval = PyObject_TypeCheck(inst, (PyTypeObject *)cls);
}
else if (PyTuple_Check(cls)) {
/* Not a general sequence -- that opens up the road to
recursion and stack overflow. */
int i, n;
n = PyTuple_GET_SIZE(cls);
for (i = 0; i < n; i++) {
retval = PyObject_IsInstance(
inst, PyTuple_GET_ITEM(cls, i));
if (retval != 0)
break;
}
return retval;
}
else if (!PyInstance_Check(inst)) {
if (__class__ == NULL) {
__class__ = PyString_FromString("__class__");
@ -1827,7 +1841,8 @@ PyObject_IsInstance(PyObject *inst, PyObject *cls)
if (retval < 0) {
PyErr_SetString(PyExc_TypeError,
"isinstance() arg 2 must be a class or type");
"isinstance() arg 2 must be a class or type "
"or tuple of those");
}
return retval;
}

View File

@ -1641,10 +1641,12 @@ builtin_isinstance(PyObject *self, PyObject *args)
}
static char isinstance_doc[] =
"isinstance(object, class-or-type) -> Boolean\n\
"isinstance(object, class-or-type-or-tuple) -> Boolean\n\
\n\
Return whether an object is an instance of a class or of a subclass thereof.\n\
With a type as second argument, return whether that is the object's type.";
With a type as second argument, return whether that is the object's type.\n\
The form using a tuple, isinstance(x, (A, B, ...)), is a shortcut for\n\
isinstance(x, A) or isinstance(x, B) or ... (etc.).";
static PyObject *