mirror of
https://github.com/cool-RR/PySnooper.git
synced 2026-01-23 02:14:04 +00:00
Add support for custom repr
This commit is contained in:
parent
22019f16ae
commit
4a32e77b33
4 changed files with 60 additions and 7 deletions
20
README.md
20
README.md
|
|
@ -143,7 +143,7 @@ Start all snoop lines with a prefix, to grep for them easily:
|
|||
@pysnooper.snoop(prefix='ZZZ ')
|
||||
```
|
||||
|
||||
On multi-threaded apps identify which thread are snooped in output::
|
||||
On multi-threaded apps identify which thread are snooped in output:
|
||||
|
||||
```python
|
||||
@pysnooper.snoop(thread_info=True)
|
||||
|
|
@ -151,6 +151,24 @@ On multi-threaded apps identify which thread are snooped in output::
|
|||
|
||||
PySnooper supports decorating generators.
|
||||
|
||||
You can also customize the repr of an object:
|
||||
|
||||
```python
|
||||
def large(l):
|
||||
return isinstance(l, list) and len(l) > 5
|
||||
|
||||
def print_list_size(l):
|
||||
return 'list(size={})'.format(len(l))
|
||||
|
||||
@pysnooper.snoop(custom_repr=((large, print_list_size),))
|
||||
def sum_to_x(x):
|
||||
l = list(range(x))
|
||||
return sum(l)
|
||||
|
||||
sum_to_x(10000)
|
||||
```
|
||||
|
||||
You will get `l = list(size=10000)` for the list
|
||||
|
||||
# Installation #
|
||||
|
||||
|
|
|
|||
|
|
@ -21,11 +21,11 @@ if pycompat.PY2:
|
|||
ipython_filename_pattern = re.compile('^<ipython-input-([0-9]+)-.*>$')
|
||||
|
||||
|
||||
def get_local_reprs(frame, watch=()):
|
||||
def get_local_reprs(frame, watch=(), custom_repr=()):
|
||||
code = frame.f_code
|
||||
vars_order = code.co_varnames + code.co_cellvars + code.co_freevars + tuple(frame.f_locals.keys())
|
||||
|
||||
result_items = [(key, utils.get_shortish_repr(value)) for key, value in frame.f_locals.items()]
|
||||
result_items = [(key, utils.get_shortish_repr(value, custom_repr=custom_repr)) for key, value in frame.f_locals.items()]
|
||||
result_items.sort(key=lambda key_value: vars_order.index(key_value[0]))
|
||||
result = collections.OrderedDict(result_items)
|
||||
|
||||
|
|
@ -189,6 +189,7 @@ class Tracer:
|
|||
prefix='',
|
||||
overwrite=False,
|
||||
thread_info=False,
|
||||
custom_repr=(),
|
||||
):
|
||||
self._write = get_write_function(output, overwrite)
|
||||
|
||||
|
|
@ -208,6 +209,7 @@ class Tracer:
|
|||
self.target_codes = set()
|
||||
self.target_frames = set()
|
||||
self.thread_local = threading.local()
|
||||
self.custom_repr = custom_repr
|
||||
|
||||
def __call__(self, function):
|
||||
self.target_codes.add(function.__code__)
|
||||
|
|
@ -310,7 +312,7 @@ class Tracer:
|
|||
# #
|
||||
old_local_reprs = self.frame_to_local_reprs.get(frame, {})
|
||||
self.frame_to_local_reprs[frame] = local_reprs = \
|
||||
get_local_reprs(frame, watch=self.watch)
|
||||
get_local_reprs(frame, watch=self.watch, custom_repr=self.custom_repr)
|
||||
|
||||
newish_string = ('Starting var:.. ' if event == 'call' else
|
||||
'New var:....... ')
|
||||
|
|
@ -383,7 +385,7 @@ class Tracer:
|
|||
thread_global.depth -= 1
|
||||
|
||||
if not ended_by_exception:
|
||||
return_value_repr = utils.get_shortish_repr(arg)
|
||||
return_value_repr = utils.get_shortish_repr(arg, custom_repr=self.custom_repr)
|
||||
self.write('{indent}Return value:.. {return_value_repr}'.
|
||||
format(**locals()))
|
||||
|
||||
|
|
|
|||
|
|
@ -49,9 +49,14 @@ def shitcode(s):
|
|||
)
|
||||
|
||||
|
||||
def get_shortish_repr(item):
|
||||
def get_shortish_repr(item, custom_repr=()):
|
||||
try:
|
||||
r = repr(item)
|
||||
for condition, action in custom_repr:
|
||||
if condition(item):
|
||||
r = action(item)
|
||||
break
|
||||
else:
|
||||
r = repr(item)
|
||||
except Exception:
|
||||
r = 'REPR FAILED'
|
||||
r = r.replace('\r', '').replace('\n', '')
|
||||
|
|
|
|||
|
|
@ -1131,4 +1131,32 @@ def test_generator():
|
|||
)
|
||||
|
||||
|
||||
def test_custom_repr():
|
||||
string_io = io.StringIO()
|
||||
|
||||
def large(l):
|
||||
return isinstance(l, list) and len(l) > 5
|
||||
|
||||
def print_list_size(l):
|
||||
return 'list(size={})'.format(len(l))
|
||||
|
||||
@pysnooper.snoop(string_io, custom_repr=((large, print_list_size),))
|
||||
def sum_to_x(x):
|
||||
l = list(range(x))
|
||||
return sum(l)
|
||||
|
||||
result = sum_to_x(10000)
|
||||
|
||||
output = string_io.getvalue()
|
||||
assert_output(
|
||||
output,
|
||||
(
|
||||
VariableEntry('x', '10000'),
|
||||
CallEntry(),
|
||||
LineEntry(),
|
||||
VariableEntry('l', 'list(size=10000)'),
|
||||
LineEntry(),
|
||||
ReturnEntry(),
|
||||
ReturnValueEntry('49995000'),
|
||||
)
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue