@@ -332,15 +332,29 @@ stored in the :mod:`sys` module is reset to its previous value::
332
332
:keyword: `!except* ` clause
333
333
--------------------------
334
334
335
- The :keyword: `!except* ` clause(s) are used for handling
336
- :exc: `ExceptionGroup `\s . The exception type for matching is interpreted as in
337
- the case of :keyword: `except `, but in the case of exception groups we can have
338
- partial matches when the type matches some of the exceptions in the group.
339
- This means that multiple :keyword: `!except* ` clauses can execute,
340
- each handling part of the exception group.
341
- Each clause executes at most once and handles an exception group
342
- of all matching exceptions. Each exception in the group is handled by at most
343
- one :keyword: `!except* ` clause, the first that matches it. ::
335
+ The :keyword: `!except* ` clause(s) specify one or more handlers for groups of
336
+ exceptions (:exc: `BaseExceptionGroup ` instances). A :keyword: `try ` statement
337
+ can have either :keyword: `except ` or :keyword: `!except* ` clauses, but not both.
338
+ The exception type for matching is mandatory in the case of :keyword: `!except* `,
339
+ so ``except*: `` is a syntax error. The type is interpreted as in the case of
340
+ :keyword: `!except `, but matching is performed on the exceptions contained in the
341
+ group that is being handled. An :exc: `TypeError ` is raised if a matching
342
+ type is a subclass of :exc: `!BaseExceptionGroup `, because that would have
343
+ ambiguous semantics.
344
+
345
+ When an exception group is raised in the try block, each :keyword: `!except* `
346
+ clause splits (see :meth: `~BaseExceptionGroup.split `) it into the subgroups
347
+ of matching and non-matching exceptions. If the matching subgroup is not empty,
348
+ it becomes the handled exception (the value returned from :func: `sys.exception `)
349
+ and assigned to the target of the :keyword: `!except* ` clause (if there is one).
350
+ Then, the body of the :keyword: `!except* ` clause executes. If the non-matching
351
+ subgroup is not empty, it is processed by the next :keyword: `!except* ` in the
352
+ same manner. This continues until all exceptions in the group have been matched,
353
+ or the last :keyword: `!except* ` clause has run.
354
+
355
+ After all :keyword: `!except* ` clauses execute, the group of unhandled exceptions
356
+ is merged with any exceptions that were raised or re-raised from within
357
+ :keyword: `!except* ` clauses. This merged exception group propagates on.::
344
358
345
359
>>> try:
346
360
... raise ExceptionGroup("eg",
@@ -353,22 +367,18 @@ one :keyword:`!except*` clause, the first that matches it. ::
353
367
caught <class 'ExceptionGroup'> with nested (TypeError(2),)
354
368
caught <class 'ExceptionGroup'> with nested (OSError(3), OSError(4))
355
369
+ Exception Group Traceback (most recent call last):
356
- | File "<stdin>", line 2, in <module>
357
- | ExceptionGroup: eg
370
+ | File "<doctest default[0]>", line 2, in <module>
371
+ | raise ExceptionGroup("eg",
372
+ | [ValueError(1), TypeError(2), OSError(3), OSError(4)])
373
+ | ExceptionGroup: eg (1 sub-exception)
358
374
+-+---------------- 1 ----------------
359
375
| ValueError: 1
360
376
+------------------------------------
361
377
362
-
363
- Any remaining exceptions that were not handled by any :keyword: `!except* `
364
- clause are re-raised at the end, along with all exceptions that were
365
- raised from within the :keyword: `!except* ` clauses. If this list contains
366
- more than one exception to reraise, they are combined into an exception
367
- group.
368
-
369
- If the raised exception is not an exception group and its type matches
370
- one of the :keyword: `!except* ` clauses, it is caught and wrapped by an
371
- exception group with an empty message string. ::
378
+ If the exception raised from the :keyword: `try ` block is not an exception group
379
+ and its type matches one of the :keyword: `!except* ` clauses, it is caught and
380
+ wrapped by an exception group with an empty message string. This ensures that the
381
+ type of the target ``e `` is consistently :exc: `BaseExceptionGroup `::
372
382
373
383
>>> try:
374
384
... raise BlockingIOError
@@ -377,13 +387,7 @@ exception group with an empty message string. ::
377
387
...
378
388
ExceptionGroup('', (BlockingIOError()))
379
389
380
- An :keyword: `!except* ` clause must have a matching expression; it cannot be ``except*: ``.
381
- Furthermore, this expression cannot contain exception group types, because that would
382
- have ambiguous semantics.
383
-
384
- It is not possible to mix :keyword: `except ` and :keyword: `!except* `
385
- in the same :keyword: `try `.
386
- The :keyword: `break `, :keyword: `continue `, and :keyword: `return ` statements
390
+ :keyword: `break `, :keyword: `continue ` and :keyword: `return `
387
391
cannot appear in an :keyword: `!except* ` clause.
388
392
389
393
0 commit comments