only catch AttributeError in hasattr() #9666

This commit is contained in:
Benjamin Peterson 2010-08-24 03:26:23 +00:00
parent 9cf5ef4cc0
commit 17689991e6
5 changed files with 19 additions and 17 deletions

View file

@ -463,10 +463,10 @@ are always available. They are listed here in alphabetical order.
.. function:: hasattr(object, name) .. function:: hasattr(object, name)
The arguments are an object and a string. The result is ``True`` if the string The arguments are an object and a string. The result is ``True`` if the
is the name of one of the object's attributes, ``False`` if not. (This is string is the name of one of the object's attributes, ``False`` if not. (This
implemented by calling ``getattr(object, name)`` and seeing whether it raises an is implemented by calling ``getattr(object, name)`` and seeing whether it
exception or not.) raises an :exc:`AttributeError` or not.)
.. function:: hash(object) .. function:: hash(object)

View file

@ -495,15 +495,16 @@ class BuiltinTest(unittest.TestCase):
self.assertRaises(TypeError, hasattr) self.assertRaises(TypeError, hasattr)
self.assertEqual(False, hasattr(sys, chr(sys.maxunicode))) self.assertEqual(False, hasattr(sys, chr(sys.maxunicode)))
# Check that hasattr allows SystemExit and KeyboardInterrupts by # Check that hasattr propagates all exceptions outside of
# AttributeError.
class A: class A:
def __getattr__(self, what): def __getattr__(self, what):
raise KeyboardInterrupt raise SystemExit
self.assertRaises(KeyboardInterrupt, hasattr, A(), "b") self.assertRaises(SystemExit, hasattr, A(), "b")
class B: class B:
def __getattr__(self, what): def __getattr__(self, what):
raise SystemExit raise ValueError
self.assertRaises(SystemExit, hasattr, B(), "b") self.assertRaises(ValueError, hasattr, B(), "b")
def test_hash(self): def test_hash(self):
hash(None) hash(None)

View file

@ -730,6 +730,7 @@ Steven Scott
Barry Scott Barry Scott
Nick Seidenman Nick Seidenman
Žiga Seilnach Žiga Seilnach
Yury Selivanov
Fred Sells Fred Sells
Jiwon Seo Jiwon Seo
Roger D. Serwy Roger D. Serwy

View file

@ -12,6 +12,9 @@ What's New in Python 3.2 Alpha 2?
Core and Builtins Core and Builtins
----------------- -----------------
- Issue #9666: Only catch AttributeError in hasattr(). All other exceptions that
occur during attribute lookup are now propagated to the caller.
- Issue #8622: Add PYTHONFSENCODING environment variable to override the - Issue #8622: Add PYTHONFSENCODING environment variable to override the
filesystem encoding. filesystem encoding.

View file

@ -893,24 +893,21 @@ builtin_hasattr(PyObject *self, PyObject *args)
} }
v = PyObject_GetAttr(v, name); v = PyObject_GetAttr(v, name);
if (v == NULL) { if (v == NULL) {
if (!PyErr_ExceptionMatches(PyExc_Exception)) if (PyErr_ExceptionMatches(PyExc_AttributeError)) {
return NULL;
else {
PyErr_Clear(); PyErr_Clear();
Py_INCREF(Py_False); Py_RETURN_FALSE;
return Py_False;
} }
return NULL;
} }
Py_DECREF(v); Py_DECREF(v);
Py_INCREF(Py_True); Py_RETURN_TRUE;
return Py_True;
} }
PyDoc_STRVAR(hasattr_doc, PyDoc_STRVAR(hasattr_doc,
"hasattr(object, name) -> bool\n\ "hasattr(object, name) -> bool\n\
\n\ \n\
Return whether the object has an attribute with the given name.\n\ Return whether the object has an attribute with the given name.\n\
(This is done by calling getattr(object, name) and catching exceptions.)"); (This is done by calling getattr(object, name) and catching AttributeError.)");
static PyObject * static PyObject *