1import py 2import sys 3 4builtin_repr = repr 5 6reprlib = py.builtin._tryimport('repr', 'reprlib') 7 8class SafeRepr(reprlib.Repr): 9 """ subclass of repr.Repr that limits the resulting size of repr() 10 and includes information on exceptions raised during the call. 11 """ 12 def repr(self, x): 13 return self._callhelper(reprlib.Repr.repr, self, x) 14 15 def repr_unicode(self, x, level): 16 # Strictly speaking wrong on narrow builds 17 def repr(u): 18 if "'" not in u: 19 return py.builtin._totext("'%s'") % u 20 elif '"' not in u: 21 return py.builtin._totext('"%s"') % u 22 else: 23 return py.builtin._totext("'%s'") % u.replace("'", r"\'") 24 s = repr(x[:self.maxstring]) 25 if len(s) > self.maxstring: 26 i = max(0, (self.maxstring-3)//2) 27 j = max(0, self.maxstring-3-i) 28 s = repr(x[:i] + x[len(x)-j:]) 29 s = s[:i] + '...' + s[len(s)-j:] 30 return s 31 32 def repr_instance(self, x, level): 33 return self._callhelper(builtin_repr, x) 34 35 def _callhelper(self, call, x, *args): 36 try: 37 # Try the vanilla repr and make sure that the result is a string 38 s = call(x, *args) 39 except py.builtin._sysex: 40 raise 41 except: 42 cls, e, tb = sys.exc_info() 43 exc_name = getattr(cls, '__name__', 'unknown') 44 try: 45 exc_info = str(e) 46 except py.builtin._sysex: 47 raise 48 except: 49 exc_info = 'unknown' 50 return '<[%s("%s") raised in repr()] %s object at 0x%x>' % ( 51 exc_name, exc_info, x.__class__.__name__, id(x)) 52 else: 53 if len(s) > self.maxsize: 54 i = max(0, (self.maxsize-3)//2) 55 j = max(0, self.maxsize-3-i) 56 s = s[:i] + '...' + s[len(s)-j:] 57 return s 58 59def saferepr(obj, maxsize=240): 60 """ return a size-limited safe repr-string for the given object. 61 Failing __repr__ functions of user instances will be represented 62 with a short exception info and 'saferepr' generally takes 63 care to never raise exceptions itself. This function is a wrapper 64 around the Repr/reprlib functionality of the standard 2.6 lib. 65 """ 66 # review exception handling 67 srepr = SafeRepr() 68 srepr.maxstring = maxsize 69 srepr.maxsize = maxsize 70 srepr.maxother = 160 71 return srepr.repr(obj) 72