Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nice general way to always invoke python debugger upon exception

I'd like to have my debugger run post_mortem() any time an exception is encountered, without having to modify the source that I'm working on. I see lots of examples that involve wrapping code in a try/except block, but I'd like to have it always run, regardless of what I'm working on.

I worked on a python wrapper script but that got to be ugly and pretty much unusable.

I use pudb, which is API-equivalent to pdb, so a pdb-specific answer is fine. I run code from within my editor (vim) and would like to have the pm come up any time an exception is encountered.

like image 590
Captain Midday Avatar asked May 06 '13 05:05

Captain Midday


2 Answers

It took a few months of not doing anything about it, but I happened to stumble upon a solution. I'm sure this is nothing new for the more experienced.

I have the following in my environment:

export PYTHONUSERBASE=~/.python
export PYTHONPATH=$PYTHONPATH:$PYTHONUSERBASE

And I have the following file:

~/.python/lib/python2.7/site-packages/usercustomize.py

With the following contents:

import traceback
import sys

try:
    import pudb as debugger
except ImportError:
    import pdb as debugger

def drop_debugger(type, value, tb):
  traceback.print_exception(type, value, tb)
  debugger.pm()

sys.excepthook = drop_debugger

__builtins__['debugger'] = debugger
__builtins__['st'] = debugger.set_trace

Now, whether interactively or otherwise, the debugger always jumps in upon an exception. It might be nice to smarten this up some.

It's important to make sure that you have no no-global-site-packages.txt in your site-packages. This will disable the usercustomize module with the default site.py (my virtualenv had a no-global-site-packages.txt)

Just in case it would help others, I left in the bit about modifying __builtins__. I find it quite handy to always be able to rely on some certain tools being available.

Flavor to taste.

like image 182
Captain Midday Avatar answered Nov 14 '22 20:11

Captain Midday


A possible solution is to invoke pdb (I don't know about pudb, but I'll just assume it works the same) as a script:

python -m pdb script.py

Quoting the the documentation:

When invoked as a script, pdb will automatically enter post-mortem debugging if the program being debugged exits abnormally. After post-mortem debugging (or after normal exit of the program), pdb will restart the program.

like image 41
icecrime Avatar answered Nov 14 '22 20:11

icecrime