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

Guido van Rossum guido at python.org
Tue Jan 8 19:32:00 CET 2013


On Tue, Jan 8, 2013 at 2:13 AM, Nick Coghlan <ncoghlan at gmail.com> wrote:

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.

Is your idea that if you write "with yielding x as y: blah" this effectively replaces the calls to enter and exit with "yield from x.enter()" and "yield from x.enter()"? (And assigning the result of yield fro, x.enter() to y.)

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: asynccm = db.session() conn = yield from asynccm.enter() try: # Use session here except Exception as exc: # Rollback yield from asynccm.exit(type(exc), exc, exc.traceback) else: # Commit yield from asynccm.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.

Sure, I didn't intend any time pressure. Others may take this up as well -- or if nobody cares, we can put it off until the need has been demonstrated more. possibly after Python 3.4 is release.

-- --Guido van Rossum (python.org/~guido)



More information about the Python-ideas mailing list