PEP 654: Add BaseExceptionGroup//ExceptionGroup split (#1850)

This commit is contained in:
Irit Katriel 2021-03-01 18:19:06 +00:00 committed by GitHub
parent aea3cc1016
commit 9a1afd9a94
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 26 additions and 13 deletions

View File

@ -133,14 +133,24 @@ Specification
ExceptionGroup
--------------
The new builtin exception type, ``ExceptionGroup`` is a subclass of
``BaseException``, so it is assignable to ``Exception.__cause__`` and
``Exception.__context__``, and can be raised and handled as any exception
with ``raise ExceptionGroup(...)`` and ``try: ... except ExceptionGroup: ...``.
We propose to add two new builtin exception types:
``BaseExceptionGroup(BaseException)`` and
``ExceptionGroup(BaseExceptionGroup, Exception)``. They are assignable to
``Exception.__cause__`` and ``Exception.__context__``, and they can be
raised and handled as any exception with ``raise ExceptionGroup(...)`` and
``try: ... except ExceptionGroup: ...`` or ``raise BaseExceptionGroup(...)``
and ``try: ... except BaseExceptionGroup: ...``.
Its constructor takes two positional-only parameters: a message string and a
sequence of the nested exceptions, for example:
Both have a constructor that takes two positional-only parameters: a message
string and a sequence of the nested exceptions, for example:
``ExceptionGroup('issues', [ValueError('bad value'), TypeError('bad type')])``.
The difference between them is that ``ExceptionGroup`` can only wrap
``Exception`` subclasses while ``BaseExceptionGroup`` can wrap any
``BaseException`` subclass. A factory method that inspects the nested
execptions and selects between ``ExceptionGroup`` and ``BaseExceptionGroup``
makes the choice automatic. In the rest of the document, unless stated
otherwise, when we refer to ``ExceptionGroup`` we mean either an
``ExceptionGroup`` or a ``BaseExceptionGroup``.
The ``ExceptionGroup`` class exposes these parameters in the fields ``message``
and ``errors``. A nested exception can also be an ``ExceptionGroup`` so the
@ -951,17 +961,20 @@ propose in this PEP will not break any existing code:
Programs will only be impacted by the changes proposed in this PEP once they
begin to use ``ExceptionGroups`` and ``except*``.
* An important concern was that ``except Exception:`` will continue to catch
almost all exceptions, and by making ``ExceptionGroup`` extend ``Exception``
we ensured that this will be the case. ``BaseExceptionGroups`` will not be
caught, which is appropriate because they include exceptions that would not
have been caught by ``except Exception``.
Once programs begin to use these features, there will be migration issues to
consider:
* An ``except Exception:`` clause will not catch ``ExceptionGroup`` because it
is derived from ``BaseException``. Any such clause will need to be replaced
by ``except (Exception, ExceptionGroup):`` or ``except *Exception:``.
* Similarly, any ``except T:`` clause that wraps code which is now potentially
raising ``ExceptionGroup`` needs to become ``except *T:``, and its body may
need to be updated.
* An ``except T:`` clause that wraps code which is now potentially raising
``ExceptionGroup`` may need to become ``except *T:``, and its body may
need to be updated. This means that raising an ``ExceptionGroup`` is an
API-breaking change and will likely be done in new APIs rather than
added to existing ones.
* Libraries that need to support older Python versions will not be able to use
``except*`` or raise ``ExceptionGroups``.