try-finally oddity
Apr. 28th, 2014 11:20 amThere'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.