On Tue, Jan 8, 2013 at 2:13 AM, Nick Coghlan email@example.com wrote:
On Tue, Jan 8, 2013 at 11:06 AM, Guido van Rossum firstname.lastname@example.org wrote:
On Sun, Jan 6, 2013 at 9:47 PM, Nick Coghlan email@example.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.
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.
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.