From 03290ecbf1661c0192e6abdbe00ae163af461d77 Mon Sep 17 00:00:00 2001 From: Guido van Rossum Date: Sun, 7 Oct 2001 20:54:12 +0000 Subject: 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). --- Objects/abstract.c | 17 ++++++++++++++++- Python/bltinmodule.c | 6 ++++-- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/Objects/abstract.c b/Objects/abstract.c index 4891622..33991a8 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 64afb1b..8390b7b 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 * -- cgit v0.12