]> granicus.if.org Git - python/commitdiff
only catch AttributeError in hasattr() #9666
authorBenjamin Peterson <benjamin@python.org>
Tue, 24 Aug 2010 03:26:23 +0000 (03:26 +0000)
committerBenjamin Peterson <benjamin@python.org>
Tue, 24 Aug 2010 03:26:23 +0000 (03:26 +0000)
Doc/library/functions.rst
Lib/test/test_builtin.py
Misc/ACKS
Misc/NEWS
Python/bltinmodule.c

index 15f7dd19b02482283d1c6d73423aaad9a0fe4549..814bf66d655eccc8b57e1dec45b3e059005e0a3b 100644 (file)
@@ -463,10 +463,10 @@ are always available.  They are listed here in alphabetical order.
 
 .. function:: hasattr(object, name)
 
-   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.)
+   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 :exc:`AttributeError` or not.)
 
 
 .. function:: hash(object)
index aef5de8a11ec62f481b5ff376cc648e0292d2fba..4e09ca57061cfef7bd4a08689042852f1e1174dc 100644 (file)
@@ -495,15 +495,16 @@ class BuiltinTest(unittest.TestCase):
         self.assertRaises(TypeError, hasattr)
         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:
             def __getattr__(self, what):
-                raise KeyboardInterrupt
-        self.assertRaises(KeyboardInterrupt, hasattr, A(), "b")
+                raise SystemExit
+        self.assertRaises(SystemExit, hasattr, A(), "b")
         class B:
             def __getattr__(self, what):
-                raise SystemExit
-        self.assertRaises(SystemExit, hasattr, B(), "b")
+                raise ValueError
+        self.assertRaises(ValueError, hasattr, B(), "b")
 
     def test_hash(self):
         hash(None)
index eef51e3e86bc61a1afa57c2971507d0fb147a016..d1fc416807d6afcef2e5da93c53553f31d0e87ca 100644 (file)
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -730,6 +730,7 @@ Steven Scott
 Barry Scott
 Nick Seidenman
 Žiga Seilnach
+Yury Selivanov
 Fred Sells
 Jiwon Seo
 Roger D. Serwy
index 944df931fb08d3277b36856635d8883141c71fb2..5d234647edd3be440c0ec4c22e33bc64eaec9e48 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -12,6 +12,9 @@ What's New in Python 3.2 Alpha 2?
 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
   filesystem encoding.
 
index e1f2931dbc2952f82676f2fb3c07d061ab752738..3bcb08ee987cd7e4a1685140bbe439d7b947c462 100644 (file)
@@ -893,24 +893,21 @@ builtin_hasattr(PyObject *self, PyObject *args)
     }
     v = PyObject_GetAttr(v, name);
     if (v == NULL) {
-        if (!PyErr_ExceptionMatches(PyExc_Exception))
-            return NULL;
-        else {
+        if (PyErr_ExceptionMatches(PyExc_AttributeError)) {
             PyErr_Clear();
-            Py_INCREF(Py_False);
-            return Py_False;
+            Py_RETURN_FALSE;
         }
+        return NULL;
     }
     Py_DECREF(v);
-    Py_INCREF(Py_True);
-    return Py_True;
+    Py_RETURN_TRUE;
 }
 
 PyDoc_STRVAR(hasattr_doc,
 "hasattr(object, name) -> bool\n\
 \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 *