From 5a80f8ab95c5f5745803aa794cf5ddbe9adf424d 2013-10-30 22:09:53
From: MinRK <benjaminrk@gmail.com>
Date: 2013-10-30 22:09:53
Subject: [PATCH] test really bad repr

---

diff --git a/IPython/lib/pretty.py b/IPython/lib/pretty.py
index 9f20a17..2da3dd8 100644
--- a/IPython/lib/pretty.py
+++ b/IPython/lib/pretty.py
@@ -170,13 +170,13 @@ def _safe_repr(obj):
         return _failed_repr(obj, e)
 
 def _safe_getattr(obj, attr, default=None):
-    """never-raise version of getattr
+    """Safe version of getattr.
     
-    catches errors other than AttributeError,
-    unlike vanilla getattr
+    Same as getattr, but will return ``default`` on any Exception,
+    rather than raising.
     """
     try:
-        return getattr(obj, attr)
+        return getattr(obj, attr, default)
     except Exception:
         return default
 
diff --git a/IPython/lib/tests/test_pretty.py b/IPython/lib/tests/test_pretty.py
index 49c6bd3..0df3448 100644
--- a/IPython/lib/tests/test_pretty.py
+++ b/IPython/lib/tests/test_pretty.py
@@ -160,3 +160,25 @@ def test_bad_repr():
     """Don't raise, even when repr fails"""
     output = pretty.pretty(BadRepr())
     nt.assert_in("failed", output)
+    nt.assert_in("at 0x", output)
+    nt.assert_in("test_pretty", output)
+
+class BadException(Exception):
+    def __str__(self):
+        return -1
+
+class ReallyBadRepr(object):
+    __module__ = 1
+    @property
+    def __class__(self):
+        raise ValueError("I am horrible")
+    
+    def __repr__(self):
+        raise BadException()
+
+def test_really_bad_repr():
+    output = pretty.pretty(ReallyBadRepr())
+    nt.assert_in("failed", output)
+    nt.assert_in("BadException: unknown", output)
+    nt.assert_in("unknown type", output)
+    
\ No newline at end of file