22import reprlib
33
44
5- def _call_and_format_exception (call , x , * args ):
5+ def _format_repr_exception (exc , obj ):
6+ exc_name = type (exc ).__name__
67 try :
7- # Try the vanilla repr and make sure that the result is a string
8- return call (x , * args )
9- except Exception as exc :
10- exc_name = type (exc ).__name__
11- try :
12- exc_info = str (exc )
13- except Exception :
14- exc_info = "unknown"
15- return '<[{}("{}") raised in repr()] {} object at 0x{:x}>' .format (
16- exc_name , exc_info , x .__class__ .__name__ , id (x )
17- )
8+ exc_info = str (exc )
9+ except Exception :
10+ exc_info = "unknown"
11+ return '<[{}("{}") raised in repr()] {} object at 0x{:x}>' .format (
12+ exc_name , exc_info , obj .__class__ .__name__ , id (obj )
13+ )
14+
15+
16+ def _ellipsize (s , maxsize ):
17+ if len (s ) > maxsize :
18+ i = max (0 , (maxsize - 3 ) // 2 )
19+ j = max (0 , maxsize - 3 - i )
20+ return s [:i ] + "..." + s [len (s ) - j :]
21+ return s
1822
1923
2024class SafeRepr (reprlib .Repr ):
2125 """subclass of repr.Repr that limits the resulting size of repr()
2226 and includes information on exceptions raised during the call.
2327 """
2428
25- def repr (self , x ):
26- return self ._callhelper (reprlib .Repr .repr , self , x )
27-
28- def repr_unicode (self , x , level ):
29- # Strictly speaking wrong on narrow builds
30- def repr (u ):
31- if "'" not in u :
32- return "'%s'" % u
33- elif '"' not in u :
34- return '"%s"' % u
35- else :
36- return "'%s'" % u .replace ("'" , r"\'" )
29+ def __init__ (self , maxsize ):
30+ super ().__init__ ()
31+ self .maxstring = maxsize
32+ self .maxsize = maxsize
3733
38- s = repr (x [: self .maxstring ])
39- if len (s ) > self .maxstring :
40- i = max (0 , (self .maxstring - 3 ) // 2 )
41- j = max (0 , self .maxstring - 3 - i )
42- s = repr (x [:i ] + x [len (x ) - j :])
43- s = s [:i ] + "..." + s [len (s ) - j :]
44- return s
34+ def repr (self , x ):
35+ try :
36+ s = super ().repr (x )
37+ except Exception as exc :
38+ s = _format_repr_exception (exc , x )
39+ return _ellipsize (s , self .maxsize )
4540
4641 def repr_instance (self , x , level ):
47- return self ._callhelper (repr , x )
48-
49- def _callhelper (self , call , x , * args ):
50- s = _call_and_format_exception (call , x , * args )
51- if len (s ) > self .maxsize :
52- i = max (0 , (self .maxsize - 3 ) // 2 )
53- j = max (0 , self .maxsize - 3 - i )
54- s = s [:i ] + "..." + s [len (s ) - j :]
55- return s
42+ try :
43+ s = repr (x )
44+ except Exception as exc :
45+ s = _format_repr_exception (exc , x )
46+ return _ellipsize (s , self .maxsize )
5647
5748
5849def safeformat (obj ):
5950 """return a pretty printed string for the given object.
6051 Failing __repr__ functions of user instances will be represented
6152 with a short exception info.
6253 """
63- return _call_and_format_exception (pprint .pformat , obj )
54+ try :
55+ return pprint .pformat (obj )
56+ except Exception as exc :
57+ return _format_repr_exception (exc , obj )
6458
6559
6660def saferepr (obj , maxsize = 240 ):
@@ -70,9 +64,4 @@ def saferepr(obj, maxsize=240):
7064 care to never raise exceptions itself. This function is a wrapper
7165 around the Repr/reprlib functionality of the standard 2.6 lib.
7266 """
73- # review exception handling
74- srepr = SafeRepr ()
75- srepr .maxstring = maxsize
76- srepr .maxsize = maxsize
77- srepr .maxother = 160
78- return srepr .repr (obj )
67+ return SafeRepr (maxsize ).repr (obj )
0 commit comments