Skip to content

Commit 4b23f85

Browse files
authored
Merge pull request #78 from getslash/feature/blacklist-repr
Add configuration for blacklisted repr types (closes #77)
2 parents 68e5854 + d7a345f commit 4b23f85

File tree

2 files changed

+30
-10
lines changed

2 files changed

+30
-10
lines changed

backslash/contrib/utils.py

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@
55

66
from .._compat import PY2
77

8+
try:
9+
from slash import config as slash_config
10+
except ImportError:
11+
slash_config = None
12+
813

914
_SPECIAL_DIRS = ('.git', '.hg', '.svn')
1015

@@ -42,12 +47,23 @@ def _is_ipython_frame(frame):
4247
return 'ipython-input' in frame['filename'] and frame['lineno'] == 1
4348

4449
def distill_object_attributes(obj, truncate=True):
50+
repr_blacklisted_types = _get_repr_blacklisted_types()
4551

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)
4754
for attr, value in _iter_distilled_object_attributes(obj)}
4855

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+
4964
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)
5167
for frame in returned:
5268
if _is_ipython_frame(frame):
5369
commands = frame['locals'].get('In', {}).get('value', None)
@@ -65,18 +81,18 @@ def distill_slash_traceback(err, line_radius=5):
6581
frame['code_lines_before'], _, frame['code_lines_after'] = _splice_lines(lines, lineno - 1, line_radius)
6682
return returned
6783

68-
def _extract_frames(traceback):
84+
def _extract_frames(traceback, repr_blacklisted_types):
6985
returned = traceback.to_list()
7086
for frame, distilled_dict in zip(traceback.frames, returned):
7187
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)
7490
return returned
7591

76-
def _capture_locals(frame):
92+
def _capture_locals(frame, repr_blacklisted_types):
7793
if frame is None:
7894
return None
79-
return {local_name: {"value": _safe_repr(local_value)}
95+
return {local_name: {"value": _safe_repr(local_value, repr_blacklisted_types)}
8096
for key, value in frame.f_locals.items()
8197
if "@" not in key
8298
for local_name, local_value in _unwrap_object_variable(key, value)}
@@ -106,11 +122,11 @@ def _iter_distilled_object_attributes(obj):
106122
continue
107123
yield attr, value
108124

109-
def _capture_globals(frame):
125+
def _capture_globals(frame, repr_blacklisted_types):
110126
if frame is None:
111127
return None
112128
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)})
114130
for global_name, value in frame.f_globals.items()
115131
if global_name in used_globals and _is_global_included(value))
116132

@@ -144,7 +160,10 @@ def _nested_assign(dictionary, key, value):
144160
else:
145161
dictionary = dictionary.setdefault(part, {})
146162

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+
148167
try:
149168
returned = repr(value)
150169
except Exception: # pylint: disable=broad-except

docs/changelog.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
Changelog
22
=========
33

4+
* :feature:`77` backslash-python now honors Slash's blacklist for performing ``repr`` on traceback distilling, if available
45
* :release:`2.36.0 <7-5-2018>`
56
* :feature:`72` Avoid reporting session_start once a session already exists
67
* :release:`2.35.0 <3-5-2018>`

0 commit comments

Comments
 (0)