try-finally oddity
Apr. 28th, 2014 11:20 am![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
There's a curious oddity with Python's treatment of
While it seems a little odd, I don't think we can really call it a "gotcha", as it shouldn't be all that surprising. The
It should be no surprise that
A little less obvious is that it can also swallow exceptions:
Earlier, I wrote that the
It also won't run if Python is killed by the operating system, e.g. in response to
There are also two official ways to force Python to exit without running cleanup code, including code in
return
inside try...finally
blocks:py> def test(): ... try: ... return 23 ... finally: ... return 42 ... py> test() 42
While it seems a little odd, I don't think we can really call it a "gotcha", as it shouldn't be all that surprising. The
finally
block is guaranteed to run when the try
block is left, however it is left. The first return
sets the return value to 23, the second resets it to 42.It should be no surprise that
finally
can raise an exception:py> def test(): ... try: return 23 ... finally: raise ValueError ... py> test() Traceback (most recent call last): File "", line 1, in File " ", line 3, in test ValueError
A little less obvious is that it can also swallow exceptions:
py> def test(): ... try: raise ValueError ... finally: return 42 ... py> test() 42
Earlier, I wrote that the
finally
block is guaranteed to run. That's not quite true. The finally
block won't run if control never leaves the try
block:try: while True: pass finally: print('this never gets reached')
It also won't run if Python is killed by the operating system, e.g. in response to
kill -9
, or following loss of power and other such catastrophic failures.There are also two official ways to force Python to exit without running cleanup code, including code in
finally
blocks: os.abort
and os._exit
. Both should be used only for specialized purposes. Normally you should exit your Python programs by:- Falling out the bottom of the program. When there is no more code to run, Python exits cleanly.
- Calling
sys.exit
. - Raising
SystemExit
.