PEP 654: Explain why we did not extend except to handle ExceptionGroups (#1846)

This commit is contained in:
Irit Katriel 2021-02-27 00:59:40 +00:00 committed by GitHub
parent afa1503545
commit 31ba5bd70c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 35 additions and 3 deletions

View File

@ -108,6 +108,10 @@ other types in the same ``ExceptionGroup`` need to be automatically reraised,
otherwise it is too easy for user code to inadvertently swallow exceptions
that it is not handling.
We considered whether it is possible to modify the semantics of ``except``
for this purpose, in a backwards-compatible manner, and found that it is not.
See the `Rejected Ideas`_ section for more on this.
The purpose of this PEP, then, is to add the ``except*`` syntax for handling
``ExceptionGroups`` in the interpreter, which in turn requires that
``ExceptionGroup`` is added as a builtin type. The semantics of handling
@ -1017,8 +1021,33 @@ group. Furthermore, a useful display of the traceback includes information
about the nested exceptions. For these reasons we decided that it is best to
leave the traceback mechanism as it is and modify the traceback display code.
A full redesign of ``except``
-----------------------------
Extend ``except`` to handle ``ExceptionGroups``
-----------------------------------------------
We considered extending the semantics of ``except`` to handle
``ExceptionGroups``, instead of introducing ``except*``. There were two
backwards compatibility concerns with this. The first is the type of the
caught exception. Consider this example:
.. code-block::
try:
. . .
except OSError as err:
if err.errno != ENOENT:
raise
If the value assigned to err is an ``ExceptionGroup`` containing all of
the ``OSErrors`` that were raised, then the attribute access ``err.errno``
no longer works. So we would need to execute the body of the ``except``
clause multiple times, once for each exception in the group. However, this
too is a potentially breaking change because at the moment we write ``except``
clauses with the knowledge that they are only executed once. If there is
a non-idempotent operation there, such as releasing a resource, the
repetition could be harmful.
A new ``except`` alternative
----------------------------
We considered introducing a new keyword (such as ``catch``) which can be used
to handle both naked exceptions and ``ExceptionGroups``. Its semantics would
@ -1033,7 +1062,10 @@ continues to be used for simple exceptions.
Applying an ``except*`` clause on one exception at a time
---------------------------------------------------------
We considered making ``except*`` clauses always execute on a single exception,
We explained above why it is unsafe to execute an ``except`` clause in existing
code more than once. We considered doing this in the new ``except*`` clauses,
where the backwards compatibility considerations do not exist.
The idea is to always execute an ``except*`` clause on a single exception,
possibly executing the same clause multiple times when it matches multiple
exceptions. We decided instead to execute each ``except*`` clause at most once,
giving it an ``ExceptionGroup`` that contains all matching exceptions. The