Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

python pdb: resume code execution after exception caught?

Tags:

ipython

pdb

If I run a code with the ipython %pdb magic enabled and the code throws an exception, is there any way to tell the code to continue executing afterwards?

e.g., say the exception is a ValueError: x=0 not allowed. Can I, in pdb, set x=1 and allow the code to continue (resume) executing?

like image 971
keflavich Avatar asked Dec 07 '11 22:12

keflavich


People also ask

How do you continue execution in pdb?

@turtle: continue should "Continue execution, only stop when a breakpoint is encountered", according to the docs.

What command in pdb resumes execution?

You can use breakpoint commands to start your program up again. Simply use the continue command, or step , or any other command that resumes execution.

How do I stop a pdb set trace?

To start execution, you use the continue or c command. If the program executes successfully, you will be taken back to the (Pdb) prompt where you can restart the execution again. At this point, you can use quit / q or Ctrl+D to exit the debugger.

How do I stop Python debugging?

Turning off the (Pdb) prompt… with “c” (continue) If you wish simply to stop debugging, but to let the program continue running, then you want to use the “c” (for “continue”) command at the (Pdb) prompt. This will cause your program to continue running normally, without pausing for debugging. It may run to completion.


1 Answers

I don't think you can resume code post-mortem (i.e. the exception was actually raised, triggering invocation of the debugger). What you can do, is put breakpoints in your code where you have been seeing errors, and that allows you to change values, and continue the program avoiding the error.

Given a script myscript.py:

# myscript.py
from IPython.core.debugger import Tracer

# a callable to invoke the IPython debugger. debug_here() is like pdb.set_trace()
debug_here = Tracer()

def test():
    counter = 0
    while True:
        counter += 1
        if counter % 4 == 0:
             # invoke debugger here, so we can prevent the forbidden condition
            debug_here()
        if counter % 4 == 0:
            raise ValueError("forbidden counter: %s" % counter)

        print counter

test()

Which continually increments a counter, raising an error if it's ever divisible by 4. But we have edited it to drop into the debugger under the error condition, so we might be able to save ourselves.

Run this script from IPython:

In [5]: run myscript
1
2
3
> /Users/minrk/dev/ip/mine/myscript.py(14)test()
     13             debug_here()
---> 14         if counter % 4 == 0:
     15             raise ValueError("forbidden counter: %s" % counter)

# increment counter to prevent the error from raising:
ipdb> counter += 1
# continue the program:
ipdb> continue
5
6
7
> /Users/minrk/dev/ip/mine/myscript.py(13)test()
     12              # invoke debugger here, so we can prevent the forbidden condition

---> 13             debug_here()
     14         if counter % 4 == 0:

# if we just let it continue, the error will raise
ipdb> continue
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
IPython/utils/py3compat.pyc in execfile(fname, *where)
    173             else:
    174                 filename = fname
--> 175             __builtin__.execfile(filename, *where)

myscript.py in <module>()
     17         print counter
     18 
---> 19 test()

myscript.py in test()
     11         if counter % 4 == 0:
     12              # invoke debugger here, so we can prevent the forbidden condition

     13             debug_here()
     14         if counter % 4 == 0:
---> 15             raise ValueError("forbidden counter: %s" % counter)

ValueError: forbidden counter: 8

In [6]:
like image 179
minrk Avatar answered Oct 07 '22 06:10

minrk