From: Guido van Rossum Date: Sun, 7 Oct 2001 20:54:12 +0000 (+0000) Subject: Implement isinstance(x, (A, B, ...)). Note that we only allow tuples, X-Git-Tag: v2.2.1c1~1407 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=03290ecbf1661c0192e6abdbe00ae163af461d77;p=python 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). --- diff --git a/Objects/abstract.c b/Objects/abstract.c index 4891622a72..33991a81cb 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -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; } diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c index 64afb1ba22..8390b7b80b 100644 --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -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 *