Welcome, guest | Sign In | My Account | Store | Cart

When Python runs a script and an uncatched exception is raised, a traceback is printed and the script is terminated. Python2.1 has introduced sys.excepthook, which can be used to override the handling of uncaught exceptions. This allows to automatically start the debugger on an unexpected exception, even if python is not running in interactive mode.

Python, 17 lines
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
# code snippet, to be included in 'sitecustomize.py'
import sys

def info(type, value, tb):
   if hasattr(sys, 'ps1') or not sys.stderr.isatty():
      # we are in interactive mode or we don't have a tty-like
      # device, so we call the default hook
      sys.__excepthook__(type, value, tb)
   else:
      import traceback, pdb
      # we are NOT in interactive mode, print the exception...
      traceback.print_exception(type, value, tb)
      print
      # ...then start the debugger in post-mortem mode.
      pdb.pm()

sys.excepthook = info

The above code should be included in 'sitecustomize.py', which is automatically imported by python. The debugger is only started when python is run in non-interactive mode.

If you have not yet a 'sizecustomize.py' file, create one and place it somewhere on your pythonpath.

7 comments

Matt Feifarek 21 years, 1 month ago  # | flag

Gui debugger? This is a great idea; I'd love to use it under the PythonWin gui debugger. Any way to make that happen?

I'm using Python as the Active Script language for IIS/ASP, and would love to throw the errors into the PythonWin debugger.

Thanks!

Christopher Prinos 20 years, 1 month ago  # | flag

using pywin debugger. instead of:

import pdb pdb.pm()

use:

import pywin.debugger pywin.debugger.pm()

Syver Enstad 19 years, 12 months ago  # | flag

Some small improvements. It is nice to check if the exception is a syntax error because SyntaxError's can't be debugged.

if hasattr(sys, 'ps1') or not sys.stderr.isatty() or \
     type == SyntaxError: # there is nothing to be done on syntax errors

Also nice is just assigning the debug exception hook when the program is run is debug mode.

if __debug__:
   sys.excepthook = info
Adam Hupp 19 years, 8 months ago  # | flag

Should check if stdin.isatty also. If stdin isn't a tty (e.g. a pipe) and this gets called the pdb code will just start printing it's prompt continually instead of giving a useful traceback. Changing the test to "not (sys.stderr.isatty() and sys.stdin.isatty())" fixes it.

-Adam

Jens Liebehenschel 16 years, 10 months ago  # | flag

Addidtional check: sys.stdout.isatty(). If the standart output is redirected to a file, then you might not want to start the debugger, because you do not see the debugger's output. Under consideration of the previous comments the condition has to be changed to:

if hasattr(sys, 'ps1') or not sys.stderr.isatty() or not sys.stdin.isatty() or not sys.stdout.isatty() or type==SyntaxError:

Yaroslav Bulatov 13 years, 1 month ago  # | flag

Note, sometimes sys.excepthook gets redefined by other modules, for instance if you are using IPython embedded shell. In this case, insert following after all the imports in your script

from sitecustomize import info sys.excepthook=info

Ray Chuan 8 years, 11 months ago  # | flag

I've collected the comments here in my gist: https://gist.github.com/rctay/3169104