##// END OF EJS Templates
Merge pull request #4459 from minrk/bad-repr...
Thomas Kluyver -
r13489:49af4ae9 merge
parent child Browse files
Show More
@@ -202,7 +202,7 b' class FormatterABC(with_metaclass(abc.ABCMeta, object)):'
202 202 """
203 203 try:
204 204 return repr(obj)
205 except TypeError:
205 except Exception:
206 206 return None
207 207
208 208
@@ -465,10 +465,7 b' class PlainTextFormatter(BaseFormatter):'
465 465 def __call__(self, obj):
466 466 """Compute the pretty representation of the object."""
467 467 if not self.pprint:
468 try:
469 return repr(obj)
470 except TypeError:
471 return ''
468 return pretty._safe_repr(obj)
472 469 else:
473 470 # This uses use StringIO, as cStringIO doesn't handle unicode.
474 471 stream = StringIO()
@@ -125,6 +125,60 b" __all__ = ['pretty', 'pprint', 'PrettyPrinter', 'RepresentationPrinter',"
125 125
126 126 _re_pattern_type = type(re.compile(''))
127 127
128 def _failed_repr(obj, e):
129 """Render a failed repr, including the exception.
130
131 Tries to get exception and type info
132 """
133 # get exception name
134 if e.__class__.__module__ in ('exceptions', 'builtins'):
135 ename = e.__class__.__name__
136 else:
137 ename = '{}.{}'.format(
138 e.__class__.__module__,
139 e.__class__.__name__,
140 )
141 # and exception string, which sometimes fails
142 # (usually due to unicode error message)
143 try:
144 estr = str(e)
145 except Exception:
146 estr = "unknown"
147
148 # and class name
149 try:
150 klass = _safe_getattr(obj, '__class__', None) or type(obj)
151 mod = _safe_getattr(klass, '__module__', None)
152 if mod in (None, '__builtin__', 'builtins', 'exceptions'):
153 classname = klass.__name__
154 else:
155 classname = mod + '.' + klass.__name__
156 except Exception:
157 # this may be paranoid, but we already know repr is broken
158 classname = "unknown type"
159
160 # the informative repr
161 return "<repr(<{} at 0x{:x}>) failed: {}: {}>".format(
162 classname, id(obj), ename, estr,
163 )
164
165 def _safe_repr(obj):
166 """Don't assume repr is not broken."""
167 try:
168 return repr(obj)
169 except Exception as e:
170 return _failed_repr(obj, e)
171
172 def _safe_getattr(obj, attr, default=None):
173 """Safe version of getattr.
174
175 Same as getattr, but will return ``default`` on any Exception,
176 rather than raising.
177 """
178 try:
179 return getattr(obj, attr, default)
180 except Exception:
181 return default
128 182
129 183 def pretty(obj, verbose=False, max_width=79, newline='\n'):
130 184 """
@@ -346,7 +400,7 b' class RepresentationPrinter(PrettyPrinter):'
346 400 self.stack.append(obj_id)
347 401 self.begin_group()
348 402 try:
349 obj_class = getattr(obj, '__class__', None) or type(obj)
403 obj_class = _safe_getattr(obj, '__class__', None) or type(obj)
350 404 # First try to find registered singleton printers for the type.
351 405 try:
352 406 printer = self.singleton_pprinters[obj_id]
@@ -388,8 +442,8 b' class RepresentationPrinter(PrettyPrinter):'
388 442 class is not in the registry. Successful matches will be moved to the
389 443 regular type registry for future use.
390 444 """
391 mod = getattr(cls, '__module__', None)
392 name = getattr(cls, '__name__', None)
445 mod = _safe_getattr(cls, '__module__', None)
446 name = _safe_getattr(cls, '__name__', None)
393 447 key = (mod, name)
394 448 printer = None
395 449 if key in self.deferred_pprinters:
@@ -492,10 +546,10 b' def _default_pprint(obj, p, cycle):'
492 546 The default print function. Used if an object does not provide one and
493 547 it's none of the builtin objects.
494 548 """
495 klass = getattr(obj, '__class__', None) or type(obj)
496 if getattr(klass, '__repr__', None) not in _baseclass_reprs:
549 klass = _safe_getattr(obj, '__class__', None) or type(obj)
550 if _safe_getattr(klass, '__repr__', None) not in _baseclass_reprs:
497 551 # A user-provided repr. Find newlines and replace them with p.break_()
498 output = repr(obj)
552 output = _safe_repr(obj)
499 553 for idx,output_line in enumerate(output.splitlines()):
500 554 if idx:
501 555 p.break_()
@@ -658,7 +712,7 b' def _re_pattern_pprint(obj, p, cycle):'
658 712
659 713 def _type_pprint(obj, p, cycle):
660 714 """The pprint for classes and types."""
661 mod = getattr(obj, '__module__', None)
715 mod = _safe_getattr(obj, '__module__', None)
662 716 if mod is None:
663 717 # Heap allocated types might not have the module attribute,
664 718 # and others may set it to None.
@@ -673,7 +727,7 b' def _type_pprint(obj, p, cycle):'
673 727
674 728 def _repr_pprint(obj, p, cycle):
675 729 """A pprint that just redirects to the normal repr function."""
676 p.text(repr(obj))
730 p.text(_safe_repr(obj))
677 731
678 732
679 733 def _function_pprint(obj, p, cycle):
@@ -74,6 +74,10 b' class BreakingReprParent(object):'
74 74 with p.group(4,"TG: ",":"):
75 75 p.pretty(BreakingRepr())
76 76
77 class BadRepr(object):
78
79 def __repr__(self):
80 return 1/0
77 81
78 82
79 83 def test_indentation():
@@ -150,4 +154,31 b' def test_pprint_break_repr():'
150 154 """
151 155 output = pretty.pretty(BreakingReprParent())
152 156 expected = "TG: Breaking(\n ):"
153 nt.assert_equal(output, expected) No newline at end of file
157 nt.assert_equal(output, expected)
158
159 def test_bad_repr():
160 """Don't raise, even when repr fails"""
161 output = pretty.pretty(BadRepr())
162 nt.assert_in("failed", output)
163 nt.assert_in("at 0x", output)
164 nt.assert_in("test_pretty", output)
165
166 class BadException(Exception):
167 def __str__(self):
168 return -1
169
170 class ReallyBadRepr(object):
171 __module__ = 1
172 @property
173 def __class__(self):
174 raise ValueError("I am horrible")
175
176 def __repr__(self):
177 raise BadException()
178
179 def test_really_bad_repr():
180 output = pretty.pretty(ReallyBadRepr())
181 nt.assert_in("failed", output)
182 nt.assert_in("BadException: unknown", output)
183 nt.assert_in("unknown type", output)
184 No newline at end of file
General Comments 0
You need to be logged in to leave comments. Login now