Skip to main content

A simple, zero-dependency utility to raise exceptions as if they originated directly from the invoking method

Reason this release was yanked:

Yanked due to broken functionality caused by mismatched high-version code introduced via copy-paste.

Project description

Introduction

clean_raise is a simple, zero-dependency utility to raise exceptions as if they originated directly from the invoking method.

Supported Versions

  • Overall Package Support: Python 3.9 ~ Python 3.15
  • Distribution Strategy: This project distributes independent wheel files optimized for specific Python versions.

Basic Usage

from clean_raise import clean_raise

def func():
    clean_raise(RuntimeError('An error occurred during runtime'))

func()

You will get a traceback like this, entirely skipping the execution frames of clean_raise itself:

Traceback (most recent call last):
  File "(FILEPATH)", line 6, in <module>
    func()
    ~~~~^^
RuntimeError: An error occurred during runtime

Advanced Usage

clean_raise() accepts an optional bytecode offset parameter, lasti_move, allowing you to manually recalibrate where the traceback indicator points at the bytecode level.

def clean_raise(exception: Any | None = None, lasti_move: int | None = 0, /) -> NoReturn: ...
  • exception: The exception instance or class to be raised. If the argument is not an instance or subclass of BaseException, it will be wrapped and raised as RuntimeError(exception). If omitted, it defaults to raising RuntimeError('No active exception to reraise').
  • lasti_move: The logical bytecode instruction offset (positive moves forward, negative moves backward). Use this to fine-tune the traceback pointer if it does not align precisely with your target code block.

Note: Although Python code objects group bytes in 2-byte intervals (1 code unit), clean_raise() automatically scales lasti_move internally. Additionally, it skips redundant opcodes (such as CACHE, NOP, and RESUME) for a more intuitive user experience. When passing this argument, please specify the value in increments of 1 logical instruction.


How It Works

To strip the internal call stack from the traceback, this utility employs low-level and somewhat intrusive runtime operations. Please be aware of the following behaviors when integrating this module:

1. Temporary sys.excepthook Override

To prevent a native raise statement from duplicating the error message on screen, this tool temporarily overrides the global sys.excepthook if clean_raise() is called outside a try-except block.

2. Behavior Within try-except Blocks

  • To ensure exceptions can be caught normally within active error-handling scopes, the utility parses the current frame's co_exceptiontable in reverse.
  • If it detects that clean_raise was invoked inside a handled block (by checking if lasti falls within a calculated range), it will reraise the exception. This allows the exception to bubble up normally so that external except clauses can capture it correctly.

3. Global Scope Restrictions

clean_raise() relies on traversing back up the execution frames to synthesize the clean traceback. Consequently, it cannot be called directly from the global scope. Violating this constraint will raise the following exception: RuntimeError: clean_raise.clean_raise() cannot be called from the global scope


Known Issues

1. Behavior in asyncio Environments Differs from Native Errors

Because clean_raise works by traversing and synthesizing frames backward from the caller's context until it reaches the top-level frame (frame is None)—rather than originating the traceback directly from the actual exception trigger point—it will generate tracebacks in an asyncio environment that differ significantly from native raise statements.

2. Traceback Chain Pollution on Caught Exception Objects

Due to Python's native behavior, any raise statement unconditionally appends the current execution frame to the exception's traceback chain. When clean_raise() is caught within a try-except block, it achieves this by triggering a literal raise alongside a temporarily silenced excepthook. Consequently, the resulting exception object will inevitably contain a frame from clean_raise inside its .__traceback__.tb_next chain, causing minor traceback pollution.

3. Lack of Native Threading Support

The current implementation is optimized for the main execution thread and does not yet safely adapt to multi-threaded environments. Because unhandled exceptions within spawning threads are intercepted by threading.excepthook rather than the standard sys.excepthook, invoking clean_raise() inside a separate thread may lead to unexpected tracebacks.

*Full support for multi-threaded contexts is planned for a future release.

Project details


Download files

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

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

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

clean_raise-1.1.1-py313-none-any.whl (9.3 kB view details)

Uploaded Python 3.13

clean_raise-1.1.1-py312-none-any.whl (9.3 kB view details)

Uploaded Python 3.12

clean_raise-1.1.1-py311-none-any.whl (9.3 kB view details)

Uploaded Python 3.11

clean_raise-1.1.1-py39-none-any.whl (9.2 kB view details)

Uploaded Python 3.9

File details

Details for the file clean_raise-1.1.1-py313-none-any.whl.

File metadata

  • Download URL: clean_raise-1.1.1-py313-none-any.whl
  • Upload date:
  • Size: 9.3 kB
  • Tags: Python 3.13
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.15.0a3

File hashes

Hashes for clean_raise-1.1.1-py313-none-any.whl
Algorithm Hash digest
SHA256 7af722263c684b685d83c97afa241711d50bee2c907e9e4f308d0b36c942ba41
MD5 a8c98f47ebcd0f5fcd7d89a8aae1ebaa
BLAKE2b-256 5fe705c6db666fcd3ad3de89c09e5124212b9728f0aaaf24848c33eaa93033ca

See more details on using hashes here.

File details

Details for the file clean_raise-1.1.1-py312-none-any.whl.

File metadata

  • Download URL: clean_raise-1.1.1-py312-none-any.whl
  • Upload date:
  • Size: 9.3 kB
  • Tags: Python 3.12
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.15.0a3

File hashes

Hashes for clean_raise-1.1.1-py312-none-any.whl
Algorithm Hash digest
SHA256 2ceab1dde7ed47827eae948d16eff379f19d0df984d78b555bcbf278459ec1c9
MD5 55583d2ed76f63b4f744a646f75f1bad
BLAKE2b-256 518fa168c7c999514d57ddae585507b44d86e9ec91aa46740798f25ac3d44094

See more details on using hashes here.

File details

Details for the file clean_raise-1.1.1-py311-none-any.whl.

File metadata

  • Download URL: clean_raise-1.1.1-py311-none-any.whl
  • Upload date:
  • Size: 9.3 kB
  • Tags: Python 3.11
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.15.0a3

File hashes

Hashes for clean_raise-1.1.1-py311-none-any.whl
Algorithm Hash digest
SHA256 58c25ee70a5455f0b771e46e92f511e921b39332eb07e1fbece69ea826f68f3f
MD5 e727803bdd56319bc9ab2eb0ca620df3
BLAKE2b-256 360aee899527fee7226cb945afa5893c2fbcd47a8399ff2a572eaa17db2ea4c9

See more details on using hashes here.

File details

Details for the file clean_raise-1.1.1-py39-none-any.whl.

File metadata

  • Download URL: clean_raise-1.1.1-py39-none-any.whl
  • Upload date:
  • Size: 9.2 kB
  • Tags: Python 3.9
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.15.0a3

File hashes

Hashes for clean_raise-1.1.1-py39-none-any.whl
Algorithm Hash digest
SHA256 d425e77a289aef1e096c818f89b085b270afaf1c783b4812fedbea3fa80b9c4d
MD5 f965e18b3105ab18aa5c6db5d1117eed
BLAKE2b-256 2496478c087671eeeb97d8700824b8f1fe56d68e5c55cb417e83532238caa6ce

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