diff --git a/pysnooper/tracer.py b/pysnooper/tracer.py index 56165d3..773ed1f 100644 --- a/pysnooper/tracer.py +++ b/pysnooper/tracer.py @@ -15,10 +15,10 @@ import traceback from .variables import CommonVariable, Exploding, BaseVariable from . import utils, pycompat + if pycompat.PY2: from io import open - ipython_filename_pattern = re.compile('^$') @@ -38,6 +38,7 @@ def get_local_reprs(frame, watch=(), custom_repr=(), max_length=None, normalize= return result +# if it is unavailable source. class UnavailableSource(object): def __getitem__(self, i): return u'SOURCE IS UNAVAILABLE' @@ -73,7 +74,7 @@ def get_path_and_source_from_frame(frame): import IPython ipython_shell = IPython.get_ipython() ((_, _, source_chunk),) = ipython_shell.history_manager. \ - get_range(0, entry_number, entry_number + 1) + get_range(0, entry_number, entry_number + 1) source = source_chunk.splitlines() except Exception: pass @@ -148,6 +149,7 @@ class FileWriter(object): thread_global = threading.local() DISABLED = bool(os.getenv('PYSNOOPER_DISABLED', '')) + class Tracer: ''' Snoop on the function, writing everything it's doing to stderr. @@ -203,18 +205,19 @@ class Tracer: @pysnooper.snoop(relative_time=True) ''' + def __init__(self, output=None, watch=(), watch_explode=(), depth=1, prefix='', overwrite=False, thread_info=False, custom_repr=(), max_variable_length=100, normalize=False, relative_time=False): self._write = get_write_function(output, overwrite) self.watch = [ - v if isinstance(v, BaseVariable) else CommonVariable(v) - for v in utils.ensure_tuple(watch) - ] + [ - v if isinstance(v, BaseVariable) else Exploding(v) - for v in utils.ensure_tuple(watch_explode) - ] + v if isinstance(v, BaseVariable) else CommonVariable(v) + for v in utils.ensure_tuple(watch) + ] + [ + v if isinstance(v, BaseVariable) else Exploding(v) + for v in utils.ensure_tuple(watch_explode) + ] self.frame_to_local_reprs = {} self.start_times = {} self.depth = depth @@ -226,7 +229,7 @@ class Tracer: self.target_frames = set() self.thread_local = threading.local() if len(custom_repr) == 2 and not all(isinstance(x, - pycompat.collections_abc.Iterable) for x in custom_repr): + pycompat.collections_abc.Iterable) for x in custom_repr): custom_repr = (custom_repr,) self.custom_repr = custom_repr self.last_source_path = None @@ -379,7 +382,7 @@ class Tracer: start_time = self.start_times[frame] except KeyError: start_time = self.start_times[frame] = \ - datetime_module.datetime.now() + datetime_module.datetime.now() duration = datetime_module.datetime.now() - start_time timestamp = pycompat.timedelta_format(duration) else: @@ -412,27 +415,26 @@ 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, custom_repr=self.custom_repr, - max_length=self.max_variable_length, - normalize=self.normalize, - ) + get_local_reprs(frame, + watch=self.watch, custom_repr=self.custom_repr, + max_length=self.max_variable_length, + normalize=self.normalize, + ) newish_string = ('Starting var:.. ' if event == 'call' else - 'New var:....... ') + 'New var:....... ') for name, value_repr in local_reprs.items(): if name not in old_local_reprs: self.write('{indent}{newish_string}{name} = {value_repr}'.format( - **locals())) + **locals())) elif old_local_reprs[name] != value_repr: self.write('{indent}Modified var:.. {name} = {value_repr}'.format( - **locals())) + **locals())) # # ### Finished newish and modified variables. ########################### - ### Dealing with misplaced function definition: ####################### # # if event == 'call' and source_line.lstrip().startswith('@'): @@ -448,6 +450,7 @@ class Tracer: if candidate_source_line.lstrip().startswith('def'): # Found the def line! + # Save line_no and sorce line line_no = candidate_line_no source_line = candidate_source_line break @@ -473,7 +476,7 @@ class Tracer: else: self.write(u'{indent}{timestamp} {thread_info}{event:9} ' u'{line_no:4} {source_line}'.format(**locals())) - + # If meets return, write Return value of return_value_repr. if event == 'return': self.frame_to_local_reprs.pop(frame, None) self.start_times.pop(frame, None) @@ -481,9 +484,9 @@ class Tracer: if not ended_by_exception: return_value_repr = utils.get_shortish_repr(arg, - custom_repr=self.custom_repr, - max_length=self.max_variable_length, - normalize=self.normalize, + self.custom_repr, + self.max_variable_length, + self.normalize, ) self.write('{indent}Return value:.. {return_value_repr}'. format(**locals())) diff --git a/pysnooper/utils.py b/pysnooper/utils.py index ff9b9e8..ad351f7 100644 --- a/pysnooper/utils.py +++ b/pysnooper/utils.py @@ -4,9 +4,9 @@ import abc import re -import sys from .pycompat import ABC, string_types, collections_abc + def _check_methods(C, *methods): mro = C.__mro__ for method in methods: @@ -32,15 +32,13 @@ class WritableStream(ABC): return NotImplemented - file_reading_errors = ( IOError, OSError, - ValueError # IronPython weirdness. + ValueError # IronPython weirdness. ) - def shitcode(s): return ''.join( (c if (0 < ord(c) < 256) else '?') for c in s @@ -89,10 +87,7 @@ def truncate(string, max_length): def ensure_tuple(x): if isinstance(x, collections_abc.Iterable) and \ - not isinstance(x, string_types): + not isinstance(x, string_types): return tuple(x) else: return (x,) - - - diff --git a/tests/samples/exception.py b/tests/samples/exception.py index 6ca15f1..800c9e2 100644 --- a/tests/samples/exception.py +++ b/tests/samples/exception.py @@ -1,6 +1,5 @@ import pysnooper - def foo(): raise TypeError('bad') @@ -18,7 +17,6 @@ def main(): except: pass - expected_output = ''' Source path:... Whatever 12:18:08.017782 call 17 def main():