Skip to main content

Traceback Serializer Project (offline-debug)

PyPI version Tests Coverage Ruff Ty checked

Overview

A Python package for high-fidelity serialization and deserialization of exceptions and their complete tracebacks. Unlike other solutions, offline-debug reconstructs actual types.FrameType objects using the Python C API, ensuring that re-raised exceptions look and feel genuine to debuggers and introspection tools.

Core Functions

  • save_traceback(exc: BaseException, file: Path | BytesIO, proxy_types=DEFAULT_PROXY_TYPES): Serializes an exception, its traceback, and all picklable local/global variables to a binary file or buffer. proxy_types names classes whose instances must never be touched (see Object proxies).
  • load_traceback(file: Path | BytesIO) -> Never: Loads the serialized state, reconstructs the exception and its full traceback chain (including __cause__ and __context__), and raises it.
  • parse_traceback(file: Path | BytesIO) -> ExceptionData: Loads the serialized data and returns an ExceptionData object. This allows for inspecting the exception, stack frames, and variables without reconstructing the full traceback or raising the exception.

Usage Example

To get started, install with:
pip install offline-debug or uv add offline-debug

from pathlib import Path
from offline_debug import save_traceback, load_traceback, parse_traceback

# --- Saving an exception ---
try:
    some_complex_operation()
except Exception as e:
    save_traceback(e, Path("crash_report.dump"))

# --- Option 1: Re-raise the exception for debugging ---
# This will look like the original crash in your debugger
load_traceback(Path("crash_report.dump"))

# --- Option 2: Inspect data without raising ---
data = parse_traceback(Path("crash_report.dump"))
print(f"Number of frames: {len(data.tb_frames)}")
for frame in data.tb_frames:
    print(f"File: {frame.code.co_filename}, Line: {frame.lineno}")

Exception Group Support

offline-debug has full support for ExceptionGroup (Python 3.11+). When you parse a saved ExceptionGroup, you can access its nested exceptions:

from offline_debug import parse_traceback, ExceptionGroupData

data = parse_traceback(Path("exception_group.dump"))

if isinstance(data, ExceptionGroupData):
    print(f"Group contains {len(data.exceptions)} sub-exceptions")
    for sub_exc_data in data.exceptions:
        # Each sub_exc_data is itself an ExceptionData object
        print(f"Sub-exception frames: {len(sub_exc_data.tb_frames)}")

Object proxies

An object proxy such as an rpyc netref turns every instance operation - attribute reads, repr, isinstance (through __class__), pickling (through __reduce_ex__) - into a remote call that blocks for the peer's full timeout once the connection breaks, and a dead peer is often why the code crashed. So save_traceback recognises proxies from their type alone and writes a placeholder like <proxy rpyc.core.netref.SaharaClient at 0x7f...> without touching the instance:

save_traceback(e, dump_file, proxy_types=(*DEFAULT_PROXY_TYPES, MyProxyBase))

An entry is a class or a fully-qualified class name such as "rpyc.core.netref.BaseNetref", which names a proxy family without importing its package; both forms match subclasses, since only type(value).__mro__ is consulted. DEFAULT_PROXY_TYPES covers rpyc netrefs out of the box. Proxies are replaced wherever they appear: frame variables, items nested in containers, and an exception's args or attributes.

An unregistered proxy is still slow to save, but can no longer lose the dump: a placeholder falls back to the bare object repr when repr or str raises.

Technical Implementation

  • True Frame Reconstruction: Uses ctypes to call PyFrame_New from the Python C API. This creates real frame objects which are required for a valid types.TracebackType.
  • Python 3.13 Compatibility: Leverages PEP 667 features where f_locals is a write-through proxy, allowing for accurate local variable restoration.
  • Support python 3.12 as well
  • Resilient Serialization:
    • pickle is used for exceptions and variables.
    • marshal is used for code objects.
    • Non-picklable items are gracefully handled by storing their repr.

Development & Tooling

  • Package Manager: uv
  • Minimum Python: 3.12
  • Testing: pytest
  • Commands:
    • Add dependencies: uv add <package>
    • Run tests: uv run pytest

Metadata

Release files for offline-debug 0.3.3

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

Source distribution (sdist)

Source distribution for offline-debug 0.3.3
File Size Uploaded
offline_debug-0.3.3.tar.gz 13.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for offline-debug 0.3.3
File Interpreter ABI Platform
offline_debug-0.3.3-py3-none-any.whl Python 3 none any Details

Total release size: 31.0 kB

Release files / offline_debug-0.3.3.tar.gz

Download URL offline_debug-0.3.3.tar.gz
Size 13.7 kB
Tags Source
SHA-256 checksum
How to use checksums
7d25ac22a2d31eb5542ef438555b9f1a704eaeb83f2e315eddb6158b6971c1c9
BLAKE2b-256 checksum
How to use checksums
a3293e3171f13a5b901dae8c2e322c31ba9eed332af2240af2f4d43c093baccb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 7, 2026.

Transparency log

Release files / offline_debug-0.3.3-py3-none-any.whl

Download URL offline_debug-0.3.3-py3-none-any.whl
Size 17.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
3424e726be097ff134b9d25f733d913a4c0bfc0fb2356870a714c99bdf385e2d
BLAKE2b-256 checksum
How to use checksums
6ca0c548f2920d2c0d0e28d5e69ed41f2c9c90ff2c6348c2c6eda9f72c3271b4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 7, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.3.3 This release

2 release files

0.3.2

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.1

2 release files

0.1.0

2 release files

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