contextlib.contextmanager and try/finally

Ian Kelly ian.g.kelly at gmail.com
Tue Jan 31 17:09:34 EST 2012


On Tue, Jan 31, 2012 at 2:07 PM, Prasad, Ramit
<ramit.prasad at jpmorgan.com> wrote:
>>Like Neil mentioned, a contextmanager generator is wrapped with an
>>__exit__ method that is guaranteed to be called and that explicitly
>>resumes or closes the generator.  So as long as your contextmanager
>>generator is properly written (i.e. it yields exactly once), the
>>finally block will execute in a timely fashion.
>
> Is that true even in the face of something like sys.exit()?

Yes.

> What happens if 1) sys.exit is called while in the same thread

Why don't you try it and find out?  To answer the question, though,
sys.exit() raises a SystemExit exception, which propagates out of the
with block and calls the __exit__ method, which then throws the
exception to the generator, which executes its finally clause and
exits.  The __exit__ method returns false, so the SystemExit exception
continues to propagate, and if it is not caught, then the process
exits.

> 2) sys.exit is called from another thread but while this thread
> is in context manager?

Then the other thread raises SystemExit, and the current thread is
unaffected.  sys.exit only affects the thread it is called in.

You can certainly come up with scenarios in which the finally clause
does not execute, e.g. killing the interpreter with "kill -9" or
yanking out the power cord.  Within the confines of the Python
interpreter, though, it is guaranteed that the finally block will
execute.



More information about the Python-list mailing list