

[](https://GitHub.com/Naereen/StrapDown.js/graphs/commit-activity)
[](https://github.com/psf/blue)
[](https://opensource.org/licenses/MIT)
[](https://codecov.io/gh/tybruno/zombie-py)
[](10.0/10)
[](https://github.com/psf/pylama)
[](10.0/10)
# zombie-py
Bringing Raised Exceptions Back From the Dead As New Exceptions.
`zombie-py` is a Python library that simplifies the process of transforming and re-raising exceptions. It provides a context manager and decorator for handling exceptions, allowing you to define custom transformations for exceptions. `zombie-py` is designed to make it easier to handle exceptions in Python by providing a simple and flexible way to transform and re-raise exceptions.
## Key Features:
* **Easy**: Simplifies the process of transforming and re-raising exceptions.
* **Context Manager and Decorator**: Provides both context manager and decorator for handling exceptions.
* **Customizable**: Allows defining custom transformations for exceptions.
* **Fully Tested**: Ensures reliability through comprehensive tests.
## Installation
`pip install zombie-py`
## Usage
### Example 1: Using as a Context Manager
```python
from zombie import ExceptionTransformation, Reraise
transform = ExceptionTransformation(
original_exception=KeyError,
new_exception=ValueError,
),
# Using as a context manager with multiple transforms
with Reraise(transform):
raise KeyError('Original error message')
```
#### Example Output
```shell
Traceback (most recent call last):
File "example.py", line 20, in <module>
raise KeyError('Original error message')
File "example.py", line 15, in <module>
raise ValueError('Original error message') from e
ValueError: 'Original error message'
```
### Example 2: Using as a Decorator
```python
from zombie import ExceptionTransformation, Reraise
transforms = [
ExceptionTransformation(
original_exception=KeyError,
new_exception=ValueError,
error_message='A KeyError occurred',
raise_from_error=True,
),
ExceptionTransformation(
original_exception=TypeError,
new_exception=RuntimeError,
error_message='A TypeError occurred',
raise_from_error=True,
),
]
# Using as a decorator with multiple transforms
@Reraise(transforms)
def func():
raise KeyError('Original error message')
func()
```
#### Example Output
```shell
Traceback (most recent call last):
File "example.py", line 20, in <module>
func()
File "example.py", line 15, in func
raise KeyError('Original error message')
KeyError: 'Original error message'
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "example.py", line 20, in <module>
func()
File "example.py", line 15, in func
raise ValueError('A KeyError occurred') from e
ValueError: A KeyError occurred
```
#### Example 3: Ordering of Exception Transformations
The order in which `ExceptionTransformation` objects are provided to the `Reraise` context manager or decorator matters.
The transformations are applied sequentially, and the first matching transformation will be used to transform and
raise the exception. This means that if multiple transformations could apply to the same exception,
the first one in the list will take precedence. For example, consider the following transformations:
```python
from zombie import ExceptionTransformation, Reraise
# Order matters: The first matching transformation will be applied
@Reraise(
[
ExceptionTransformation(
original_exception=KeyError,
new_exception=ValueError,
error_message='A KeyError occurred',
),
ExceptionTransformation(
original_exception=Exception,
new_exception=KeyboardInterrupt,
error_message='An Exception occurred',
),
]
)
def func():
raise KeyError('Original error message')
func()
# Raises ValueError with message 'A KeyError occurred'
# Since KeyError is a subclass of Exception, the second transformation will not be applied.
```
#### Example Output
```shell
Traceback (most recent call last):
File "zombie.py", line 314, in <module>
func()
File "zombie.py", line 213, in wrapper
_raise_transformed_exception(
File "zombie.py", line 138, in _raise_transformed_exception
_transform_and_raise(transform=transform, error=error)
File "zombie.py", line 109, in _transform_and_raise
raise transform.new_exception(error_message) from None
ValueError: A KeyError occurred
```
In this example, even though `KeyError` is a subclass of `Exception`, the `ExceptionTransformation` for `Exception` will be applied first, transforming the `KeyError` into a `KeyboardInterrupt`. If the order were reversed, the `KeyError` would be transformed into a `RuntimeError` instead. Therefore, the order of transformations can affect the final exception that is raised.
## Advanced Usage Examples for `ExceptionTransformation`
### Using `error_message`
The `error_message` parameter allows you to customize the error message of
the new exception. You can use a static string or a `string.Template` to
include dynamic content from the original exception. Using the default `None` will use the original exception's
message.
#### Default Error Message
If the `error_message` parameter is not provided, the new exception will use the original exception's message.
```python
from zombie import ExceptionTransformation, Reraise
# Define an exception transformation without an error message
transform = ExceptionTransformation(
original_exception=KeyError,
new_exception=ValueError,
raise_from_error=True
)
@Reraise(transform)
def example_function():
raise KeyError("Original error message")
try:
example_function()
except Exception as e:
print(e) # Output: Original error message
```
#### Static Error Message
```python
from zombie.zombie import ExceptionTransformation, Reraise
# Define an exception transformation with a static error message
transform = ExceptionTransformation(
original_exception=KeyError,
new_exception=ValueError,
error_message="A static error message",
raise_from_error=True
)
@Reraise(transform)
def example_function():
raise KeyError("Original error message")
try:
example_function()
except Exception as e:
print(e) # Output: A static error message
```
#### Dynamic Error Message with string.Template
```python
from zombie import ExceptionTransformation, Reraise
import string
# Define an exception transformation with a dynamic error message
transform = ExceptionTransformation(
original_exception=KeyError,
new_exception=ValueError,
error_message=string.Template("Error: ${original_error_message}"),
raise_from_error=True
)
@Reraise(transform)
def example_function():
raise KeyError("Original error message")
try:
example_function()
except Exception as e:
print(e) # Output: Error: Original error message
```
### Using `raise_from_error`
The `raise_from_error` parameter determines whether the new exception should be
chained from the original exception. If raise_from_error is `True`,
the new exception will include the original exception as its cause.
`False` will raise the new exception without the original exception as its cause.
`False` is the default value.
#### With `raise_from_error=True`
```python
from zombie.zombie import ExceptionTransformation, Reraise
# Define an exception transformation with raise_from_error=True
transform = ExceptionTransformation(
original_exception=KeyError,
new_exception=ValueError,
error_message="An error occurred",
raise_from_error=True
)
@Reraise(transform)
def example_function():
raise KeyError("Original error message")
example_function()
```
##### Example Output
```shell
$ python example.py
Traceback (most recent call last):
File "example.py", line 20, in <module>
raise KeyError('Original error message')
KeyError: 'Original error message'
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "example.py", line 20, in <module>
raise KeyError('Original error message')
File "example.py", line 15, in <module>
raise ValueError('A KeyError occurred') from e
ValueError: A KeyError occurred
```
#### With `raise_from_error=False` (default)
```python
from zombie import ExceptionTransformation, Reraise
# Define an exception transformation with raise_from_error=False
transform = ExceptionTransformation(
original_exception=KeyError,
new_exception=ValueError,
error_message="An error occurred",
raise_from_error=False
)
@Reraise(transform)
def example_function():
raise KeyError("Original error message")
example_function()
```
##### Example Output
```shell
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<path_to_project>/zombie/zombie.py", line 146, in wrapper
_raise_transformed_exception(*exception_transformations, error=error)
File "<path_to_project>/zombie/zombie.py", line 116, in _raise_transformed_exception
_transform_and_raise(transform=transform, error=error)
File "<path_to_project>/zombie/zombie.py", line 85, in _transform_and_raise
raise transform.new_exception(error_message) from None
ValueError: An error occurred
```
Raw data
{
"_id": null,
"home_page": "https://github.com/tybruno/zombie-py",
"name": "zombie-py",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.10",
"maintainer_email": null,
"keywords": "python re-raise exceptions",
"author": "Tyler Bruno",
"author_email": null,
"download_url": "https://files.pythonhosted.org/packages/8c/f9/16041f30b83659a859aa42f206bc5ef6baefaa110973dd9249365cfc086a/zombie_py-1.3.tar.gz",
"platform": null,
"description": "\n\n\n[](https://GitHub.com/Naereen/StrapDown.js/graphs/commit-activity)\n[](https://github.com/psf/blue)\n[](https://opensource.org/licenses/MIT)\n[](https://codecov.io/gh/tybruno/zombie-py)\n[](10.0/10)\n[](https://github.com/psf/pylama)\n[](10.0/10)\n\n# zombie-py\n\nBringing Raised Exceptions Back From the Dead As New Exceptions.\n\n`zombie-py` is a Python library that simplifies the process of transforming and re-raising exceptions. It provides a context manager and decorator for handling exceptions, allowing you to define custom transformations for exceptions. `zombie-py` is designed to make it easier to handle exceptions in Python by providing a simple and flexible way to transform and re-raise exceptions.\n## Key Features:\n\n* **Easy**: Simplifies the process of transforming and re-raising exceptions.\n* **Context Manager and Decorator**: Provides both context manager and decorator for handling exceptions.\n* **Customizable**: Allows defining custom transformations for exceptions.\n* **Fully Tested**: Ensures reliability through comprehensive tests.\n\n## Installation\n\n`pip install zombie-py`\n\n## Usage\n\n### Example 1: Using as a Context Manager\n\n```python\nfrom zombie import ExceptionTransformation, Reraise\n\ntransform = ExceptionTransformation(\n original_exception=KeyError,\n new_exception=ValueError,\n ),\n\n# Using as a context manager with multiple transforms\nwith Reraise(transform):\n raise KeyError('Original error message')\n```\n#### Example Output\n\n```shell\nTraceback (most recent call last):\n File \"example.py\", line 20, in <module>\n raise KeyError('Original error message')\n File \"example.py\", line 15, in <module>\n raise ValueError('Original error message') from e\nValueError: 'Original error message'\n```\n\n### Example 2: Using as a Decorator\n\n```python\nfrom zombie import ExceptionTransformation, Reraise\n\ntransforms = [\n ExceptionTransformation(\n original_exception=KeyError,\n new_exception=ValueError,\n error_message='A KeyError occurred',\n raise_from_error=True,\n ),\n ExceptionTransformation(\n original_exception=TypeError,\n new_exception=RuntimeError,\n error_message='A TypeError occurred',\n raise_from_error=True,\n ),\n]\n\n# Using as a decorator with multiple transforms\n@Reraise(transforms)\ndef func():\n raise KeyError('Original error message')\n\nfunc()\n```\n#### Example Output\n```shell\nTraceback (most recent call last):\n File \"example.py\", line 20, in <module>\n func()\n File \"example.py\", line 15, in func\n raise KeyError('Original error message')\nKeyError: 'Original error message'\n\nThe above exception was the direct cause of the following exception:\n\nTraceback (most recent call last):\n File \"example.py\", line 20, in <module>\n func()\n File \"example.py\", line 15, in func\n raise ValueError('A KeyError occurred') from e\nValueError: A KeyError occurred\n```\n\n#### Example 3: Ordering of Exception Transformations\n\nThe order in which `ExceptionTransformation` objects are provided to the `Reraise` context manager or decorator matters.\nThe transformations are applied sequentially, and the first matching transformation will be used to transform and\nraise the exception. This means that if multiple transformations could apply to the same exception, \nthe first one in the list will take precedence. For example, consider the following transformations:\n```python\nfrom zombie import ExceptionTransformation, Reraise\n\n# Order matters: The first matching transformation will be applied\n@Reraise(\n [\n ExceptionTransformation(\n original_exception=KeyError,\n new_exception=ValueError,\n error_message='A KeyError occurred', \n ),\n ExceptionTransformation(\n original_exception=Exception,\n new_exception=KeyboardInterrupt,\n error_message='An Exception occurred',\n ),\n ]\n)\ndef func():\n raise KeyError('Original error message')\n\nfunc()\n# Raises ValueError with message 'A KeyError occurred'\n# Since KeyError is a subclass of Exception, the second transformation will not be applied.\n```\n\n#### Example Output\n```shell\nTraceback (most recent call last):\n File \"zombie.py\", line 314, in <module>\n func()\n File \"zombie.py\", line 213, in wrapper\n _raise_transformed_exception(\n File \"zombie.py\", line 138, in _raise_transformed_exception\n _transform_and_raise(transform=transform, error=error)\n File \"zombie.py\", line 109, in _transform_and_raise\n raise transform.new_exception(error_message) from None\nValueError: A KeyError occurred\n```\n\nIn this example, even though `KeyError` is a subclass of `Exception`, the `ExceptionTransformation` for `Exception` will be applied first, transforming the `KeyError` into a `KeyboardInterrupt`. If the order were reversed, the `KeyError` would be transformed into a `RuntimeError` instead. Therefore, the order of transformations can affect the final exception that is raised.\n\n## Advanced Usage Examples for `ExceptionTransformation`\n\n### Using `error_message`\n\nThe `error_message` parameter allows you to customize the error message of \nthe new exception. You can use a static string or a `string.Template` to\n include dynamic content from the original exception. Using the default `None` will use the original exception's \nmessage.\n\n#### Default Error Message\n\nIf the `error_message` parameter is not provided, the new exception will use the original exception's message.\n\n```python\nfrom zombie import ExceptionTransformation, Reraise\n\n# Define an exception transformation without an error message\ntransform = ExceptionTransformation(\n original_exception=KeyError,\n new_exception=ValueError,\n raise_from_error=True\n)\n\n@Reraise(transform)\ndef example_function():\n raise KeyError(\"Original error message\")\n\ntry:\n example_function()\nexcept Exception as e:\n print(e) # Output: Original error message\n```\n#### Static Error Message\n\n```python\nfrom zombie.zombie import ExceptionTransformation, Reraise\n\n# Define an exception transformation with a static error message\ntransform = ExceptionTransformation(\n original_exception=KeyError,\n new_exception=ValueError,\n error_message=\"A static error message\",\n raise_from_error=True\n)\n\n@Reraise(transform)\ndef example_function():\n raise KeyError(\"Original error message\")\n\ntry:\n example_function()\nexcept Exception as e:\n print(e) # Output: A static error message\n\n```\n#### Dynamic Error Message with string.Template\n```python\nfrom zombie import ExceptionTransformation, Reraise\nimport string\n\n# Define an exception transformation with a dynamic error message\ntransform = ExceptionTransformation(\n original_exception=KeyError,\n new_exception=ValueError,\n error_message=string.Template(\"Error: ${original_error_message}\"),\n raise_from_error=True\n)\n\n@Reraise(transform)\ndef example_function():\n raise KeyError(\"Original error message\")\n\ntry:\n example_function()\nexcept Exception as e:\n print(e) # Output: Error: Original error message\n```\n### Using `raise_from_error`\nThe `raise_from_error` parameter determines whether the new exception should be \nchained from the original exception. If raise_from_error is `True`,\n the new exception will include the original exception as its cause.\n`False` will raise the new exception without the original exception as its cause.\n`False` is the default value.\n\n#### With `raise_from_error=True`\n```python\nfrom zombie.zombie import ExceptionTransformation, Reraise\n\n# Define an exception transformation with raise_from_error=True\ntransform = ExceptionTransformation(\n original_exception=KeyError,\n new_exception=ValueError,\n error_message=\"An error occurred\",\n raise_from_error=True\n)\n\n@Reraise(transform)\ndef example_function():\n raise KeyError(\"Original error message\")\n\nexample_function()\n\n```\n##### Example Output\n\n```shell\n$ python example.py\nTraceback (most recent call last):\n File \"example.py\", line 20, in <module>\n raise KeyError('Original error message')\nKeyError: 'Original error message'\n\nThe above exception was the direct cause of the following exception:\n\nTraceback (most recent call last):\n File \"example.py\", line 20, in <module>\n raise KeyError('Original error message')\n File \"example.py\", line 15, in <module>\n raise ValueError('A KeyError occurred') from e\nValueError: A KeyError occurred\n```\n#### With `raise_from_error=False` (default)\n```python\nfrom zombie import ExceptionTransformation, Reraise\n\n# Define an exception transformation with raise_from_error=False\ntransform = ExceptionTransformation(\n original_exception=KeyError,\n new_exception=ValueError,\n error_message=\"An error occurred\",\n raise_from_error=False\n)\n\n@Reraise(transform)\ndef example_function():\n raise KeyError(\"Original error message\")\n\nexample_function()\n```\n##### Example Output\n\n```shell\nTraceback (most recent call last):\n File \"<stdin>\", line 1, in <module>\n File \"<path_to_project>/zombie/zombie.py\", line 146, in wrapper\n _raise_transformed_exception(*exception_transformations, error=error)\n File \"<path_to_project>/zombie/zombie.py\", line 116, in _raise_transformed_exception\n _transform_and_raise(transform=transform, error=error)\n File \"<path_to_project>/zombie/zombie.py\", line 85, in _transform_and_raise\n raise transform.new_exception(error_message) from None\nValueError: An error occurred\n```\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Raising Exceptions From the Dead by Re-raising Them With New Exception Types",
"version": "1.3",
"project_urls": {
"Homepage": "https://github.com/tybruno/zombie-py"
},
"split_keywords": [
"python",
"re-raise",
"exceptions"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "20c684253f2dc580201576d98874ae2c7376d2e59d430f70d8c41951743413cb",
"md5": "657e2989b461a950d674864d3aeaf952",
"sha256": "33448840023f1965e9f53c13d1913de24ddf692ff6493071de1b3762a99407b2"
},
"downloads": -1,
"filename": "zombie_py-1.3-py3-none-any.whl",
"has_sig": false,
"md5_digest": "657e2989b461a950d674864d3aeaf952",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.10",
"size": 7407,
"upload_time": "2025-02-21T22:40:44",
"upload_time_iso_8601": "2025-02-21T22:40:44.425924Z",
"url": "https://files.pythonhosted.org/packages/20/c6/84253f2dc580201576d98874ae2c7376d2e59d430f70d8c41951743413cb/zombie_py-1.3-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "8cf916041f30b83659a859aa42f206bc5ef6baefaa110973dd9249365cfc086a",
"md5": "7b707b9c2b330ce4eb2cafe44d31cb66",
"sha256": "94c9cd6dcc6dc7522ce2b230186fc649fdfbf7c11484597435d1aebded73297c"
},
"downloads": -1,
"filename": "zombie_py-1.3.tar.gz",
"has_sig": false,
"md5_digest": "7b707b9c2b330ce4eb2cafe44d31cb66",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.10",
"size": 10006,
"upload_time": "2025-02-21T22:40:45",
"upload_time_iso_8601": "2025-02-21T22:40:45.941004Z",
"url": "https://files.pythonhosted.org/packages/8c/f9/16041f30b83659a859aa42f206bc5ef6baefaa110973dd9249365cfc086a/zombie_py-1.3.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-02-21 22:40:45",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "tybruno",
"github_project": "zombie-py",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "zombie-py"
}