debugging - save variable to interactive namespace from python debugger -
when running inside interactive session (in case ipython), , inside debugger (ipdb or pdb) able put variable main interactive namespace within debugging namespace.
this useful if code crashes, has done significant work, of salvageable save time (for example, loading data disk).
so i'd this, example:
>>> run -m my.module loading data disk... done loading data. processing data... --------------------------------------------------------------------------- indexerror traceback (most recent call last) ... -> here goes wrong during processing, loading of data worked fine... i'd go debugger check out happened, , see loaded_data:
>>> debug ipdb> len(loaded_data) 100000 -> able save variable interactive namespace use outside debugger, so:
ipdb> save_to_interactive('loaded_data') ipdb> exit >>> len(loaded_data) 100000
you can accomplish getting reference outer interpreter's stack frame, , writing frame globals.
given sample module breakpoint kicks pdb:
my_module.py:
def fun(arg): import pdb; pdb.set_trace() print arg example demonstrating basic concept:
>>> import my_module >>> my_module.fun(1) > /users/lukasgraf/src/stackoverflow/my_module.py(3)fun() -> print arg (pdb) import sys (pdb) sys._getframe(0) <frame object @ 0x1032ab290> # current frame (pdb) sys._getframe(0).f_globals['__name__'] 'my_module' # next outer frame (pdb) sys._getframe(1).f_globals['__name__'] 'pdb' # etc... # in example, frame 10 happens # 1 outer interpreter (pdb) sys._getframe(10).f_globals['__name__'] '__main__' so here's quick , dirty function walks stack looking '__name__' value of '__main__' in frame globals:
debughelper.py:
import sys # safe , define maximum of frames we're trying walk max_frames = 20 def save_to_interactive(dct): n = 0 # walk stack looking '__name__' # value of '__main__' in frame globals n in range(max_frames): cur_frame = sys._getframe(n) name = cur_frame.f_globals.get('__name__') if name == '__main__': # yay - we're in stack frame of interactive interpreter! # update frame globals dict containing our data cur_frame.f_globals.update(dct) break usage:
>>> import my_module >>> my_module.fun('foo') > /users/lukasgraf/src/stackoverflow/my_module.py(3)fun() -> print arg (pdb) import debughelper (pdb) debughelper.save_to_interactive({'mykey': 42}) (pdb) c foo # continued pdb, we're in outer interpreter again >>> print mykey 42 >>>
Comments
Post a Comment