From 0322982875c03d9b44ba3e5ef38863f26d8eef01 Mon Sep 17 00:00:00 2001 From: Alex Hall Date: Sun, 28 Apr 2019 12:56:57 +0200 Subject: [PATCH] More informative repr for exceptions. Forgot to use repr_instance --- pysnooper/tracer.py | 27 ++++++++++++++++++++++++--- tests/test_pysnooper.py | 27 +++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 3 deletions(-) diff --git a/pysnooper/tracer.py b/pysnooper/tracer.py index bd0ec77..87e9ffa 100644 --- a/pysnooper/tracer.py +++ b/pysnooper/tracer.py @@ -15,12 +15,33 @@ from .third_party import six ipython_filename_pattern = re.compile('^$') -repr_instance = reprlib.Repr() -repr_instance.maxother = 100 + +class MyRepr(reprlib.Repr): + def __init__(self): + super(MyRepr, self).__init__() + self.maxother = 100 + + def repr(self, x): + try: + return super(MyRepr, self).repr(x) + except Exception as e: + return '<{} instance at {:#x} (__repr__ raised {})>'.format( + x.__class__.__name__, id(x), e.__class__.__name__) + + def repr_instance(self, x, level): + s = reprlib.builtins.repr(x) + if len(s) > self.maxother: + i = max(0, (self.maxother - 3) // 2) + j = max(0, self.maxother - 3 - i) + s = s[:i] + '...' + s[len(s) - j:] + return s + + +repr_instance = MyRepr() def get_shortish_repr(item): - r = reprlib.repr(item) + r = repr_instance.repr(item) r = r.replace('\r', '').replace('\n', '') return r diff --git a/tests/test_pysnooper.py b/tests/test_pysnooper.py index 8f25373..03567c5 100644 --- a/tests/test_pysnooper.py +++ b/tests/test_pysnooper.py @@ -158,6 +158,33 @@ def test_long_variable(): ) +def test_repr_exception(): + class Bad(object): + def __repr__(self): + 1 / 0 + + @pysnooper.snoop() + def my_function(): + bad = Bad() + + with sys_tools.OutputCapturer(stdout=False, + stderr=True) as output_capturer: + result = my_function() + assert result is None + output = output_capturer.string_io.getvalue() + assert_output( + output, + ( + VariableEntry('Bad'), + CallEntry('def my_function():'), + LineEntry('bad = Bad()'), + VariableEntry('bad', value_regex=r''), + ReturnEntry(), + ReturnValueEntry('None') + ) + ) + + def test_depth(): string_io = io.StringIO()