Skip to content

Commit eabe61d

Browse files
committed
gh-135629: rewrite language reference section on except* to improve clarity
1 parent 08ce7c6 commit eabe61d

File tree

1 file changed

+23
-19
lines changed

1 file changed

+23
-19
lines changed

Doc/reference/compound_stmts.rst

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -335,15 +335,25 @@ stored in the :mod:`sys` module is reset to its previous value::
335335
:keyword:`!except*` clause
336336
--------------------------
337337

338-
The :keyword:`!except*` clause(s) are used for handling
339-
:exc:`ExceptionGroup`\s. The exception type for matching is interpreted as in
340-
the case of :keyword:`except`, but in the case of exception groups we can have
341-
partial matches when the type matches some of the exceptions in the group.
342-
This means that multiple :keyword:`!except*` clauses can execute,
343-
each handling part of the exception group.
344-
Each clause executes at most once and handles an exception group
345-
of all matching exceptions. Each exception in the group is handled by at most
346-
one :keyword:`!except*` clause, the first that matches it. ::
338+
The :keyword:`!except*` clause(s) specify one or more handlers for groups of
339+
exceptions (:exc:`BaseExceptionGroup` instances). A :keyword:`try` statement
340+
can have either :keyword:`except` or :keyword:`!except*` clauses, but not both.
341+
The exception type for matching is interpreted as in the case of
342+
:keyword:`except`, but matching is performed on the exceptions contained in the
343+
group that is being handled. Each :keyword:`!except*` clause splits (see
344+
:meth:`~BaseExceptionGroup.split`) the exception group into the subgroups of
345+
matching and non-matching exceptions. If the matching subgroup is not empty, it
346+
becomes the handled exception (the value returned from `sys.exception()`) and
347+
assigned to the target of the :keyword:`!except*` clause (if there is one). Then,
348+
the body of the :keyword:`!except*` clause is executed. If the non-matching
349+
subgroup is not empty, it is processed by the next :keyword:`!except*` in the
350+
same manner. This continues until all exceptions in the group have been matched,
351+
or the last :keyword:`!except*` clause has run.
352+
353+
After the last :keyword:`!except*` runs, and before the :keyword:`!finally` block
354+
(if there is one) executes, the group of unhandled exceptions is merged with
355+
any exceptions that were raised or re-raised from within :keyword:`!except*`
356+
clauses. This merged exception group propagates on.
347357

348358
>>> try:
349359
... raise ExceptionGroup("eg",
@@ -362,16 +372,10 @@ one :keyword:`!except*` clause, the first that matches it. ::
362372
| ValueError: 1
363373
+------------------------------------
364374

365-
366-
Any remaining exceptions that were not handled by any :keyword:`!except*`
367-
clause are re-raised at the end, along with all exceptions that were
368-
raised from within the :keyword:`!except*` clauses. If this list contains
369-
more than one exception to reraise, they are combined into an exception
370-
group.
371-
372-
If the raised exception is not an exception group and its type matches
373-
one of the :keyword:`!except*` clauses, it is caught and wrapped by an
374-
exception group with an empty message string. ::
375+
If the exception raised from the :keyword:`try` block is not an exception group
376+
and its type matches one of the :keyword:`!except*` clauses, it is caught and
377+
wrapped by an exception group with an empty message string. This ensures that the
378+
type of the target `e` is consistently :exc:`BaseExceptionGroup`::
375379

376380
>>> try:
377381
... raise BlockingIOError

0 commit comments

Comments
 (0)