Show HN: Py_better_exchook: intelligently print variables in stack traces

4 hours ago 2

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_exchook
import 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 defined

Python 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 given

Python 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:

https://gist.githubusercontent.com/albertz/a4ce78e5ccd037041638777f10b10327/raw/2cda70f8c5c0478e545640369ebf58d49bf0001c/screenshot2.png

Screencast with DomTerm using text folding (see more):

https://gist.githubusercontent.com/albertz/a4ce78e5ccd037041638777f10b10327/raw/7ec2bb7079dbd56119d498f20905404cb2d812c0/screencast-domterm.gif

-- Albert Zeyer, <http://www.az2000.de>

Read Entire Article