@@ -307,13 +307,13 @@ try:
307307 )
308308 )
309309except * TypeError as e:
310- print (f ' got some TypeErrors: { len (e)} ' )
310+ print (f ' got some TypeErrors: { list (e)} ' )
311311except * Exception :
312312 pass
313313
314314# would print:
315315#
316- # got some TypeErrors: 2
316+ # got some TypeErrors: [TypeError('b'), TypeError('c')]
317317```
318318
319319Iteration over an ` ExceptionGroup ` that has nested ` ExceptionGroup ` objects
@@ -338,9 +338,12 @@ print(
338338# [ValueError('a'), TypeError('b'), TypeError('c'), KeyError('d')]
339339```
340340
341- ### "raise e" and "raise"
341+ ### Re-raising ExceptionGroups
342342
343- There is no difference between bare ` raise ` and a more specific ` raise e ` :
343+ It is important to point out that the ` ExceptionGroup ` bound to ` e ` is an
344+ ephemeral object. Raising it via ` raise ` or ` raise e ` will not cause changes
345+ to the overall shape of the ` ExceptionGroup ` . Any modifications to it will
346+ likely get lost:
344347
345348``` python
346349try :
@@ -353,25 +356,75 @@ try:
353356 )
354357 )
355358except * TypeError as e:
356- raise # or "raise e"
359+ e.foo = ' bar'
360+ # ^----------- `e` is an ephemeral object that might get
361+ # destroyed after the `except*` clause.
362+ ```
363+
364+ If the user wants to "flatten" the tree, they can explicitly create a new
365+ ` ExceptionGroup ` and raise it:
366+
367+
368+ ``` python
369+ try :
370+ raise ExceptionGroup(
371+ ValueError (' a' ),
372+ TypeError (' b' ),
373+ ExceptionGroup(
374+ TypeError (' c' ),
375+ KeyError (' d' )
376+ )
377+ )
378+ except * TypeError as e:
379+ raise ExceptionGroup(* e)
357380
358381# would terminate with:
359382#
360383# ExceptionGroup(
361384# ValueError('a'),
362- # TypeError('b'),
363385# ExceptionGroup(
386+ # TypeError('b'),
364387# TypeError('c'),
388+ # ),
389+ # ExceptionGroup(
365390# KeyError('d')
366391# )
367392# )
368393```
369394
370- It is important to point out that the ` ExceptionGroup ` bound to ` e ` is an
371- ephemeral object. Raising it via ` raise ` or ` raise e ` will not cause changes
372- to the overall shape of the ` ExceptionGroup ` . If the user wants to "flatten"
373- the tree, they can explicitly create a new ` ExceptionGroup ` and raise it:
395+ With the regular exceptions, there's a subtle difference between bare ` raise `
396+ and a more specific ` raise e ` :
397+
398+ ``` python
399+ def foo (): | def foo ():
400+ try : | try :
401+ 1 / 0 | 1 / 0
402+ except ZeroDivisionError as e: | except ZeroDivisionError :
403+ raise e | raise
404+ |
405+ foo() | foo()
406+ |
407+ Traceback (most recent call last): | Traceback (most recent call last):
408+ File " /Users/guido/a.py" , line 7 | File " /Users/guido/b.py" , line 7
409+ foo() | foo()
410+ File " /Users/guido/a.py" , line 5 | File " /Users/guido/b.py" , line 3
411+ raise e | 1 / 0
412+ File " /Users/guido/a.py" , line 3 | ZeroDivisionError : division by zero
413+ 1 / 0 |
414+ ZeroDivisionError : division by zero |
415+ ```
416+
417+ This difference is preserved with exception groups:
374418
419+ * The ` raise ` form re-raises all exceptions from the group * without recording
420+ the current frame in their tracebacks* .
421+
422+ * The ` raise e ` form re-raises all exceptions from the group with tracebacks
423+ updated to point out to the current frame, effectively resulting in user
424+ seeing the ` raise e ` line in their tracebacks.
425+
426+ That said, both forms would not affect the overall shape of the exception
427+ group:
375428
376429``` python
377430try :
@@ -384,17 +437,15 @@ try:
384437 )
385438 )
386439except * TypeError as e:
387- raise ExceptionGroup( * e)
440+ raise # or "raise e"
388441
389- # would terminate with:
442+ # would both terminate with:
390443#
391444# ExceptionGroup(
392445# ValueError('a'),
446+ # TypeError('b'),
393447# ExceptionGroup(
394- # TypeError('b'),
395448# TypeError('c'),
396- # ),
397- # ExceptionGroup(
398449# KeyError('d')
399450# )
400451# )
0 commit comments