"""Defines a safe repr function. This will always return a string of "reasonable" length |
no matter what the object does in it's own repr function. Let's examine what can go wrong |
in an arbitrary repr function. |
The default repr will return something like (on Win32 anyway): |
<foo.bar object at 0x008D5650>. Well behaved user-defined repr() methods will do similar. |
The usual expectation is that repr will return a single line string. |
|
1. However, the repr method can raise an exception of an arbitrary type. |
|
Also, the return value may not be as expected: |
2. The return value may not be a string! |
3. The return value may not be a single line string, it may contain line breaks. |
4. The method may enter a loop and never return. |
5. The return value may be enormous, eg range(100000) |
|
The standard library has a nice implementation in the repr module that will do the job, |
but the exception |
handling is silent, so the the output contains no clue that repr() call raised an |
exception. I would like to be told if repr raises an exception, it's a serious error, so |
a sublass of repr overrides the method that does repr for class instances.""" |
|
|
import repr |
import __builtin__ |
|
|
class SafeRepr(repr.Repr): |
def __init__(self, *args, **kwargs): |
repr.Repr.__init__(self, *args, **kwargs) |
|
self.maxstring = 240 |
self.maxother = 160 |
def repr_instance(self, x, level): |
try: |
|
s = str(__builtin__.repr(x)) |
except (KeyboardInterrupt, MemoryError, SystemExit): |
raise |
except Exception ,e: |
try: |
exc_name = e.__class__.__name__ |
except: |
exc_name = 'unknown' |
try: |
exc_info = str(e) |
except: |
exc_info = 'unknown' |
return '<[%s("%s") raised in repr()] %s object at 0x%x>' % \ |
(exc_name, exc_info, x.__class__.__name__, id(x)) |
except: |
try: |
name = x.__class__.__name__ |
except: |
name = 'unknown' |
return '<[unknown exception raised in repr()] %s object at 0x%x>' % \ |
(name, id(x)) |
if len(s) > self.maxstring: |
i = max(0, (self.maxstring-3)//2) |
j = max(0, self.maxstring-3-i) |
s = s[:i] + '...' + s[len(s)-j:] |
return s |
|
_repr = SafeRepr().repr |
|