source file: /home/buildslave/tahoe/edgy/build/src/allmydata/util/humanreadable.py
file stats: 73 lines, 63 executed: 86.3% covered
coverage versus previous test: 0 lines added, 0 lines removed
    1. import exceptions, os
    2. from repr import Repr
    3. 
    4. class BetterRepr(Repr):
    5.     def __init__(self):
    6.         Repr.__init__(self)
    7. 
    8.         # Note: These levels can get adjusted dynamically!  My goal is to get more info when printing important debug stuff like exceptions and stack traces and less info when logging normal events.  --Zooko 2000-10-14
    9.         self.maxlevel = 6
   10.         self.maxdict = 6
   11.         self.maxlist = 6
   12.         self.maxtuple = 6
   13.         self.maxstring = 300
   14.         self.maxother = 300
   15. 
   16.     def repr_function(self, obj, level):
   17.         if hasattr(obj, 'func_code'):
   18.             return '<' + obj.func_name + '() at ' + os.path.basename(obj.func_code.co_filename) + ':' + str(obj.func_code.co_firstlineno) + '>'
   19.         else:
   20.             return '<' + obj.func_name + '() at (builtin)'
   21. 
   22.     def repr_instance_method(self, obj, level):
   23.         if hasattr(obj, 'func_code'):
   24.             return '<' + obj.im_class.__name__ + '.' + obj.im_func.__name__ + '() at ' + os.path.basename(obj.im_func.func_code.co_filename) + ':' + str(obj.im_func.func_code.co_firstlineno) + '>'
   25.         else:
   26.             return '<' + obj.im_class.__name__ + '.' + obj.im_func.__name__ + '() at (builtin)'
   27. 
   28.     def repr_long(self, obj, level):
   29.         s = `obj` # XXX Hope this isn't too slow...
   30.         if len(s) > self.maxlong:
   31.             i = max(0, (self.maxlong-3)/2)
   32.             j = max(0, self.maxlong-3-i)
   33.             s = s[:i] + '...' + s[len(s)-j:]
   34.         if s[-1] == 'L':
   35.             return s[:-1]
   36.         return s
   37. 
   38.     def repr_instance(self, obj, level):
   39.         """
   40.         If it is an instance of Exception, format it nicely (trying to emulate
   41.         the format that you see when an exception is actually raised, plus
   42.         bracketing '<''s).  If it is an instance of dict call self.repr_dict()
   43.         on it.  If it is an instance of list call self.repr_list() on it. Else
   44.         call Repr.repr_instance().
   45.         """
   46.         if isinstance(obj, exceptions.Exception):
   47.             # Don't cut down exception strings so much.
   48.             tms = self.maxstring
   49.             self.maxstring = max(512, tms * 4)
   50.             tml = self.maxlist
   51.             self.maxlist = max(12, tml * 4)
   52.             try:
   53.                 if hasattr(obj, 'args'):
   54.                     if len(obj.args) == 1:
   55.                         return '<' + obj.__class__.__name__ + ': ' + self.repr1(obj.args[0], level-1) + '>'
   56.                     else:
   57.                         return '<' + obj.__class__.__name__ + ': ' + self.repr1(obj.args, level-1) + '>'
   58.                 else:
   59.                     return '<' + obj.__class__.__name__ + '>'
   60.             finally:
   61.                 self.maxstring = tms
   62.                 self.maxlist = tml
   63. 
   64.         if isinstance(obj, dict):
   65.             return self.repr_dict(obj, level)
   66. 
   67.         if isinstance(obj, list):
   68.             return self.repr_list(obj, level)
   69. 
   70.         return Repr.repr_instance(self, obj, level)
   71. 
   72.     def repr_list(self, obj, level):
   73.         """
   74.         copied from standard repr.py and fixed to work on multithreadedly mutating lists.
   75.         """
   76.         if level <= 0: return '[...]'
   77.         n = len(obj)
   78.         myl = obj[:min(n, self.maxlist)]
   79.         s = ''
   80.         for item in myl:
   81.             entry = self.repr1(item, level-1)
   82.             if s: s = s + ', '
   83.             s = s + entry
   84.         if n > self.maxlist: s = s + ', ...'
   85.         return '[' + s + ']'
   86. 
   87.     def repr_dict(self, obj, level):
   88.         """
   89.         copied from standard repr.py and fixed to work on multithreadedly mutating dicts.
   90.         """
   91.         if level <= 0: return '{...}'
   92.         s = ''
   93.         n = len(obj)
   94.         items = obj.items()[:min(n, self.maxdict)]
   95.         items.sort()
   96.         for key, val in items:
   97.             entry = self.repr1(key, level-1) + ':' + self.repr1(val, level-1)
   98.             if s: s = s + ', '
   99.             s = s + entry
  100.         if n > self.maxdict: s = s + ', ...'
  101.         return '{' + s + '}'
  102. 
  103. # This object can be changed by other code updating this module's "brepr"
  104. # variables.  This is so that (a) code can use humanreadable with
  105. # "from humanreadable import hr; hr(mything)", and (b) code can override
  106. # humanreadable to provide application-specific human readable output
  107. # (e.g. libbase32's base32id.AbbrevRepr).
  108. brepr = BetterRepr()
  109. 
  110. def hr(x):
  111.     return brepr.repr(x)