[Python-ideas] Yielding through context managers
Nick Coghlan
ncoghlan at gmail.com
Tue Jan 8 11:13:50 CET 2013
On Tue, Jan 8, 2013 at 11:06 AM, Guido van Rossum <guido at python.org> wrote:
> On Sun, Jan 6, 2013 at 9:47 PM, Nick Coghlan <ncoghlan at gmail.com> wrote:
>> Ah, true, I hadn't thought of that. So yes, any case where the
>> __exit__ method can be "fire-and-forget" is also straightforward to
>> implement with just PEP 3156. That takes us back to things like
>> database transactions being the only ones where
>
> And 'yielding' wouldn't do anything about this, would it?
Any new syntax should properly handle the database transaction context
manager problem, otherwise what's the point? The workarounds for
asynchronous __next__ and __enter__ methods aren't too bad - it's
allowing asynchronous __exit__ methods that can only be solved with
new syntax.
>> I'm not seeing any obvious holes in that strategy, but I haven't
>> looked closely at the compiler code in a while, so there may be
>> limitations I haven't accounted for.
>
> So would 'yielding' insert the equivalent of 'yield from' or the
> equivalent of 'yield' in the code?
Given PEP 3156, the most logical would be for it to use "yield from",
since that is becoming the asynchronous equivalent of a normal
function call.
Something like:
with yielding db.session() as :
# Do stuff here
Could be made roughly equivalent to:
_async_cm = db.session()
conn = yield from _async_cm.__enter__()
try:
# Use session here
except Exception as exc:
# Rollback
yield from _async_cm.__exit__(type(exc), exc, exc.__traceback__)
else:
# Commit
yield from _async_cm.__exit__(None, None, None)
Creating a contextlib.contextmanager style decorator for writing such
asynchronous context managers would be difficult, though, as the two
different meanings of "yield" would get in each other's way - you
would need something like "yield EnterResult(expr)" to indicate to
__enter__ in the wrapper object when to stop. It would probably be
easier to just write separate __enter__ and __exit__ methods as
coroutines.
However, note that I just wanted to be clear that I consider the idea
of a syntax for "asynchronous context managers" plausible, and
sketched out a possible design to explain *why* I thought it should be
possible. My focus will stay with PEP 432 until that's done.
Cheers,
Nick.
--
Nick Coghlan | ncoghlan at gmail.com | Brisbane, Australia
More information about the Python-ideas
mailing list