Show More
@@ -125,13 +125,60 b" __all__ = ['pretty', 'pprint', 'PrettyPrinter', 'RepresentationPrinter'," | |||||
125 |
|
125 | |||
126 | _re_pattern_type = type(re.compile('')) |
|
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 | ||||
128 | def _safe_repr(obj): |
|
165 | def _safe_repr(obj): | |
129 |
"""Don't |
|
166 | """Don't assume repr is not broken.""" | |
130 | try: |
|
167 | try: | |
131 | return repr(obj) |
|
168 | return repr(obj) | |
132 | except Exception as e: |
|
169 | except Exception as e: | |
133 |
return |
|
170 | return _failed_repr(obj, e) | |
134 |
|
171 | |||
|
172 | def _safe_getattr(obj, attr, default=None): | |||
|
173 | """never-raise version of getattr | |||
|
174 | ||||
|
175 | catches errors other than AttributeError, | |||
|
176 | unlike vanilla getattr | |||
|
177 | """ | |||
|
178 | try: | |||
|
179 | return getattr(obj, attr) | |||
|
180 | except Exception: | |||
|
181 | return default | |||
135 |
|
182 | |||
136 | def pretty(obj, verbose=False, max_width=79, newline='\n'): |
|
183 | def pretty(obj, verbose=False, max_width=79, newline='\n'): | |
137 | """ |
|
184 | """ | |
@@ -353,7 +400,7 b' class RepresentationPrinter(PrettyPrinter):' | |||||
353 | self.stack.append(obj_id) |
|
400 | self.stack.append(obj_id) | |
354 | self.begin_group() |
|
401 | self.begin_group() | |
355 | try: |
|
402 | try: | |
356 | obj_class = getattr(obj, '__class__', None) or type(obj) |
|
403 | obj_class = _safe_getattr(obj, '__class__', None) or type(obj) | |
357 | # First try to find registered singleton printers for the type. |
|
404 | # First try to find registered singleton printers for the type. | |
358 | try: |
|
405 | try: | |
359 | printer = self.singleton_pprinters[obj_id] |
|
406 | printer = self.singleton_pprinters[obj_id] | |
@@ -395,8 +442,8 b' class RepresentationPrinter(PrettyPrinter):' | |||||
395 | class is not in the registry. Successful matches will be moved to the |
|
442 | class is not in the registry. Successful matches will be moved to the | |
396 | regular type registry for future use. |
|
443 | regular type registry for future use. | |
397 | """ |
|
444 | """ | |
398 | mod = getattr(cls, '__module__', None) |
|
445 | mod = _safe_getattr(cls, '__module__', None) | |
399 | name = getattr(cls, '__name__', None) |
|
446 | name = _safe_getattr(cls, '__name__', None) | |
400 | key = (mod, name) |
|
447 | key = (mod, name) | |
401 | printer = None |
|
448 | printer = None | |
402 | if key in self.deferred_pprinters: |
|
449 | if key in self.deferred_pprinters: | |
@@ -499,8 +546,8 b' def _default_pprint(obj, p, cycle):' | |||||
499 | The default print function. Used if an object does not provide one and |
|
546 | The default print function. Used if an object does not provide one and | |
500 | it's none of the builtin objects. |
|
547 | it's none of the builtin objects. | |
501 | """ |
|
548 | """ | |
502 | klass = getattr(obj, '__class__', None) or type(obj) |
|
549 | klass = _safe_getattr(obj, '__class__', None) or type(obj) | |
503 | if getattr(klass, '__repr__', None) not in _baseclass_reprs: |
|
550 | if _safe_getattr(klass, '__repr__', None) not in _baseclass_reprs: | |
504 | # A user-provided repr. Find newlines and replace them with p.break_() |
|
551 | # A user-provided repr. Find newlines and replace them with p.break_() | |
505 | output = _safe_repr(obj) |
|
552 | output = _safe_repr(obj) | |
506 | for idx,output_line in enumerate(output.splitlines()): |
|
553 | for idx,output_line in enumerate(output.splitlines()): | |
@@ -665,7 +712,7 b' def _re_pattern_pprint(obj, p, cycle):' | |||||
665 |
|
712 | |||
666 | def _type_pprint(obj, p, cycle): |
|
713 | def _type_pprint(obj, p, cycle): | |
667 | """The pprint for classes and types.""" |
|
714 | """The pprint for classes and types.""" | |
668 | mod = getattr(obj, '__module__', None) |
|
715 | mod = _safe_getattr(obj, '__module__', None) | |
669 | if mod is None: |
|
716 | if mod is None: | |
670 | # Heap allocated types might not have the module attribute, |
|
717 | # Heap allocated types might not have the module attribute, | |
671 | # and others may set it to None. |
|
718 | # and others may set it to None. |
General Comments 0
You need to be logged in to leave comments.
Login now