06-26-2021, 05:29 AM
Ever wish Python would just give you a debugger whenever an unhandled exception is raised? Me too! Here's how we can do that.
You need to create or pick a directory. This directory should remain empty except for the file we're going to create or only ever hold python modules you want to be able to import without all that package nusence. What we're going to do is add this directory to the path Python searches when looking to import modules. We do this by setting the PYTHONPATH environment variable in one of our .profile, .bashrc, or other shell config file you use for this sort of thing. If you've never set an environment variable, just google how to do it. You can do this on Windows, you just have to follow instructions for adding a new environment variable, use Windows style path names, and reboot once you've set this all up.
Now we put the following in /path/to/dir/sitecustomize.py (that filename is important, but the directory is whatever you set PYTHONPATH to). Whenever python starts running it attempts to import the sitecustomize module. This means we can have Python execute code when we run other python programs or start the Python REPL. The code below changes the sys.excepthook function to a new function. The sys.excepthook function is called whenever an exception reaches the top of the call stack without an exception handler. The default function we're overwriting is what prints the traceback you're used to and then exits the program. Our new function will instead do one of 3 things:
Go forth and break some shit!
You need to create or pick a directory. This directory should remain empty except for the file we're going to create or only ever hold python modules you want to be able to import without all that package nusence. What we're going to do is add this directory to the path Python searches when looking to import modules. We do this by setting the PYTHONPATH environment variable in one of our .profile, .bashrc, or other shell config file you use for this sort of thing. If you've never set an environment variable, just google how to do it. You can do this on Windows, you just have to follow instructions for adding a new environment variable, use Windows style path names, and reboot once you've set this all up.
Hidden Content
Now we put the following in /path/to/dir/sitecustomize.py (that filename is important, but the directory is whatever you set PYTHONPATH to). Whenever python starts running it attempts to import the sitecustomize module. This means we can have Python execute code when we run other python programs or start the Python REPL. The code below changes the sys.excepthook function to a new function. The sys.excepthook function is called whenever an exception reaches the top of the call stack without an exception handler. The default function we're overwriting is what prints the traceback you're used to and then exits the program. Our new function will instead do one of 3 things:
- If it's a KeyboardInterrupt because you pressed Ctrl-C or BdbQuit which is raised when you press Ctrl-D in the debugger, it'll just ignore these now and no longer print the ugly traceback. I generally prefer this behaviour as I don't often find I press Ctrl-C because a Python program has hung and really need that traceback. More often it's some python program I don't want running anymore and then I get a big wad of their internal state in my terminal. You can remove this part of the conditional if you'd prefer those also start the debugger or add the sys.__excepthook__(ex_type, ex_val, ex_tb) line before the return if you'd rather keep that traceback info.
- When an exception is unhandled and you're not running in the REPL, Python will now start the PDB debugger! You can now poke around the state of the crashing application checking variables and seeing what dumb mistake you made this time!
- The else catches the case where you are in the REPL. You don't want the debugger if you're writing interactively. You already essentially have a debugger and getting pdb is just a waste of time for typos in the REPL.
Hidden Content
Go forth and break some shit!