Skip to main content

A zero-dependency debugging engine for Python that intercepts unhandled exceptions, extracts post-mortem state, masks sensitive data, and provides formatted crash reports with an interactive debugging REPL.

Project description

crash_sight

Python 3.8 - 3.14 Zero Dependencies MIT License Tests Passing

Production-Grade Debugging Engine · A zero-dependency runtime exception interceptor that hijacks sys.excepthook to maximize Developer Experience (DX).

crash_sight is a post-mortem debugging engine for Python 3.8+ that operates at the runtime interceptor level. When an unhandled exception escapes your application, crash_sight captures the precise execution context, scrubs sensitive data, generates a beautifully formatted ANSI terminal report, exports a clean Markdown log, and drops you into an interactive REPL at the exact crash site — all with zero external dependencies.


Core Pillars

crash_sight's architecture is composed of five tightly integrated modules, each responsible for a critical stage of the post-mortem pipeline:

Module Responsibility
Core Interceptor (crash_sight.core.interceptor) Registers a global hook on sys.excepthook, traverses the stack frame window to the deepest frame, and orchestrates the entire pipeline.
Security Data Scrubber (crash_sight.security.masker) Scans local and global variables using case-insensitive regex pattern matching, replacing sensitive values (e.g., password, secret, token, apiKey, credential) with "******** (SECURED)". Supports nested dictionaries, lists, and tuples with infinite recursion depth.
Terminal Formatter (crash_sight.formatter.terminal) Renders a visually stunning ANSI-colored crash report complete with source code context, variable dump, and precise arrow markers — all using only standard library linecache.
Post-Mortem REPL (crash_sight.repl.console) Launches an interactive Python shell (code.InteractiveConsole) injected with the exact masked locals and globals from the crash frame, allowing real-time forensic inspection.
Markdown Exporter (crash_sight.exporter.markdown) Strips ANSI color codes and writes a pristine Markdown version of the crash report to crash_report_[YYYYMMDD_HHMMSS].md for logging, CI/CD, or team sharing.

Installation

Install crash_sight locally in development/editable mode from the project root:

pip install -e .

Zero Dependencies Guaranteepip freeze will show zero additional packages. crash_sight uses only Python Standard Library modules: sys, inspect, linecache, code, os, re, datetime, typing.


Quick Start

Create a file called test_crash.py with the following content:

import crash_sight

crash_sight.install()

def risky_function(user_input):
    user_password = "sup3rS3cr3t!"
    apiKey = "AIzaSyD-abc123def456"
    my_secret_token = "ghp_xxxxxxxxxxxx"
    ratio = 100 / user_input  # will trigger ZeroDivisionError when user_input = 0

risky_function(0)

Then run it:

python test_crash.py

That's it — two lines to activate crash_sight. The rest is automatic.


Aesthetic Terminal Preview

When you run the example above, crash_sight will print a report like this to stderr:

🔍 crash_sight — Post-Mortem Report
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

⚡ ZeroDivisionError: division by zero

📍 Location:
   📄 File: /path/to/test_crash.py
   🔧 Function: risky_function
   ⏰ Line: 8

📄 Code Context:
   5  | def risky_function(user_input):
   6  |     user_password = "sup3rS3cr3t!"
   7  |     apiKey = "AIzaSyD-abc123def456"
   8  ───> ratio = 100 / user_input
   9  | 
  10  | risky_function(0)

🔍 Local Variables (Masked):
   user_input        = 0
   user_password     = ******** (SECURED)
   apiKey            = ******** (SECURED)
   my_secret_token   = ******** (SECURED)
   ratio             = <not defined>

📁 Report saved to: crash_report_20250320_143022.md

💻 Opening interactive REPL at crash site...
   Type 'exit()' or 'quit()' to return to the shell.

Security & Masking Specifications

The security engine (crash_sight.security.masker) applies a deterministic, pattern-based masking algorithm with the following rules:

Pattern Matching (Case-Insensitive)

Any variable key containing any of these substrings (case-insensitive) will have its value replaced:

