[Python-ideas] Yielding through context managers (original) (raw)

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