#1574217: only swallow AttributeErrors in isinstance, not everything.

Patch and tests by Brian Harring, with improvements by Ralf Schmitt.
This commit is contained in:
R. David Murray 2010-11-20 16:33:30 +00:00
parent f149e45a4e
commit 6bb9989ae3
4 changed files with 30 additions and 3 deletions

View File

@ -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

View File

@ -337,6 +337,7 @@ Barry Hantman
Lynda Hardman
Derek Harland
Jason Harper
Brian Harring
Larry Hastings
Shane Hathaway
Rycharde Hawkes

View File

@ -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.

View File

@ -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);