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