diff --git a/debug_me.py b/debug_me.py index fb3ae89..d7c6577 100644 --- a/debug_me.py +++ b/debug_me.py @@ -24,7 +24,7 @@ def fermat(n): Warning! Untested with n > 2. """ from itertools import count - for x in range(20): + for x in range(100): for y in range(1, x+1): for z in range(1, x**n+y**n + 1): #from pudb import set_trace; set_trace() @@ -36,3 +36,4 @@ print "SF", simple_func(10) for i in fermat(2): print i +print "FINISHED" diff --git a/pudb/__init__.py b/pudb/__init__.py index c1e0933..2fe5a18 100644 --- a/pudb/__init__.py +++ b/pudb/__init__.py @@ -1,4 +1,5 @@ -VERSION = "0.92.9" +NUM_VERSION = (0, 92, 10) +VERSION = ".".join(str(nv) for nv in NUM_VERSION) @@ -16,7 +17,82 @@ def _get_debugger(): -def run(statement, globals=None, locals=None): +def runscript(mainpyfile, args=None, pre_run="", steal_output=False): + from pudb.debugger import Debugger + dbg = Debugger(steal_output=steal_output) + + # Note on saving/restoring sys.argv: it's a good idea when sys.argv was + # modified by the script being debugged. It's a bad idea when it was + # changed by the user from the command line. The best approach would be to + # have a "restart" command which would allow explicit specification of + # command line arguments. + + import sys + if args is not None: + prev_sys_argv = sys.argv[:] + sys.argv = [mainpyfile] + args + + # replace pudb's dir with script's dir in front of module search path. + from os.path import dirname + prev_sys_path = sys.path[:] + sys.path[0] = dirname(mainpyfile) + + while True: + if pre_run: + from subprocess import call + retcode = call(pre_run, close_fds=True, shell=True) + if retcode: + print "*** WARNING: pre-run process exited with code %d." % retcode + raw_input("[Hit Enter]") + + status_msg = "" + + try: + dbg._runscript(mainpyfile) + except SystemExit, se: + status_msg = "The debuggee exited normally with status code was %d.\n\n" % se.code + except: + dbg.post_mortem = True + dbg.interaction(None, sys.exc_info()) + + def quit_debugger(w, size, key): + dbg.ui.quit_event_loop = ["quit"] + + import urwid + pre_run_edit = urwid.Edit("", pre_run) + + result = dbg.ui.call_with_ui(dbg.ui.dialog, + urwid.ListBox([urwid.Text( + "Your PuDB session has ended.\n\n%s" + "Would you like to quit PuDB or restart your program?\n" + "You may hit 'q' to quit." + % status_msg), + urwid.Text("\n\nIf you decide to restart, this command will be run prior to " + "actually restarting:"), + urwid.AttrWrap(pre_run_edit, "value") + ]), + [ + ("Restart", "restart"), + ("Quit", "quit"), + ], + focus_buttons=True, + bind_enter_esc=False, + title="Finished", + extra_bindings=[("q", quit_debugger)]) + + if result == "quit": + return + + pre_run = pre_run_edit.get_edit_text() + + dbg.restart() + + if args is not None: + sys.argv = prev_sys_argv + + sys.path = prev_sys_path + +def run_statement(statement, globals=None, locals=None): _get_debugger().run(statement, globals, locals) def runeval(expression, globals=None, locals=None): diff --git a/pudb/ipython.py b/pudb/ipython.py new file mode 100644 index 0000000..8021465 --- /dev/null +++ b/pudb/ipython.py @@ -0,0 +1,31 @@ +import os +import IPython.ipapi +import pudb + +ip = IPython.ipapi.get() + +def pudb_f(self, arg): + """ Debug a script (like %run -d) in IPython process, using PuDB. + + Usage: + + %pudb test.py [args] + Run script test.py under PuDB. + """ + + if not arg.strip(): + print __doc__ + return + + from IPython.genutils import arg_split + args = arg_split(arg) + + path = os.path.abspath(args[0]) + args = args[1:] + if not os.path.isfile(path): + raise IPython.ipapi.UsageError("%%pudb: file %s does not exist" % path) + + from pudb import runscript + runscript(path, args) + +ip.expose_magic('pudb', pudb_f) diff --git a/pudb/run.py b/pudb/run.py index 400c68c..3440d54 100644 --- a/pudb/run.py +++ b/pudb/run.py @@ -24,67 +24,11 @@ def main(): sys.argv = args - # Replace pudb's dir with script's dir in front of module search path. - sys.path[0] = dirname(mainpyfile) + from pudb import runscript + runscript(mainpyfile, + pre_run=options.pre_run, + steal_output=options.steal_output) - # Note on saving/restoring sys.argv: it's a good idea when sys.argv was - # modified by the script being debugged. It's a bad idea when it was - # changed by the user from the command line. The best approach would be to - # have a "restart" command which would allow explicit specification of - # command line arguments. - - from pudb.debugger import Debugger - dbg = Debugger(steal_output=options.steal_output) - - while True: - if options.pre_run: - from subprocess import call - retcode = call(options.pre_run, close_fds=True, shell=True) - if retcode: - print "*** WARNING: pre-run process exited with code %d." % retcode - raw_input("[Hit Enter]") - - status_msg = "" - - try: - dbg._runscript(mainpyfile) - except SystemExit, se: - status_msg = "The debuggee exited normally with status code was %d.\n\n" % se.code - except: - dbg.post_mortem = True - dbg.interaction(None, sys.exc_info()) - - def quit_debugger(w, size, key): - dbg.ui.quit_event_loop = ["quit"] - - import urwid - pre_run_edit = urwid.Edit("", options.pre_run) - - result = dbg.ui.call_with_ui(dbg.ui.dialog, - urwid.ListBox([urwid.Text( - "Your PuDB session has ended.\n\n%s" - "Would you like to quit PuDB or restart your program?\n" - "You may hit 'q' to quit." - % status_msg), - urwid.Text("\n\nIf you decide to restart, this command will be run prior to " - "actually restarting:"), - urwid.AttrWrap(pre_run_edit, "value") - ]), - [ - ("Restart", "restart"), - ("Quit", "quit"), - ], - focus_buttons=True, - bind_enter_esc=False, - title="Finished", - extra_bindings=[("q", quit_debugger)]) - - if result == "quit": - return - - options.pre_run = pre_run_edit.get_edit_text() - - dbg.restart() diff --git a/setup.py b/setup.py index 063aa87..6921edd 100644 --- a/setup.py +++ b/setup.py @@ -70,6 +70,21 @@ setup(name='pudb', python -m pudb.run my-script.py + IPython integration + ^^^^^^^^^^^^^^^^^^^ + + PuDB ships with IPython integration. Just stick the line:: + + import pudb.ipython + + into your `$HOME/.ipython/ipy_user_conf.py`, and then you may use the magic + command:: + + %pudb script.py [args] + + where `[args]` represents optional arguments, to launch PuDB from within + IPython. + Programming PuDB ----------------