When I raise any exceptions inside a context manager the cleanup code is not run. For example:
from contextlib import contextmanager
try:
raise BaseException()
except BaseException:
print "bye from except"
@contextmanager
def say_goodbye():
yield
print "bye from context manager"
with say_goodbye():
raise BaseException()
Will output:
bye from except
Traceback (most recent call last):
File "", line 15, in
BaseException
Notice that the try/except properly catches the exception while the with statement does not. Is there something I don't understand about how with statements are supposed to work?
You can see the code in a fiddle here: http://pythonfiddle.com/context-manager-failing
FYI I'm running python 2.7 on OSX mavericks. Although I've been able to reproduce in many environments so I doubt that has much to do with it.
You'll need to add exception handling yourself:
The above ensures the
finally
block always runs regardless of an exception inside the with block. If you want exceptions to be handled you'll need to catch those and possible reraise them:As the documentation says:
Also note that
BaseException
is not anException
:Your own exceptions should inherit from
Exception
, notBaseException
.