Enable snoop during a recursive trace
skeledrew opened this issue · 7 comments
Hi,
I'm working on a debugging toolbox which includes snoop (as well as Birdseye). One of the features is to automatically wrap a function that raises while tracing and, since there's no way to move execution back to the point before the function was run (without maybe some arcade bytecode hacking), eval the wrapped function again during the handling of the exception. One of the things that wrapper does is wrap the function with spy
before running it again. I find that Birdseye works fine, however snoop provides no feedback. Is this the intended behavior? How can I work around it?
Running the function from the beginning again sounds very likely to cause more confusion and frustration while debugging. Any extra side effects that happen during the rerun can mislead the user.
Assuming you really want to do this (which so far I'm against) can you clarify further what you're doing? It's hard to know how you're using snoop and why it might not be working.
So the issue is I find it tedious to be always adding and removing decorators during development, so I want to automate that process. As such I've created a manager that is always tracing during development, and handles unanticipated exceptions by getting the arguments, wrapping with spy, and evaling again with those arguments. I'll also likely be adding hot reloading. Does that help? I'm aware that global changes and mutable arguments for example can lead to state corruption, and will be putting in a warning for when it seems that's likely.
Can you share some minimal code?
Sharing the entire WiP as it's a bit complex to extract a working relevant bit. Primary areas of interest are lines 112 and 226. I hope that's OK.
OK, I think I get it now. The problem is that Python itself doesn't allow recursive sys.settrace, i.e. you can't trace the code that's running during the current trace function. Here's some discussions from when PySnooper ran into this:
Oh, I see. Thanks for those references. There still remains the question re Birdseye though: why does it still work at that level? How does its mechanism differ from snoop's?
I guess perhaps what I'll end up doing is modifying the modules at import time so everything is wrapped by default. That however means I'll have to find a sane way to ignore all expected exceptions...
Ah, I've found the Birdseye "How it works". Thanks again!