Skip to content
This repository was archived by the owner on Apr 10, 2022. It is now read-only.

Commit 610b4db

Browse files
committed
Clarify the difference in tracebacks between raise and raise e
1 parent dea7741 commit 610b4db

File tree

1 file changed

+66
-15
lines changed

1 file changed

+66
-15
lines changed

except_star.md

Lines changed: 66 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -307,13 +307,13 @@ try:
307307
)
308308
)
309309
except *TypeError as e:
310-
print(f'got some TypeErrors: {len(e)}')
310+
print(f'got some TypeErrors: {list(e)}')
311311
except *Exception:
312312
pass
313313

314314
# would print:
315315
#
316-
# got some TypeErrors: 2
316+
# got some TypeErrors: [TypeError('b'), TypeError('c')]
317317
```
318318

319319
Iteration 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
346349
try:
@@ -353,25 +356,75 @@ try:
353356
)
354357
)
355358
except *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
377430
try:
@@ -384,17 +437,15 @@ try:
384437
)
385438
)
386439
except *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

Comments
 (0)