@@ -335,15 +335,29 @@ 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 mandatory in the case of :keyword: `!except* `,
342+ so ``except*: `` is a syntax error. The type is interpreted as in the case of
343+ :keyword: `!except `, but matching is performed on the exceptions contained in the
344+ group that is being handled. An :exc: `TypeError ` is raised if a matching
345+ type is a subclass of :exc: `!BaseExceptionGroup `, because that would have
346+ ambiguous semantics.
347+
348+ When an exception group is raised in the try block, each :keyword: `!except* `
349+ clause splits (see :meth: `~BaseExceptionGroup.split `) it into the subgroups
350+ of matching and non-matching exceptions. If the matching subgroup is not empty,
351+ it becomes the handled exception (the value returned from :func: `sys.exception `)
352+ and assigned to the target of the :keyword: `!except* ` clause (if there is one).
353+ Then, the body of the :keyword: `!except* ` clause executes. If the non-matching
354+ subgroup is not empty, it is processed by the next :keyword: `!except* ` in the
355+ same manner. This continues until all exceptions in the group have been matched,
356+ or the last :keyword: `!except* ` clause has run.
357+
358+ After all :keyword: `!except* ` clauses execute, the group of unhandled exceptions
359+ is merged with any exceptions that were raised or re-raised from within
360+ :keyword: `!except* ` clauses. This merged exception group propagates on.::
347361
348362 >>> try:
349363 ... raise ExceptionGroup("eg",
@@ -356,22 +370,18 @@ one :keyword:`!except*` clause, the first that matches it. ::
356370 caught <class 'ExceptionGroup'> with nested (TypeError(2),)
357371 caught <class 'ExceptionGroup'> with nested (OSError(3), OSError(4))
358372 + Exception Group Traceback (most recent call last):
359- | File "<stdin>", line 2, in <module>
360- | ExceptionGroup: eg
373+ | File "<doctest default[0]>", line 2, in <module>
374+ | raise ExceptionGroup("eg",
375+ | [ValueError(1), TypeError(2), OSError(3), OSError(4)])
376+ | ExceptionGroup: eg (1 sub-exception)
361377 +-+---------------- 1 ----------------
362378 | ValueError: 1
363379 +------------------------------------
364380
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. ::
381+ If the exception raised from the :keyword: `try ` block is not an exception group
382+ and its type matches one of the :keyword: `!except* ` clauses, it is caught and
383+ wrapped by an exception group with an empty message string. This ensures that the
384+ type of the target ``e `` is consistently :exc: `BaseExceptionGroup `::
375385
376386 >>> try:
377387 ... raise BlockingIOError
@@ -380,13 +390,7 @@ exception group with an empty message string. ::
380390 ...
381391 ExceptionGroup('', (BlockingIOError()))
382392
383- An :keyword: `!except* ` clause must have a matching expression; it cannot be ``except*: ``.
384- Furthermore, this expression cannot contain exception group types, because that would
385- have ambiguous semantics.
386-
387- It is not possible to mix :keyword: `except ` and :keyword: `!except* `
388- in the same :keyword: `try `.
389- The :keyword: `break `, :keyword: `continue `, and :keyword: `return ` statements
393+ :keyword: `break `, :keyword: `continue ` and :keyword: `return `
390394cannot appear in an :keyword: `!except* ` clause.
391395
392396
0 commit comments