Keyword Example Keys That Trigger Masking
password password, userPassword, PASSWORD, passwords_list
secret secret, my_secret_token, SECRET_KEY, secret_answer
token token, api_token, TOKEN, auth_tokens
apikey apiKey, API_KEY, apikey, api_key_v2
credential credential, credentials, CREDENTIALS

Recursive Scrubbing — Full Nested Support

Masking is applied recursively to arbitrary-depth data structures:

  • Nested dictionaries: {"db": {"password": "s3cr3t"}}{"db": {"password": "******** (SECURED)"}}
  • Lists of dictionaries: [{"apiKey": "xyz"}, {"other": 42}][{"apiKey": "******** (SECURED)"}, {"other": 42}]
  • Tuples: ("user", {"token": "abc"})("user", {"token": "******** (SECURED)"})
  • Mixed nesting is fully supported.

False-Positive Guard

Variables whose keys contain certain "safe" substrings are intelligently bypassed:

  • not_secretNOT masked (contains "secret" but guarded)
  • public_token_idNOT masked (contains "token" but guarded)

Built-in exception list: not_secret, not_password, public_token, non_credential, and equivalents are safely ignored.


Python 3.14 Compatibility Note

crash_sight is fully compliant with PEP 667 (introduced in Python 3.13, standard in 3.14). The extract_deepest_context() function explicitly converts frame.f_locals and frame.f_globals to standard dict objects using dict() constructor, ensuring seamless compatibility with Python 3.13+ where FrameLocalsProxy is returned instead of a plain dictionary.

This safeguard is encapsulated in the core interceptor:

# In Python 3.13+, frame.f_locals returns FrameLocalsProxy, not a plain dict
f_locals: Dict[str, Any] = dict(frame.f_locals)
f_globals: Dict[str, Any] = dict(frame.f_globals)

Tested and verified across Python 3.8 through 3.14-pre release.


Testing

crash_sight ships with a comprehensive test suite (90+ tests covering unit, integration, and edge-case scenarios). Run the full suite with:

python -m unittest discover -s tests -p "test_*.py" -v

Test categories include:

  • Core interceptor installation/idempotency/uninstallation
  • Deepest frame extraction (including chain tracebacks)
  • Security masker — pattern matching, nested structures, false-positive guard
  • Terminal formatter (ANSI rendering, code context windows)
  • Markdown exporter (cleaning, naming conventions)
  • REPL initialization and context injection
  • Cross-version compatibility (Python 3.8–3.14)

Development & Contributing

  1. Clone the repository:

    git clone https://github.com/annaqibz01/crash_sight.git
    cd crash_sight
    
  2. Install in editable mode:

    pip install -e .
    
  3. Run the tests:

    python -m unittest discover -s tests -p "test_*.py" -v
    
  4. Submit a pull request or open an issue on GitHub Issues.


License

Distributed under the MIT License. See LICENSE for more information.


crash_sight — Zero-dependency debugging. Precision post-mortem. Maximum DX.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

crash_sight-1.0.0.tar.gz (33.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

crash_sight-1.0.0-py3-none-any.whl (20.3 kB view details)

Uploaded Python 3

File details

Details for the file crash_sight-1.0.0.tar.gz.

File metadata

  • Download URL: crash_sight-1.0.0.tar.gz
  • Upload date:
  • Size: 33.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.5

File hashes

Hashes for crash_sight-1.0.0.tar.gz
Algorithm Hash digest
SHA256 ea4c4e90e39092fe54ce4591567fadf95eb7eb171e525b9db29a12f0f6b7d89e
MD5 91721342577ccef1ebe2a57da4d50bdd
BLAKE2b-256 4c5b5b369193b15ef0c4c844336441dddcafe54c7d299fc654b11f1a6eff34b2

See more details on using hashes here.

File details

Details for the file crash_sight-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: crash_sight-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 20.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.5

File hashes

Hashes for crash_sight-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 92297fb663037e36c88c2a3136e4d800a9016906a51184b9a684fe4493e2f1a4
MD5 6ca2f9802fe235c602f4436b627a1e5d
BLAKE2b-256 e24b8172e608af020433366464446d5e6af544487b549748cf64b8751644b9d5

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page