|
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 |