From what I can tell, pdb does not recognize when the source code has changed between "runs". That is, if I'm debugging, notice a bug, fix that bug, and rerun the program in pdb (i.e. without exiting pdb), pdb will not recompile the code. I'll still be debugging the old version of the code, even if pdb lists the new source code.
So, does pdb not update the compiled code as the source changes? If not, is there a way to make it do so? I'd like to be able to stay in a single pdb session in order to keep my breakpoints and such.
FWIW, gdb will notice when the program it's debugging changes underneath it, though only on a restart of that program. This is the behavior I'm trying to replicate in pdb.
What do you mean by "rerun the program in pdb?" If you've imported a module, Python won't reread it unless you explicitly ask to do so, i.e. with reload(module)
. However, reload
is far from bulletproof (see xreload for another strategy).
There are plenty of pitfalls in Python code reloading. To more robustly solve your problem, you could wrap pdb with a class that records your breakpoint info to a file on disk, for example, and plays them back on command.
(Sorry, ignore the first version of this answer; it's early and I didn't read your question carefully enough.)
The following mini-module may help. If you import it in your pdb session, then you can use:
pdb> pdbs.r()
at any time to force-reload all non-system modules except main. The code skips that because it throws an ImportError('Cannot re-init internal module main') exception.
# pdbs.py - PDB support
from __future__ import print_function
def r():
"""Reload all non-system modules, so a pdb restart
will reload anything new
"""
import sys
# This is likely to be OS-specific
SYS_PREFIX = '/usr/lib'
for k, v in sys.modules.items():
if not hasattr(v, '__file__'):
continue
if v.__file__.startswith(SYS_PREFIX):
continue
if k == '__main__':
continue
print('reloading %s [%s]' % (k, v.__file__))
reload(v)
ipdb %autoreload
extension
6.2.0 docs document http://ipython.readthedocs.io/en/stable/config/extensions/autoreload.html#module-IPython.extensions.autoreload :
In [1]: %load_ext autoreload
In [2]: %autoreload 2
In [3]: from foo import some_function
In [4]: some_function()
Out[4]: 42
In [5]: # open foo.py in an editor and change some_function to return 43
In [6]: some_function()
Out[6]: 43