diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst index 15f7dd1..5224df6 100644 --- a/Doc/library/functions.rst +++ b/Doc/library/functions.rst @@ -466,7 +466,7 @@ are always available. They are listed here in alphabetical order. The arguments are an object and a string. The result is ``True`` if the string is the name of one of the object's attributes, ``False`` if not. (This is implemented by calling ``getattr(object, name)`` and seeing whether it raises an - exception or not.) + AttributeError or not.) .. function:: hash(object) diff --git a/Lib/test/test_builtin.py b/Lib/test/test_builtin.py index b25f3c4..d2c9cad 100644 --- a/Lib/test/test_builtin.py +++ b/Lib/test/test_builtin.py @@ -506,6 +506,26 @@ class BuiltinTest(unittest.TestCase): raise SystemExit self.assertRaises(SystemExit, hasattr, B(), "b") + + class TestException(Exception): + pass + + class C: + @property + def attr1(self): + self['foo'] + + def __getattr__(self, name): + if name == 'attr2': + raise AttributeError('attr2') + + if name == 'attr3': + raise TestException('attr3') + + self.assertRaises(TypeError, hasattr, C(), 'attr1') + self.assertEqual(False, hasattr(C(), 'attr2')) + self.assertRaises(TestException, hasattr, C(), 'attr3') + def test_hash(self): hash(None) self.assertEqual(hash(1), hash(1)) diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c index e1f2931..e67b655 100644 --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -893,7 +893,7 @@ builtin_hasattr(PyObject *self, PyObject *args) } v = PyObject_GetAttr(v, name); if (v == NULL) { - if (!PyErr_ExceptionMatches(PyExc_Exception)) + if (!PyErr_ExceptionMatches(PyExc_AttributeError)) return NULL; else { PyErr_Clear();