5
5
6
6
from .._compat import PY2
7
7
8
+ try :
9
+ from slash import config as slash_config
10
+ except ImportError :
11
+ slash_config = None
12
+
8
13
9
14
_SPECIAL_DIRS = ('.git' , '.hg' , '.svn' )
10
15
@@ -42,12 +47,23 @@ def _is_ipython_frame(frame):
42
47
return 'ipython-input' in frame ['filename' ] and frame ['lineno' ] == 1
43
48
44
49
def distill_object_attributes (obj , truncate = True ):
50
+ repr_blacklisted_types = _get_repr_blacklisted_types ()
45
51
46
- return {attr : value if isinstance (value , _ALLOWED_ATTRIBUTE_TYPES ) else _safe_repr (value , truncate = truncate )
52
+ return {attr : value
53
+ if isinstance (value , _ALLOWED_ATTRIBUTE_TYPES ) else _safe_repr (value , repr_blacklisted_types , truncate = truncate )
47
54
for attr , value in _iter_distilled_object_attributes (obj )}
48
55
56
+ def _get_repr_blacklisted_types ():
57
+ if slash_config is None :
58
+ return ()
59
+
60
+ log_config = slash_config .root .log
61
+ return getattr (log_config , 'repr_blacklisted_types' , ())
62
+
63
+
49
64
def distill_slash_traceback (err , line_radius = 5 ):
50
- returned = _extract_frames (err .traceback )
65
+ repr_blacklisted_types = _get_repr_blacklisted_types ()
66
+ returned = _extract_frames (err .traceback , repr_blacklisted_types )
51
67
for frame in returned :
52
68
if _is_ipython_frame (frame ):
53
69
commands = frame ['locals' ].get ('In' , {}).get ('value' , None )
@@ -65,18 +81,18 @@ def distill_slash_traceback(err, line_radius=5):
65
81
frame ['code_lines_before' ], _ , frame ['code_lines_after' ] = _splice_lines (lines , lineno - 1 , line_radius )
66
82
return returned
67
83
68
- def _extract_frames (traceback ):
84
+ def _extract_frames (traceback , repr_blacklisted_types ):
69
85
returned = traceback .to_list ()
70
86
for frame , distilled_dict in zip (traceback .frames , returned ):
71
87
if 'locals' not in distilled_dict and hasattr (frame , 'python_frame' ): # Slash 1.5.x deprecates the `locals` and `globals` attributes
72
- distilled_dict ['locals' ] = _capture_locals (frame .python_frame )
73
- distilled_dict ['globals' ] = _capture_globals (frame .python_frame )
88
+ distilled_dict ['locals' ] = _capture_locals (frame .python_frame , repr_blacklisted_types )
89
+ distilled_dict ['globals' ] = _capture_globals (frame .python_frame , repr_blacklisted_types )
74
90
return returned
75
91
76
- def _capture_locals (frame ):
92
+ def _capture_locals (frame , repr_blacklisted_types ):
77
93
if frame is None :
78
94
return None
79
- return {local_name : {"value" : _safe_repr (local_value )}
95
+ return {local_name : {"value" : _safe_repr (local_value , repr_blacklisted_types )}
80
96
for key , value in frame .f_locals .items ()
81
97
if "@" not in key
82
98
for local_name , local_value in _unwrap_object_variable (key , value )}
@@ -106,11 +122,11 @@ def _iter_distilled_object_attributes(obj):
106
122
continue
107
123
yield attr , value
108
124
109
- def _capture_globals (frame ):
125
+ def _capture_globals (frame , repr_blacklisted_types ):
110
126
if frame is None :
111
127
return None
112
128
used_globals = set (frame .f_code .co_names )
113
- return dict ((global_name , {"value" : _safe_repr (value )})
129
+ return dict ((global_name , {"value" : _safe_repr (value , repr_blacklisted_types )})
114
130
for global_name , value in frame .f_globals .items ()
115
131
if global_name in used_globals and _is_global_included (value ))
116
132
@@ -144,7 +160,10 @@ def _nested_assign(dictionary, key, value):
144
160
else :
145
161
dictionary = dictionary .setdefault (part , {})
146
162
147
- def _safe_repr (value , truncate = True ):
163
+ def _safe_repr (value , repr_blacklisted_types , truncate = True ):
164
+ if isinstance (value , repr_blacklisted_types ):
165
+ returned = "<{!r} object {:x}>" .format (type (value ).__name__ , id (value ))
166
+
148
167
try :
149
168
returned = repr (value )
150
169
except Exception : # pylint: disable=broad-except
0 commit comments