source: trunk/src/allmydata/util/humanreadable.py

Last change on this file was 1cfe843d, checked in by Alexandre Detiste <alexandre.detiste@…>, at 2024-02-22T23:40:25Z

more python2 removal

  • Property mode set to 100644
File size: 4.3 KB
Line 
1"""
2Utilities for turning objects into human-readable strings.
3
4This module has been ported to Python 3.
5"""
6
7import os
8from reprlib import Repr
9
10class BetterRepr(Repr, object):
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, '__code__'):
24            return '<' + obj.__name__ + '() at ' + os.path.basename(obj.__code__.co_filename) + ':' + str(obj.__code__.co_firstlineno) + '>'
25        else:
26            return '<' + obj.__name__ + '() at (builtin)'
27
28    def repr_instance_method(self, obj, level):
29        if hasattr(obj, '__code__'):
30            return '<' + obj.__self__.__class__.__name__ + '.' + obj.__func__.__name__ + '() at ' + os.path.basename(obj.__func__.__code__.co_filename) + ':' + str(obj.__func__.__code__.co_firstlineno) + '>'
31        else:
32            return '<' + obj.__self__.__class__.__name__ + '.' + obj.__func__.__name__ + '() at (builtin)'
33
34    def repr_long(self, obj, level):
35        s = repr(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, 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 = list(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).
114brepr = BetterRepr()
115
116def hr(x):
117    return brepr.repr(x)
Note: See TracBrowser for help on using the repository browser.