How to export a variable from PDB?

Question:

Imagine the following scenario: a script is started from the IPython shell and at a break point the python debugger is called. Using the PDB commands one can analyze the code and variables at this point. But often it turns out that the values of the variables call for a deeper research.

Is it possible to export the value of a variable to the IPython shell?

My specific use case:
I struggle with a quite huge numpy array which does not seem to have the correct values. I know that I can run any python commands from the python debugger, but it would be helpful to save the values of the variable at different break points and to use all of them at IPython shell. I am imaging something like

ipdb> global var1; var1 = var
ipdb> continue
...
ipdb> global var2; var2 = var
ipdb> continue
... 
In [2]: abs(var1 - var2) # do some interesting calculations with IPython
Asked By: lumbric

||

Answers:

Not a pretty solution, but working:

ipdb> import cPickle; f=open('/tmp/dump1','w+'); cPickle.dump(var,f); f.close()

ipdb> import cPickle; f=open('/tmp/dump2','w+'); cPickle.dump(var,f); f.close()

then

In [2]: var1 = cPickle.load(open('/tmp/dump1'))
In [3]: var2 = cPickle.load(open('/tmp/dump2'))
Answered By: sega_sai

You can use globals():

ipdb>__name__
'my_module'
ipdb> get_var = 'a value'
ipdb> globals()['myvar'] = get_var
ipdb> q
In [11]: my_module.myvar
Out[11]: 'a value'

This assumes the break point is set in my_module.py, so we are editing the globals of the module my_module.

Answered By: chespinoza

You need to distinguish different globals().
For example, suppose we have a module: mymodule.py

foo = 100
def test():
    bar = 200
    return bar

We run it under the control of pdb.

>>> import pdb
>>> import mymodule
>>> foobar = 300
>>> pdb.run('mymodule.test()')
> <string>(1)<module>()
(Pdb) print foobar
300
(Pdb) print foo
*** NameError: name 'foo' is not defined
(Pdb) global foobar2; foobar2 = 301
(Pdb) print foobar2
301

At the beginning, namely, before executing test(), the environment in pdb is your current globals(). Thus foobar is defined, while foo is not defined.
Then we execute test() and stop at the end of bar = 200

-> bar = 200
(Pdb) print bar
200
(Pdb) print foo
100
(Pdb) print foobar
*** NameError: name 'foobar' is not defined
(Pdb) global foo2; foo2 = 101
(Pdb) print foo2
101
(Pdb) c
>>> 

The environment in pdb has been changed. It uses mymodule‘s globals() in test(). Thus ‘foobaris not defined. whilefoo` is defined.

We have exported two variables foobar2 and foo2. But they live in different scopes.

>>> foobar2
301
>>> mymodule.foobar2

Traceback (most recent call last):
  File "<pyshell#16>", line 1, in <module>
    mymodule.foobar2
AttributeError: 'module' object has no attribute 'foobar2'
>>> mymodule.foo2
101
>>> foo2

Traceback (most recent call last):
  File "<pyshell#18>", line 1, in <module>
    foo2
NameError: name 'foo2' is not defined

You have already found the solution. But it works slightly differently.

Answered By: nymk

Based on the answers and comments above, this felt the most straightforward approach for me:

ipdb> import sys
ipdb> sys.abcdef = some_debugged_variable
ipdb> c

In [18]: import sys
In [19]: ipython_var = sys.abcdef

You can also store a dict there and hold multiple named objects if need to do so.

Answered By: Arthur.V
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.