single |
:alt: Build Status
:alt: Code Coverage
This is a backport of the BaseExceptionGroup and ExceptionGroup classes
from
Python 3.11.
It contains the following:
* The ``exceptiongroup.BaseExceptionGroup and
exceptiongroup.ExceptionGroup``
classes
* A utility function (``exceptiongroup.catch()``) for catching exceptions
possibly
nested in an exception group
* Patches to the TracebackException class that properly formats exception
groups
(installed on import)
* An exception hook that handles formatting of exception groups through
TracebackException (installed on import)
* Special versions of some of the functions from the traceback module,
modified to
correctly handle exception groups even when monkey patching is disabled,
or blocked by
another custom exception hook:
* ``traceback.format_exception()``
* ``traceback.format_exception_only()``
* ``traceback.print_exception()``
* ``traceback.print_exc()``
* A backported version of ``contextlib.suppress()`` from Python 3.12.1
which also
handles suppressing exceptions inside exception groups
If this package is imported on Python 3.11 or later, the built-in
implementations of the
exception group classes are used instead, TracebackException is not monkey
patched
and the exception hook won't be installed.
See the `standard library documentation`_ for more information on exception
groups.
.. _standard library documentation:
https://docs.python.org/3/library/exceptions.html
Catching exceptions
===================
Due to the lack of the ``except*`` syntax introduced by `PEP 654`_ in
earlier Python
versions, you need to use ``exceptiongroup.catch()`` to catch exceptions
that are
potentially nested inside an exception group. This function returns a
context manager
that calls the given handler for any exceptions matching the sole argument.
The argument to ``catch()`` must be a dict (or any Mapping) where each key
is either
an exception class or an iterable of exception classes. Each value must be
a callable
that takes a single positional argument. The handler will be called at most
once, with
an exception group as an argument which will contain all the exceptions
that are any
of the given types, or their subclasses. The exception group may contain
nested groups
containing more matching exceptions.
Thus, the following Python 3.11+ code:
.. code-block:: python
try:
...
except* (ValueError, KeyError) as excgroup:
for exc in excgroup.exceptions:
print('Caught exception:', type(exc))
except* RuntimeError:
print('Caught runtime error')
would be written with this backport like this:
.. code-block:: python
from exceptiongroup import BaseExceptionGroup, catch
def value_key_err_handler(excgroup: BaseExceptionGroup) -> None:
for exc in excgroup.exceptions:
print('Caught exception:', type(exc))
def runtime_err_handler(exc: BaseExceptionGroup) -> None:
print('Caught runtime error')
with catch({
(ValueError, KeyError): value_key_err_handler,
RuntimeError: runtime_err_handler
}):
...
|