cool-RR / PySnooper

Never use print for debugging again
MIT License
16.38k stars 952 forks source link

'_thread._local' object has no attribute 'depth' raised by snooper if there's exception upon calling snooped func #195

Closed yaelmi3 closed 4 years ago

yaelmi3 commented 4 years ago
import pysnooper
@pysnooper.snoop()
def f(x):
    pass

Calling f without x

----> 1 f()

results in:

.../pysnooper/tracer.py in simple_wrapper(*args, **kwargs)
    261         def simple_wrapper(*args, **kwargs):
    262             with self:
--> 263                 return function(*args, **kwargs)
    264
    265         @functools.wraps(function)

.../pysnooper/tracer.py in __exit__(self, exc_type, exc_value, exc_traceback)
    320         duration = datetime_module.datetime.now() - start_time
    321         elapsed_time_string = pycompat.timedelta_format(duration)
--> 322         indent = ' ' * 4 * (thread_global.depth + 1)
    323         self.write(
    324             '{indent}Elapsed time: {elapsed_time_string}'.format(**locals())

AttributeError: '_thread._local' object has no attribute 'depth'

The reason is that we initialize thread_global with depthhere, while it's always used on __exit__ here:https://github.com/cool-RR/PySnooper/blob/master/pysnooper/tracer.py#L322. In case we returned before the thread_global was initialized with depth, (i.e. https://github.com/cool-RR/PySnooper/blob/master/pysnooper/tracer.py#L351), the thread_global won't have the depth attr.

cool-RR commented 4 years ago

Great catch. Would you be interested in writing a PR to fix this and add tests?

yaelmi3 commented 4 years ago

Yup :)