Skip to main content

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.

Features

  • Shows locals/globals per frame, but only those used in the current statement. It does this by a simple Python code parser.

  • 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.

https://github.com/albertz/py_better_exchook/workflows/CI/badge.svg

Installation

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

Usage

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

Examples

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 "better_exchook.py", line 478, in <module>
    line: f()
    locals:
      f = <local> <function f at 0x107f1de60>
  File "better_exchook.py", line 477, in f
    line: x, 42, sys.stdin.__class__, sys.exc_info, y, z
    locals:
      x = <global> {'a': 'b', 1: 2}
      sys = <global> <module 'sys' (built-in)>
      sys.stdin = <global> <open file '<stdin>', mode 'r' at 0x107d9f0c0>
      sys.stdin.__class__ = <global> <type 'file'>
      sys.exc_info = <global> <built-in function exc_info>
      y = <local> 'foo'
      z = <not found>
NameError: global name 'z' is not defined

Python example code:

try:
    f = lambda x: None
    f(x, y)
except Exception:
    better_exchook.better_exchook(*sys.exc_info())

Output:

EXCEPTION
Traceback (most recent call last):
  File "better_exchook.py", line 484, in <module>
    line: f(x, y)
    locals:
      f = <local> <function <lambda> at 0x107f1df50>
      x = <local> {'a': 'b', 1: 2}
      y = <not found>
NameError: name 'y' is not defined

Python example code:

try:
    (lambda x: None)(__name__,
                     42)  # multiline
except Exception:
    better_exchook.better_exchook(*sys.exc_info())

Output:

EXCEPTION
Traceback (most recent call last):
  File "better_exchook.py", line 490, in <module>
    line: (lambda x: None)(__name__,
                           42)  # multiline
    locals:
      x = <local> {'a': 'b', 1: 2}
      __name__ = <local> '__main__', len = 8
TypeError: <lambda>() takes exactly 1 argument (2 given)

Python example code:

# use this to overwrite the global exception handler
sys.excepthook = better_exchook.better_exchook
# and fail
finalfail(sys)

Output:

EXCEPTION
Traceback (most recent call last):
  File "better_exchook.py", line 497, in <module>
    line: finalfail(sys)
    locals:
      finalfail = <not found>
      sys = <local> <module 'sys' (built-in)>
NameError: name 'finalfail' is not defined

Screenshot:

https://gist.githubusercontent.com/albertz/a4ce78e5ccd037041638777f10b10327/raw/7ec2bb7079dbd56119d498f20905404cb2d812c0/screenshot1.png

Screencast with DomTerm using text folding (see more):

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

Similar projects

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

Metadata

Release files for better-exchook 1.20250422.203226

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for better-exchook 1.20250422.203226
File Size Uploaded Provenance
better_exchook-1.20250422.203226.tar.gz 25.1 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for better-exchook 1.20250422.203226
File Interpreter ABI Platform
better_exchook-1.20250422.203226-py3-none-any.whl Python 3 none any Details

Total release size: 49.4 kB

Release files / better_exchook-1.20250422.203226.tar.gz

Download URL better_exchook-1.20250422.203226.tar.gz
Size 25.1 kB
Tags Source
SHA-256 checksum
How to use checksums
e0d672945f63e778fc00147a0825e572952104c1eced8d8d9621124e920e0853
BLAKE2b-256 checksum
How to use checksums
dd939d9f2b4f335af5ecb9b8e90e0df1329562f76feaa7738eb977eb97735d80
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.9.22

Release files / better_exchook-1.20250422.203226-py3-none-any.whl

Download URL better_exchook-1.20250422.203226-py3-none-any.whl
Size 24.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
5180502d1f6894bfc58228f2dbd4afc4571646c3645496cfe61b0fdfc09d6696
BLAKE2b-256 checksum
How to use checksums
3f40750301f8567c0e8f59d66e88eb03beb204648977536099d67b673d1699de
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.9.22

Security for better-exchook 1.20250422.203226

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

1.20160612.132345

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page