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