A nicer drop-in-replacement for Python sys.excepthook, i.e. it prints stack traces with extended information. It will add some useful information for each frame, like printing the relevant variables (relevant = referenced in the code line). Also see Python source and comments for further details.
- Shows locals/globals per frame, but only those used in the current statement. It does this by a simple Python code parser. By default, we exclude builtins, undefined names, bound methods (when accessed via the original attribute), modules, top-level module functions.
- Multi-line Python statements in the stack trace output, in case the statement goes over multiple lines.
- Shows full function qualified name (not just co_name).
- Colored/formatted output of each frame.
- Syntax highlighting for the Python source code.
- Support for DomTerm text folding (see more), where it folds all the details of each stack frame away by default, and thus provides a much more comprehensive overview, while still providing all the details when needed.
You can just copy over the single file better_exchook.py to your project.
Or alternatively, it is also available on PyPI and can be installed via:
pip install better_exchookimport better_exchook
better_exchook.install() # will just do: sys.excepthook = better_exchook
Or:
import better_exchook
better_exchook.setup_all()
-
setup_all
- install + replace_traceback_format_tb + replace_traceback_print_tb
-
install:
- sys.excepthook = better_exchook
-
replace_traceback_format_tb:
- traceback.format_tb = format_tb
- traceback.StackSummary.format = format_tb
- traceback.StackSummary.extract = _StackSummary_extract
-
replace_traceback_print_tb:
- traceback.print_tb = print_tb
- traceback.print_exception = print_exception
- traceback.print_exc = print_exc
Python example code:
try:
x = {1:2, "a":"b"}
def f():
y = "foo"
x, 42, sys.stdin.__class__, sys.exc_info, y, z
f()
except Exception:
better_exchook.better_exchook(*sys.exc_info())
Output:
EXCEPTION Traceback (most recent call last): File "/Users/az/Programmierung/py_better_exchook/demo.py", line 23, in demo line: f() locals: f = <local> <function demo.<locals>.f at 0x10328f740> File "/Users/az/Programmierung/py_better_exchook/demo.py", line 21, in demo.<locals>.f line: x, 42, sys.stdin.__class__, sys.exc_info, y, z # noqa: F821 locals: x = <local> {1: 2, 'a': 'b'} sys.stdin = <global> <_io.TextIOWrapper name='<stdin>' mode='r' encoding='utf-8'> sys.stdin.__class__ = <global> <class '_io.TextIOWrapper'> y = <local> 'foo' NameError: name 'z' is not definedPython example code:
try:
(lambda _x: None)(
__name__,
42,
) # multiline
except Exception:
better_exchook(*sys.exc_info())
Output:
EXCEPTION Traceback (most recent call last): File "/Users/az/Programmierung/py_better_exchook/demo.py", line 29, in demo line: (lambda _x: None)( __name__, 42, ) # multiline locals: __name__ = <global> '__main__', len = 8 TypeError: demo.<locals>.<lambda>() takes 1 positional argument but 2 were givenPython example code:
# use this to overwrite the global exception handler
sys.excepthook = better_exchook.better_exchook
# and fail
raise ValueError("final failure: %s" % ((sys, f1, 123),))
Output:
EXCEPTION Traceback (most recent call last): File "/Users/az/Programmierung/py_better_exchook/demo.py", line 106, in <module> line: main() locals: main = <local> <function main at 0x103071c60> File "/Users/az/Programmierung/py_better_exchook/demo.py", line 102, in main line: demo() File "/Users/az/Programmierung/py_better_exchook/demo.py", line 69, in demo line: raise ValueError("final failure: %s" % ((sys, f1, 123),)) locals: f1 = <local> <function demo.<locals>.f1 at 0x1030d1da0> ValueError: final failure: (<module 'sys' (built-in)>, <function demo.<locals>.f1 at 0x1030d1da0>, 123)Screenshot:
Screencast with DomTerm using text folding (see more):
- Nose does something similar for assertion failures.
- IPython has something similar (ultratb). Do this: from IPython.core import ultratb; sys.excepthook = ultratb.VerboseTB(). Shows more source code context (but not necessarily all relevant parts).
- Ka-Ping Yee's "cgitb.py", which is part of Python, see here, code here.
- Rich Python library. Syntax highlighting but without locals.
- andy-landy / traceback_with_variables. Python Traceback (Error Message) Printing Variables. Very similar, but less advanced. Only shows locals, not globals, and also just all locals, not only those used in current statement. Also does not expand statement if it goes over multiple lines.
- cknd / stackprinter. Similar as IPython ultratb.
- patrys / great-justice
- Qix- / better-exceptions
- onelivesleft / PrettyErrors
- See this related StackOverflow question.
-- Albert Zeyer, <http://www.az2000.de>