From 6bb9989ae38cd2610e661d6e8899ef58dd9562e3 Mon Sep 17 00:00:00 2001 From: "R. David Murray" Date: Sat, 20 Nov 2010 16:33:30 +0000 Subject: [PATCH] #1574217: only swallow AttributeErrors in isinstance, not everything. Patch and tests by Brian Harring, with improvements by Ralf Schmitt. --- Lib/test/test_isinstance.py | 14 ++++++++++++++ Misc/ACKS | 1 + Misc/NEWS | 3 +++ Objects/abstract.c | 15 ++++++++++++--- 4 files changed, 30 insertions(+), 3 deletions(-) diff --git a/Lib/test/test_isinstance.py b/Lib/test/test_isinstance.py index 9482e754386..50920c56560 100644 --- a/Lib/test/test_isinstance.py +++ b/Lib/test/test_isinstance.py @@ -81,6 +81,20 @@ class TestIsInstanceExceptions(unittest.TestCase): self.assertRaises(TypeError, isinstance, I(), C()) + # check that we don't mask non AttributeErrors + # see: http://bugs.python.org/issue1574217 + def test_isinstance_dont_mask_non_attribute_error(self): + class C(object): + def getclass(self): + raise RuntimeError() + __class__=property(getclass) + + c=C() + self.assertRaises(RuntimeError, isinstance, c, bool) + + # test another code path + class D: pass + self.assertRaises(RuntimeError, isinstance, c, D) # These tests are similar to above, but tickle certain code paths in diff --git a/Misc/ACKS b/Misc/ACKS index 3cb3a29595d..9c003e988eb 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -337,6 +337,7 @@ Barry Hantman Lynda Hardman Derek Harland Jason Harper +Brian Harring Larry Hastings Shane Hathaway Rycharde Hawkes diff --git a/Misc/NEWS b/Misc/NEWS index cb0e19dfb4d..76bf48126e9 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -10,6 +10,9 @@ What's New in Python 3.2 Beta 1? Core and Builtins ----------------- +- Issue #1574217: isinstance now catches only AttributeError, rather than + masking all errors. + - Issue #10391: Don't dereference invalid memory in error messages in the ast module. diff --git a/Objects/abstract.c b/Objects/abstract.c index 4eb33d3bc50..d039a9c8641 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -2500,7 +2500,12 @@ recursive_isinstance(PyObject *inst, PyObject *cls) if (retval == 0) { PyObject *c = PyObject_GetAttr(inst, __class__); if (c == NULL) { - PyErr_Clear(); + if (PyErr_ExceptionMatches(PyExc_AttributeError)) { + PyErr_Clear(); + } + else { + retval = -1; + } } else { if (c != (PyObject *)(inst->ob_type) && @@ -2518,8 +2523,12 @@ recursive_isinstance(PyObject *inst, PyObject *cls) return -1; icls = PyObject_GetAttr(inst, __class__); if (icls == NULL) { - PyErr_Clear(); - retval = 0; + if (PyErr_ExceptionMatches(PyExc_AttributeError)) { + PyErr_Clear(); + } + else { + retval = -1; + } } else { retval = abstract_issubclass(icls, cls);