2
2
import reprlib
3
3
4
4
5
- def _call_and_format_exception (call , x , * args ):
5
+ def _format_repr_exception (exc , obj ):
6
+ exc_name = type (exc ).__name__
6
7
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
18
22
19
23
20
24
class SafeRepr (reprlib .Repr ):
21
25
"""subclass of repr.Repr that limits the resulting size of repr()
22
26
and includes information on exceptions raised during the call.
23
27
"""
24
28
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
37
33
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 )
45
40
46
41
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 )
56
47
57
48
58
49
def safeformat (obj ):
59
50
"""return a pretty printed string for the given object.
60
51
Failing __repr__ functions of user instances will be represented
61
52
with a short exception info.
62
53
"""
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 )
64
58
65
59
66
60
def saferepr (obj , maxsize = 240 ):
@@ -70,9 +64,4 @@ def saferepr(obj, maxsize=240):
70
64
care to never raise exceptions itself. This function is a wrapper
71
65
around the Repr/reprlib functionality of the standard 2.6 lib.
72
66
"""
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