How can I extract local variables from a stack trace?

Depending on what you need, there are 2 general best practices.

Just print the variables with minimal code edits

Have a look at some related packages. For simple usage you might pick traceback-with-variables (pip install traceback-with-variables), here is it's postcard

enter image description here

Or try tbvaccine, or better-exceptions, or any other package

Programmatically access variables to use them in your code

Use inspect module

except ... as ...:
    x = inspect.trace()[-1][0].f_locals['x']

What about debugger?

Debugger is made for step-by-step execution and breakpoints. Using it to inspect exception reasons is really inconvenient and should be avoided. You can automate your debug session using two mentioned best practices.


You can also use the context manager

with ipdb.launch_ipdb_on_exception():
    main()

It's an easy-to-use wrapper using ipdb.post_mortem.


Turns out that it is possible to extract variables from a traceback object.

To manually extract values:

ipdb> !import sys
ipdb> !tb = sys.exc_info()[2]
ipdb> p tb.tb_next.tb_frame.f_locals
{'y': 0, 'x': 2}

Even better, you can use an exception to explicitly do post-mortem debugging on that stack:

import sys

def boom(x, y):
    x / y

def main():
    x = 2
    y = 0
    boom(x, y)

if __name__ == '__main__':
    try:
        main()
    except Exception as e:
        # Most debuggers allow you to just do .post_mortem()
        # but see https://github.com/gotcha/ipdb/pull/94
        tb = sys.exc_info()[2]
        import ipdb; ipdb.post_mortem(tb)

Which gets us straight to the offending code:

> /tmp/crash.py(4)boom()
      3 def boom(x, y):
----> 4     x / y
      5 

ipdb> p x
2

Tags:

Python

Pdb

Ipdb