1 """Redo the builtin repr() (representation) but with limits on most sizes.""" 2 3 __all__ = ["Repr","repr"] 4 5 import __builtin__ 6 from itertools import islice 7 8 class Repr: 9 10 def __init__(self): 11 self.maxlevel = 6 12 self.maxtuple = 6 13 self.maxlist = 6 14 self.maxarray = 5 15 self.maxdict = 4 16 self.maxset = 6 17 self.maxfrozenset = 6 18 self.maxdeque = 6 19 self.maxstring = 30 20 self.maxlong = 40 21 self.maxother = 20 22 23 def repr(self, x): 24 return self.repr1(x, self.maxlevel) 25 26 def repr1(self, x, level): 27 typename = type(x).__name__ 28 if ' ' in typename: 29 parts = typename.split() 30 typename = '_'.join(parts) 31 if hasattr(self, 'repr_' + typename): 32 return getattr(self, 'repr_' + typename)(x, level) 33 else: 34 s = __builtin__.repr(x) 35 if len(s) > self.maxother: 36 i = max(0, (self.maxother-3)//2) 37 j = max(0, self.maxother-3-i) 38 s = s[:i] + '...' + s[len(s)-j:] 39 return s 40 41 def _repr_iterable(self, x, level, left, right, maxiter, trail=''): 42 n = len(x) 43 if level <= 0 and n: 44 s = '...' 45 else: 46 newlevel = level - 1 47 repr1 = self.repr1 48 pieces = [repr1(elem, newlevel) for elem in islice(x, maxiter)] 49 if n > maxiter: pieces.append('...') 50 s = ', '.join(pieces) 51 if n == 1 and trail: right = trail + right 52 return '%s%s%s' % (left, s, right) 53 54 def repr_tuple(self, x, level): 55 return self._repr_iterable(x, level, '(', ')', self.maxtuple, ',') 56 57 def repr_list(self, x, level): 58 return self._repr_iterable(x, level, '[', ']', self.maxlist) 59 60 def repr_array(self, x, level): 61 header = "array('%s', [" % x.typecode 62 return self._repr_iterable(x, level, header, '])', self.maxarray) 63 64 def repr_set(self, x, level): 65 x = _possibly_sorted(x) 66 return self._repr_iterable(x, level, 'set([', '])', self.maxset) 67 68 def repr_frozenset(self, x, level): 69 x = _possibly_sorted(x) 70 return self._repr_iterable(x, level, 'frozenset([', '])', 71 self.maxfrozenset) 72 73 def repr_deque(self, x, level): 74 return self._repr_iterable(x, level, 'deque([', '])', self.maxdeque) 75 76 def repr_dict(self, x, level): 77 n = len(x) 78 if n == 0: return '{}' 79 if level <= 0: return '{...}' 80 newlevel = level - 1 81 repr1 = self.repr1 82 pieces = [] 83 for key in islice(_possibly_sorted(x), self.maxdict): 84 keyrepr = repr1(key, newlevel) 85 valrepr = repr1(x[key], newlevel) 86 pieces.append('%s: %s' % (keyrepr, valrepr)) 87 if n > self.maxdict: pieces.append('...') 88 s = ', '.join(pieces) 89 return '{%s}' % (s,) 90 91 def repr_str(self, x, level): 92 s = __builtin__.repr(x[:self.maxstring]) 93 if len(s) > self.maxstring: 94 i = max(0, (self.maxstring-3)//2) 95 j = max(0, self.maxstring-3-i) 96 s = __builtin__.repr(x[:i] + x[len(x)-j:]) 97 s = s[:i] + '...' + s[len(s)-j:] 98 return s 99 100 def repr_long(self, x, level): 101 s = __builtin__.repr(x) # XXX Hope this isn't too slow... 102 if len(s) > self.maxlong: 103 i = max(0, (self.maxlong-3)//2) 104 j = max(0, self.maxlong-3-i) 105 s = s[:i] + '...' + s[len(s)-j:] 106 return s 107 108 def repr_instance(self, x, level): 109 try: 110 s = __builtin__.repr(x) 111 # Bugs in x.__repr__() can cause arbitrary 112 # exceptions -- then make up something 113 except Exception: 114 return '<%s instance at %x>' % (x.__class__.__name__, id(x)) 115 if len(s) > self.maxstring: 116 i = max(0, (self.maxstring-3)//2) 117 j = max(0, self.maxstring-3-i) 118 s = s[:i] + '...' + s[len(s)-j:] 119 return s 120 121 122 def _possibly_sorted(x): 123 # Since not all sequences of items can be sorted and comparison 124 # functions may raise arbitrary exceptions, return an unsorted 125 # sequence in that case. 126 try: 127 return sorted(x) 128 except Exception: 129 return list(x) 130 131 aRepr = Repr() 132 repr = aRepr.repr 133