Question

Problem: If I have an elaborate breakpoint condition, I don't want to have to pdb.set_trace() then paste the breakpoint command manually every time I restart my program.

Is there a way to set a breakpoint from within my source-code?

What I tried: I read the docs and tried to insert this line:

pdb.run('break 445, a == 1')

But I got this error once execution hit that line:

    pdb.run('break 445, a == 1')
  File "C:\Python25\lib\pdb.py", line 1123, in run
    Pdb().run(statement, globals, locals)
  File "C:\Python25\lib\bdb.py", line 366, in run
    exec cmd in globals, locals
  File "<string>", line 1
    break 445, a == 1
            ^
SyntaxError: invalid syntax
Was it helpful?

Solution

pdb can't do this. But you could build it yourself, in your own program, a couple of ways.

The first way is simply to gate the breakpoint entry with a global variable. Something like this would be pretty trivial (simple example):

_breakpoints = {}

def reset_breakpoints(disabled=[]):
    global _breakpoints
    _breakpoints = dict((x, False) for x in disabled)

def set_breakpoint(tag, condition=True):
    if tag not in _breakpoints:
        _breakpoints[tag] = True
        if condition:
            pdb.set_trace()
    else:
        if _breakpoints[tag] and condition:
            pdb.set_trace()

def mycode():
    some_command()
    set_breakpoint('mycode0')
    another_command()
    set_breakpoint('mycode1', x == 4)

The first time through, you won't have it in the dictionary, so you'll add it and halt. But then, you can change the value in the dictionary, and then instead of actually halting, you'll check whether you should or not first. You could do a more complex condition using eval etc. but it's probably easier to do like the above. This is fairly lightweight and leaves you in full control of when things stop. Only thing, you have to remember to initialize the dict yourself (clear it usually) when restarting a debug session, if you set something to False. It doesn't integrate into the debugger, but it doesn't cost much either.

Another thing to remember... you don't have a debugger to control until you are in one. This means that unless you do pdb.run() in the first place, you aren't actually in the debugger, and there's no way to enter the debugger without halting (as far as I know). Once you are in the debugger though, it's possible to get the pdb object though, with some cleverness, using the stack. This is in IPython, and unfortunately the actual stack depth will probably be different depending on which pdb you are using etc., but you can try something like the below to get a reference to the currently-running Pdb object. Once you have it, you can use its interfaces to interact with it directly. An example:

In [331]: %debug pass
NOTE: Enter 'c' at the ipdb>  prompt to continue execution.
None
> <string>(1)<module>()

