Recipe 8.7. Starting the Debugger Automatically After an Uncaught ExceptionCredit: Thomas Heller, Christopher Prinos, Syver Enstad, Adam Hupp ProblemWhen a script propagates an exception, Python normally responds by printing a traceback and terminating execution, but you would prefer to automatically enter an interactive debugger in such cases when feasible. SolutionBy setting sys.excepthook, you can control what happens when an uncaught exception propagates all the way up: # code snippet to include in your sitecustomize.py import sys def info(type, value, tb): if hasattr(sys, 'ps1') or not ( sys.stderr.isatty( ) and sys.stdin.isatty( ) ) or issubclass(type, SyntaxError): # Interactive mode, no tty-like device, or syntax error: nothing # to do but call the default hook sys._ _excepthook_ _(type, value, tb) else: import traceback, pdb # You are NOT in interactive mode; so, print the exception... traceback.print_exception(type, value, tb) print # ...then start the debugger in post-mortem mode pdb.pm( ) sys.excepthook = info DiscussionWhen Python runs a script and an uncaught exception is raised and propagates all the way, a traceback is printed to standard error, and the script terminates. However, Python exposes sys.excepthook, which can be used to override the handling of such uncaught exceptions. This lets you automatically start the debugger on an unexpected exception when Python is not running in interactive mode but a TTY-like device is available. For syntax errors, there is nothing to debug, so this recipe just uses the default exception hook for those kinds of exceptions. The code in this recipe is meant to be included in sitecustomize.py, which Python automatically imports at startup. Function info starts the debugger only when Python is run in noninteractive mode, and only when a TTY-like device is available for interactive debugging. Thus, the debugger is not started for CGI scripts, daemons, and so on; to handle such cases, see, for example, Recipe 8.5. If you do not have a sitecustomize.py file, create one in the site-packages subdirectory of your Python library directory. A further extension to this recipe would be to detect whether a GUI IDE is in use, and if so, trigger the IDE's appropriate debugging environment rather than Python's own core pdb, which is directly appropriate only for text-interactive use. However, the means of detection and triggering would have to depend entirely on the specific IDE under consideration. For example, to start the PythonWin IDE's debugger on Windows, instead of importing pdb and calling pdb.pm, you can import pywin and call pywin.debugger.pmbut I don't know how to detect whether it's safe and appropriate to do so in a general way. See AlsoRecipe 8.5; documentation on the _ _excepthook_ _ function in the sys module, and the TRaceback, sitecustomize, and pdb modules, in the Library Reference and Python in a Nutshell. |