With normal functions calls, the program state is mostly described by a simple call stack. It is printed out as a traceback after an uncaught exception, it can be examined with inspect.stack
, and it can be displayed in a debugger after a breakpoint.
In the presence of generators, generator-based couroutines, and async def
-based coroutines, I don't think the call stack is enough. What's a good way to mentally visualize the program state? How do I inspect it in run-time?
There are functions inspect.getgeneratorstate
and inspect.getcoroutinestate
, but they only provide information about whether the generator/coroutine is created, running, suspended, or closed. In the case the state is RUNNING
, I want to be able to examine the actual line number the generator or coroutine is currently executing and the stack frames that correspond to the other functions it might have called. In the case it's SUSPENDED
, I want to examine other generators / coroutines it sent data to or yielded to.
Edit: I found a related question on SO which pointed me to this excellent article that explains everything I asked about in this question.
traceback.print_stack()
in exception handler inside anasync def
based coroutine? – Andrew Svetlov