ipdb> import inspect
ipdb> f = inspect.stack()[6]
ipdb> f0 = f[0]
ipdb> myipdb = f0.f_locals['self']
ipdb> myipdb.
myipdb.aliases               myipdb.dispatch_exception    myipdb.do_next               myipdb.fncache               myipdb.help_help             myipdb.lastcmd               myipdb.runctx
myipdb.botframe              myipdb.dispatch_line         myipdb.do_p                  myipdb.forget                myipdb.help_ignore           myipdb.lineinfo              myipdb.runeval
myipdb.bp_commands           myipdb.dispatch_return       myipdb.do_pdef               myipdb.format_stack_entry    myipdb.help_j                myipdb.lineno                myipdb.set_break
myipdb.break_anywhere        myipdb.displayhook           myipdb.do_pdoc               myipdb.get_all_breaks        myipdb.help_jump             myipdb.list_command_pydb     myipdb.set_colors
myipdb.break_here            myipdb.do_EOF                myipdb.do_pfile              myipdb.get_break             myipdb.help_l                myipdb.lookupmodule          myipdb.set_continue
myipdb.breaks                myipdb.do_a                  myipdb.do_pinfo              myipdb.get_breaks            myipdb.help_list             myipdb.mainpyfile            myipdb.set_next
myipdb.canonic               myipdb.do_alias              myipdb.do_pinfo2             myipdb.get_file_breaks       myipdb.help_n                myipdb.misc_header           myipdb.set_quit
myipdb.checkline             myipdb.do_args               myipdb.do_pp                 myipdb.get_names             myipdb.help_next             myipdb.new_do_down           myipdb.set_return
myipdb.clear_all_breaks      myipdb.do_b                  myipdb.do_psource            myipdb.get_stack             myipdb.help_p                myipdb.new_do_frame          myipdb.set_step
myipdb.clear_all_file_breaks myipdb.do_break              myipdb.do_q                  myipdb.handle_command_def    myipdb.help_pdb              myipdb.new_do_quit           myipdb.set_trace
myipdb.clear_bpbynumber      myipdb.do_bt                 myipdb.do_quit               myipdb.help_EOF              myipdb.help_pp               myipdb.new_do_restart        myipdb.set_until
myipdb.clear_break           myipdb.do_c                  myipdb.do_r                  myipdb.help_a                myipdb.help_q                myipdb.new_do_up             myipdb.setup
myipdb.cmdloop               myipdb.do_cl                 myipdb.do_restart            myipdb.help_alias            myipdb.help_quit             myipdb.nohelp                myipdb.shell
myipdb.cmdqueue              myipdb.do_clear              myipdb.do_return             myipdb.help_args             myipdb.help_r                myipdb.onecmd                myipdb.stack
myipdb.color_scheme_table    myipdb.do_commands           myipdb.do_retval             myipdb.help_b                myipdb.help_restart          myipdb.parseline             myipdb.stdin
myipdb.columnize             myipdb.do_condition          myipdb.do_run                myipdb.help_break            myipdb.help_return           myipdb.parser                myipdb.stdout
myipdb.commands              myipdb.do_cont               myipdb.do_rv                 myipdb.help_bt               myipdb.help_run              myipdb.postcmd               myipdb.stop_here
myipdb.commands_bnum         myipdb.do_continue           myipdb.do_s                  myipdb.help_c                myipdb.help_s                myipdb.postloop              myipdb.stopframe
myipdb.commands_defining     myipdb.do_d                  myipdb.do_step               myipdb.help_cl               myipdb.help_step             myipdb.precmd                myipdb.stoplineno
myipdb.commands_doprompt     myipdb.do_debug              myipdb.do_tbreak             myipdb.help_clear            myipdb.help_tbreak           myipdb.preloop               myipdb.trace_dispatch
myipdb.commands_resuming     myipdb.do_disable            myipdb.do_u                  myipdb.help_commands         myipdb.help_u                myipdb.print_list_lines      myipdb.undoc_header
myipdb.commands_silent       myipdb.do_down               myipdb.do_unalias            myipdb.help_condition        myipdb.help_unalias          myipdb.print_stack_entry     myipdb.use_rawinput
myipdb.complete              myipdb.do_enable             myipdb.do_unt                myipdb.help_cont             myipdb.help_unt              myipdb.print_stack_trace     myipdb.user_call
myipdb.complete_help         myipdb.do_exit               myipdb.do_until              myipdb.help_continue         myipdb.help_until            myipdb.print_topics          myipdb.user_exception
myipdb.completedefault       myipdb.do_h                  myipdb.do_up                 myipdb.help_d                myipdb.help_up               myipdb.prompt                myipdb.user_line
myipdb.completekey           myipdb.do_help               myipdb.do_w                  myipdb.help_debug            myipdb.help_w                myipdb.quitting              myipdb.user_return
myipdb.completenames         myipdb.do_ignore             myipdb.do_whatis             myipdb.help_disable          myipdb.help_whatis           myipdb.rcLines
myipdb.curframe              myipdb.do_j                  myipdb.do_where              myipdb.help_down             myipdb.help_where            myipdb.reset
myipdb.curindex              myipdb.do_jump               myipdb.doc_header            myipdb.help_enable           myipdb.identchars            myipdb.returnframe
myipdb.default               myipdb.do_l                  myipdb.doc_leader            myipdb.help_exec             myipdb.interaction           myipdb.ruler
myipdb.defaultFile           myipdb.do_list               myipdb.emptyline             myipdb.help_exit             myipdb.intro                 myipdb.run
myipdb.dispatch_call         myipdb.do_n                  myipdb.execRcLines           myipdb.help_h                myipdb.is_pydb               myipdb.runcall
ipdb> myipdb.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top