13257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel"""Redo the builtin repr() (representation) but with limits on most sizes."""
23257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel
33257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel__all__ = ["Repr","repr"]
43257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel
53257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDanielimport __builtin__
63257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDanielfrom itertools import islice
73257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel
83257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDanielclass Repr:
93257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel
103257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel    def __init__(self):
113257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel        self.maxlevel = 6
123257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel        self.maxtuple = 6
133257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel        self.maxlist = 6
143257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel        self.maxarray = 5
153257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel        self.maxdict = 4
163257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel        self.maxset = 6
173257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel        self.maxfrozenset = 6
183257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel        self.maxdeque = 6
193257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel        self.maxstring = 30
203257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel        self.maxlong = 40
213257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel        self.maxother = 20
223257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel
233257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel    def repr(self, x):
243257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel        return self.repr1(x, self.maxlevel)
253257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel
263257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel    def repr1(self, x, level):
273257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel        typename = type(x).__name__
283257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel        if ' ' in typename:
293257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel            parts = typename.split()
303257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel            typename = '_'.join(parts)
313257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel        if hasattr(self, 'repr_' + typename):
323257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel            return getattr(self, 'repr_' + typename)(x, level)
333257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel        else:
343257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel            s = __builtin__.repr(x)
353257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel            if len(s) > self.maxother:
363257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel                i = max(0, (self.maxother-3)//2)
373257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel                j = max(0, self.maxother-3-i)
383257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel                s = s[:i] + '...' + s[len(s)-j:]
393257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel            return s
403257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel
413257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel    def _repr_iterable(self, x, level, left, right, maxiter, trail=''):
423257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel        n = len(x)
433257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel        if level <= 0 and n:
443257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel            s = '...'
453257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel        else:
463257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel            newlevel = level - 1
473257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel            repr1 = self.repr1
483257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel            pieces = [repr1(elem, newlevel) for elem in islice(x, maxiter)]
493257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel            if n > maxiter:  pieces.append('...')
503257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel            s = ', '.join(pieces)
513257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel            if n == 1 and trail:  right = trail + right
523257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel        return '%s%s%s' % (left, s, right)
533257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel
543257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel    def repr_tuple(self, x, level):
553257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel        return self._repr_iterable(x, level, '(', ')', self.maxtuple, ',')
563257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel
573257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel    def repr_list(self, x, level):
583257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel        return self._repr_iterable(x, level, '[', ']', self.maxlist)
593257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel
603257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel    def repr_array(self, x, level):
613257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel        header = "array('%s', [" % x.typecode
623257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel        return self._repr_iterable(x, level, header, '])', self.maxarray)
633257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel
643257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel    def repr_set(self, x, level):
653257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel        x = _possibly_sorted(x)
663257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel        return self._repr_iterable(x, level, 'set([', '])', self.maxset)
673257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel
683257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel    def repr_frozenset(self, x, level):
693257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel        x = _possibly_sorted(x)
703257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel        return self._repr_iterable(x, level, 'frozenset([', '])',
713257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel                                   self.maxfrozenset)
723257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel
733257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel    def repr_deque(self, x, level):
743257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel        return self._repr_iterable(x, level, 'deque([', '])', self.maxdeque)
753257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel
763257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel    def repr_dict(self, x, level):
773257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel        n = len(x)
783257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel        if n == 0: return '{}'
793257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel        if level <= 0: return '{...}'
803257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel        newlevel = level - 1
813257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel        repr1 = self.repr1
823257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel        pieces = []
833257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel        for key in islice(_possibly_sorted(x), self.maxdict):
843257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel            keyrepr = repr1(key, newlevel)
853257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel            valrepr = repr1(x[key], newlevel)
863257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel            pieces.append('%s: %s' % (keyrepr, valrepr))
873257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel        if n > self.maxdict: pieces.append('...')
883257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel        s = ', '.join(pieces)
893257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel        return '{%s}' % (s,)
903257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel
913257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel    def repr_str(self, x, level):
923257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel        s = __builtin__.repr(x[:self.maxstring])
933257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel        if len(s) > self.maxstring:
943257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel            i = max(0, (self.maxstring-3)//2)
953257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel            j = max(0, self.maxstring-3-i)
963257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel            s = __builtin__.repr(x[:i] + x[len(x)-j:])
973257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel            s = s[:i] + '...' + s[len(s)-j:]
983257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel        return s
993257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel
1003257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel    def repr_long(self, x, level):
1013257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel        s = __builtin__.repr(x) # XXX Hope this isn't too slow...
1023257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel        if len(s) > self.maxlong:
1033257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel            i = max(0, (self.maxlong-3)//2)
1043257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel            j = max(0, self.maxlong-3-i)
1053257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel            s = s[:i] + '...' + s[len(s)-j:]
1063257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel        return s
1073257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel
1083257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel    def repr_instance(self, x, level):
1093257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel        try:
1103257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel            s = __builtin__.repr(x)
1113257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel            # Bugs in x.__repr__() can cause arbitrary
1123257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel            # exceptions -- then make up something
1133257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel        except Exception:
1143257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel            return '<%s instance at %x>' % (x.__class__.__name__, id(x))
1153257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel        if len(s) > self.maxstring:
1163257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel            i = max(0, (self.maxstring-3)//2)
1173257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel            j = max(0, self.maxstring-3-i)
1183257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel            s = s[:i] + '...' + s[len(s)-j:]
1193257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel        return s
1203257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel
1213257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel
1223257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDanieldef _possibly_sorted(x):
1233257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel    # Since not all sequences of items can be sorted and comparison
1243257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel    # functions may raise arbitrary exceptions, return an unsorted
1253257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel    # sequence in that case.
1263257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel    try:
1273257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel        return sorted(x)
1283257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel    except Exception:
1293257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel        return list(x)
1303257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDaniel
1313257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDanielaRepr = Repr()
1323257aa99321d745773a6bd1bd4ce7f6fafe74411Daryl McDanielrepr = aRepr.repr
133