@@ -335,15 +335,29 @@ stored in the :mod:`sys` module is reset to its previous value::
335
335
:keyword: `!except* ` clause
336
336
--------------------------
337
337
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.::
347
361
348
362
>>> try:
349
363
... raise ExceptionGroup("eg",
@@ -356,22 +370,18 @@ one :keyword:`!except*` clause, the first that matches it. ::
356
370
caught <class 'ExceptionGroup'> with nested (TypeError(2),)
357
371
caught <class 'ExceptionGroup'> with nested (OSError(3), OSError(4))
358
372
+ 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)
361
377
+-+---------------- 1 ----------------
362
378
| ValueError: 1
363
379
+------------------------------------
364
380
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 `::
375
385
376
386
>>> try:
377
387
... raise BlockingIOError
@@ -380,13 +390,7 @@ exception group with an empty message string. ::
380
390
...
381
391
ExceptionGroup('', (BlockingIOError()))
382
392
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 `
390
394
cannot appear in an :keyword: `!except* ` clause.
391
395
392
396
0 commit comments