Commit ba6cd364 authored by Raymond Hettinger's avatar Raymond Hettinger

* Updated repr.py to handle set() and frozenset().

* Factored out common code to a single private function.
* Use str.join() instead of + concatenation
* Loop over elements directly instead of using indexing
* Use % operator for formatting
parent 83ee7952
...@@ -3,19 +3,25 @@ ...@@ -3,19 +3,25 @@
__all__ = ["Repr","repr"] __all__ = ["Repr","repr"]
import __builtin__ import __builtin__
from itertools import islice
class Repr: class Repr:
def __init__(self): def __init__(self):
self.maxlevel = 6 self.maxlevel = 6
self.maxtuple = 6 self.maxtuple = 6
self.maxlist = 6 self.maxlist = 6
self.maxarray = 5 self.maxarray = 5
self.maxdict = 4 self.maxdict = 4
self.maxset = 6
self.maxfrozenset = 6
self.maxstring = 30 self.maxstring = 30
self.maxlong = 40 self.maxlong = 40
self.maxother = 20 self.maxother = 20
def repr(self, x): def repr(self, x):
return self.repr1(x, self.maxlevel) return self.repr1(x, self.maxlevel)
def repr1(self, x, level): def repr1(self, x, level):
typename = type(x).__name__ typename = type(x).__name__
if ' ' in typename: if ' ' in typename:
...@@ -30,58 +36,52 @@ class Repr: ...@@ -30,58 +36,52 @@ class Repr:
j = max(0, self.maxother-3-i) j = max(0, self.maxother-3-i)
s = s[:i] + '...' + s[len(s)-j:] s = s[:i] + '...' + s[len(s)-j:]
return s return s
def repr_tuple(self, x, level):
def _repr_iterable(self, x, level, left, right, maxiter, final=''):
n = len(x) n = len(x)
if n == 0: return '()' if level <= 0 and n:
if level <= 0: return '(...)' s = '...'
s = '' else:
for i in range(min(n, self.maxtuple)): newlevel = level - 1
if s: s = s + ', ' repr1 = self.repr1
s = s + self.repr1(x[i], level-1) pieces = [repr1(elem, newlevel) for elem in islice(x, maxiter)]
if n > self.maxtuple: s = s + ', ...' if n > maxiter: pieces.append('...')
elif n == 1: s = s + ',' s = ', '.join(pieces)
return '(' + s + ')' if n == 1 and final: s += final
return '%s%s%s' % (left, s, right)
def repr_tuple(self, x, level):
return self._repr_iterable(x, level, '(', ')', self.maxlist, ',')
def repr_list(self, x, level): def repr_list(self, x, level):
n = len(x) return self._repr_iterable(x, level, '[', ']', self.maxlist)
if n == 0: return '[]'
if level <= 0: return '[...]'
s = ''
for i in range(min(n, self.maxlist)):
if s: s = s + ', '
s = s + self.repr1(x[i], level-1)
if n > self.maxlist: s = s + ', ...'
return '[' + s + ']'
def repr_array(self, x, level): def repr_array(self, x, level):
n = len(x)
header = "array('%s', [" % x.typecode header = "array('%s', [" % x.typecode
if n == 0: return self._repr_iterable(x, level, header, '])', self.maxarray)
return header + "])"
if level <= 0: def repr_set(self, x, level):
return header + "...])" return self._repr_iterable(x, level, 'set([', '])', self.maxset)
s = ''
for i in range(min(n, self.maxarray)): def repr_frozenset(self, x, level):
if s: return self._repr_iterable(x, level, 'frozenset([', '])',
s += ', ' self.maxfrozenset)
s += self.repr1(x[i], level-1)
if n > self.maxarray:
s += ', ...'
return header + s + "])"
def repr_dict(self, x, level): def repr_dict(self, x, level):
n = len(x) n = len(x)
if n == 0: return '{}' if n == 0: return '{}'
if level <= 0: return '{...}' if level <= 0: return '{...}'
s = '' newlevel = level - 1
keys = x.keys() repr1 = self.repr1
keys.sort() pieces = []
for i in range(min(n, self.maxdict)): for key in islice(sorted(x), self.maxdict):
if s: s = s + ', ' keyrepr = repr1(key, newlevel)
key = keys[i] valrepr = repr1(x[key], newlevel)
s = s + self.repr1(key, level-1) pieces.append('%s: %s' % (keyrepr, valrepr))
s = s + ': ' + self.repr1(x[key], level-1) if n > self.maxdict: pieces.append('...')
if n > self.maxdict: s = s + ', ...' s = ', '.join(pieces)
return '{' + s + '}' return '{%s}' % (s,)
def repr_str(self, x, level): def repr_str(self, x, level):
s = __builtin__.repr(x[:self.maxstring]) s = __builtin__.repr(x[:self.maxstring])
if len(s) > self.maxstring: if len(s) > self.maxstring:
...@@ -90,6 +90,7 @@ class Repr: ...@@ -90,6 +90,7 @@ class Repr:
s = __builtin__.repr(x[:i] + x[len(x)-j:]) s = __builtin__.repr(x[:i] + x[len(x)-j:])
s = s[:i] + '...' + s[len(s)-j:] s = s[:i] + '...' + s[len(s)-j:]
return s return s
def repr_long(self, x, level): def repr_long(self, x, level):
s = __builtin__.repr(x) # XXX Hope this isn't too slow... s = __builtin__.repr(x) # XXX Hope this isn't too slow...
if len(s) > self.maxlong: if len(s) > self.maxlong:
...@@ -97,6 +98,7 @@ class Repr: ...@@ -97,6 +98,7 @@ class Repr:
j = max(0, self.maxlong-3-i) j = max(0, self.maxlong-3-i)
s = s[:i] + '...' + s[len(s)-j:] s = s[:i] + '...' + s[len(s)-j:]
return s return s
def repr_instance(self, x, level): def repr_instance(self, x, level):
try: try:
s = __builtin__.repr(x) s = __builtin__.repr(x)
......
...@@ -51,6 +51,20 @@ class ReprTests(unittest.TestCase): ...@@ -51,6 +51,20 @@ class ReprTests(unittest.TestCase):
eq(r([1, 2, 3, 4, 5, 6]), "[1, 2, 3, 4, 5, 6]") eq(r([1, 2, 3, 4, 5, 6]), "[1, 2, 3, 4, 5, 6]")
eq(r([1, 2, 3, 4, 5, 6, 7]), "[1, 2, 3, 4, 5, 6, ...]") eq(r([1, 2, 3, 4, 5, 6, 7]), "[1, 2, 3, 4, 5, 6, ...]")
# Sets give up after 6 as well
eq(r(set([])), "set([])")
eq(r(set([1])), "set([1])")
eq(r(set([1, 2, 3])), "set([1, 2, 3])")
eq(r(set([1, 2, 3, 4, 5, 6])), "set([1, 2, 3, 4, 5, 6])")
eq(r(set([1, 2, 3, 4, 5, 6, 7])), "set([1, 2, 3, 4, 5, 6, ...])")
# Frozensets give up after 6 as well
eq(r(frozenset([])), "frozenset([])")
eq(r(frozenset([1])), "frozenset([1])")
eq(r(frozenset([1, 2, 3])), "frozenset([1, 2, 3])")
eq(r(frozenset([1, 2, 3, 4, 5, 6])), "frozenset([1, 2, 3, 4, 5, 6])")
eq(r(frozenset([1, 2, 3, 4, 5, 6, 7])), "frozenset([1, 2, 3, 4, 5, 6, ...])")
# Dictionaries give up after 4. # Dictionaries give up after 4.
eq(r({}), "{}") eq(r({}), "{}")
d = {'alice': 1, 'bob': 2, 'charles': 3, 'dave': 4} d = {'alice': 1, 'bob': 2, 'charles': 3, 'dave': 4}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment