outsmarting context managers with coroutines

Ian Kelly ian.g.kelly at gmail.com
Sun Dec 29 06:06:37 CET 2013

On Sat, Dec 28, 2013 at 5:35 PM, Burak Arslan
<burak.arslan at arskom.com.tr> wrote:
> On 12/29/13 00:13, Burak Arslan wrote:
>> Hi,
>> Have a look at the following code snippets:
>> https://gist.github.com/plq/8164035
>> Observations:
>> output2: I can break out of outer context without closing the inner one
>> in Python 2
>> output3: Breaking out of outer context closes the inner one, but the
>> closing order is wrong.
>> output3-yf: With yield from, the closing order is fine but yield returns
>> None before throwing.
> It doesn't, my mistake. Python 3 yield from case does the right thing, I
> updated the gist. The other two cases still seem weird to me though. I
> also added a possible fix for python 2 behaviour in a separate script,
> though I'm not sure that the best way of implementing poor man's yield from.

I don't see any problems here.  The context managers in question are
created in separate coroutines and stored on separate stacks, so there
is no "inner" and "outer" context in the thread that you posted.  I
don't believe that they are guaranteed to be called in any particular
order in this case, nor do I think they should be.

For example, the first generator could yield the second generator back
to its caller and then exit, in which case the second generator would
still be active while the context manager in the first generator would
already have done its clean-up.  To assure that the context managers
exit in the order you suggest, the call to the first context manager's
exit would have to be deferred until the second context manager exits,
which could happen much later.  That would complicate the
implementation and does not fit very well with the cooperative
multi-tasking model.

More information about the Python-list mailing list