<div dir="ltr">@Kevin correct, that's the point I'd like to discuss. Most other mainstream languages that implements async/await expose the programming model with Tasks/Futures/Promises as opposed to coroutines PEP 492 states 'Objects with __await__ method are called Future-like objects in the rest of this PEP.' but their behavior differs from that of Futures in this core way. Given that most other languages have standardized around async returning a Future as opposed to a coroutine I think it's worth exploring why Python differs.<div><br></div><div>There's a lot of benefits to making the programming model coroutines without a doubt. It's absolutely brilliant that I can just call code annotated with @asyncio.coroutine and have it just work. Code using the old @asyncio.coroutine/yield from syntax should absolutely stay the same. Similarly, since ES7 async/await is backed by Promises it'll just work for any existing code out there using Promises.<br><br>My proposal would be to automatically wrap the return value from an `async` function or any object implementing `__await__` in a future with `asyncio.ensure_future()`. This would allow async/await code to behave in a similar manner to other languages implementing async/await and would remain compatible with existing code using asyncio.</div><div><br></div><div>What's your thoughts?</div><div><br></div><div>Thanks,</div><div>Roy</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Dec 15, 2015 at 3:35 PM, Kevin Conway <span dir="ltr"><<a href="mailto:kevinjacobconway@gmail.com" target="_blank">kevinjacobconway@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><p dir="ltr">I think there may be somewhat of a language barrier here. OP appears to be mixing the terms of coroutines and futures. The behavior OP describes is that of promised or async tasks in other languages.</p><p>Consider a JS promise that has been resolved:</p><p>promise.then(function (value) {...});</p><p>promise.then(function (value) {...});</p><p>Both of the above will execute the callback function with the resolved value regardless of how much earlier the promise was resolved. This is not entirely different from how Futures work in Python when using 'add_done_callback'.</p><p>The code example from OP, however, is showing the behaviour of awaiting a coroutine twice rather than awaiting a Future twice. Both objects are awaitable but both exhibit different behaviour when awaited multiple times.</p><p>A scenario I believe deserves a test is what happens in the asyncio coroutine scheduler when a promise is awaited multiple times. The current __await__ behaviour is to return self only when not done and then to return the value after resolution for each subsequent await. The Task, however, requires that it must be a Future emitted from the coroutine and not a primitive value. Awaiting a resolved future should result </p>
<br><div class="gmail_quote"><div dir="ltr">On Tue, Dec 15, 2015, 14:44 Guido van Rossum <<a href="mailto:guido@python.org" target="_blank">guido@python.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Agreed. (But let's hear from the OP first.)<br></div><div class="gmail_extra"><br><div class="gmail_quote"></div></div><div class="gmail_extra"><div class="gmail_quote">On Tue, Dec 15, 2015 at 12:27 PM, Andrew Svetlov <span dir="ltr"><<a href="mailto:andrew.svetlov@gmail.com" target="_blank">andrew.svetlov@gmail.com</a>></span> wrote:<br></div></div><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Both Yury's suggestions sounds reasonable.<br>
<div><div><br>
On Tue, Dec 15, 2015 at 10:24 PM, Yury Selivanov<br>
<<a href="mailto:yselivanov.ml@gmail.com" target="_blank">yselivanov.ml@gmail.com</a>> wrote:<br>
> Hi Roy and Guido,<br>
><br>
> On 2015-12-15 3:08 PM, Guido van Rossum wrote:<br>
> [..]<span class=""><br>
>><br>
>><br>
>> I don't know how long you have been using async/await, but I wonder if<br>
>> it's possible that you just haven't gotten used to the typical usage<br>
>> patterns? In particular, your claim "anything that takes an `awaitable` has<br>
>> to know that it wasn't already awaited" makes me sound that you're just<br>
>> using it in an atypical way (perhaps because your model is based on other<br>
>> languages). In typical asyncio code, one does not usually take an awaitable,<br>
>> wait for it, and then return it -- one either awaits it and then extracts<br>
>> the result, or one returns it without awaiting it.<br>
><br>
><br></span>
> I agree. Holding a return value just so that coroutine can return it again<br>
> seems wrong to me.<br>
><br>
> However, since coroutines are now a separate type (although they share a lot<br>
> of code with generators internally), maybe we can change them to throw an<br>
> error when they are awaited on more than one time?<br>
><br>
> That should be better than letting them return `None`:<br>
><br>
> coro = coroutine()<br>
> await coro<br>
> await coro # <- will raise RuntimeError<br>
><br>
><br>
> I'd also add a check that the coroutine isn't being awaited by more than one<br>
> coroutine simultaneously (another, completely different issue, more on which<br>
> here: <a href="https://github.com/python/asyncio/issues/288" rel="noreferrer" target="_blank">https://github.com/python/asyncio/issues/288</a>). This was fixed in<br>
> asyncio in debug mode, but ideally, we should fix this in the interpreter<br>
> core.<br>
><br>
> Yury<span class=""><br>
> _______________________________________________<br>
> Python-Dev mailing list<br>
> <a href="mailto:Python-Dev@python.org" target="_blank">Python-Dev@python.org</a><br>
> <a href="https://mail.python.org/mailman/listinfo/python-dev" rel="noreferrer" target="_blank">https://mail.python.org/mailman/listinfo/python-dev</a><br>
> Unsubscribe:<br>
</span></div></div>> <a href="https://mail.python.org/mailman/options/python-dev/andrew.svetlov%40gmail.com" rel="noreferrer" target="_blank">https://mail.python.org/mailman/options/python-dev/andrew.svetlov%40gmail.com</a><br>
<span><font color="#888888"><br>
<br>
<br>
--<br>
Thanks,<br>
Andrew Svetlov<br>
</font></span></blockquote></div></div><span class=""><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div>_______________________________________________<br>
Python-Dev mailing list<br>
<a href="mailto:Python-Dev@python.org" target="_blank">Python-Dev@python.org</a><br>
<a href="https://mail.python.org/mailman/listinfo/python-dev" rel="noreferrer" target="_blank">https://mail.python.org/mailman/listinfo/python-dev</a><br></div></div></blockquote></div></div><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div>
Unsubscribe: <a href="https://mail.python.org/mailman/options/python-dev/guido%40python.org" rel="noreferrer" target="_blank">https://mail.python.org/mailman/options/python-dev/guido%40python.org</a><br>
</div></div></blockquote></div></div><div class="gmail_extra"><br><br clear="all"><br>-- <br><div>--Guido van Rossum (<a href="http://python.org/~guido" target="_blank">python.org/~guido</a>)</div>
</div>
_______________________________________________<br>
Python-Dev mailing list<br>
<a href="mailto:Python-Dev@python.org" target="_blank">Python-Dev@python.org</a><br>
<a href="https://mail.python.org/mailman/listinfo/python-dev" rel="noreferrer" target="_blank">https://mail.python.org/mailman/listinfo/python-dev</a><br></span>
Unsubscribe: <a href="https://mail.python.org/mailman/options/python-dev/kevinjacobconway%40gmail.com" rel="noreferrer" target="_blank">https://mail.python.org/mailman/options/python-dev/kevinjacobconway%40gmail.com</a><br>
</blockquote></div></div>
<br>_______________________________________________<br>
Python-Dev mailing list<br>
<a href="mailto:Python-Dev@python.org">Python-Dev@python.org</a><br>
<a href="https://mail.python.org/mailman/listinfo/python-dev" rel="noreferrer" target="_blank">https://mail.python.org/mailman/listinfo/python-dev</a><br>
Unsubscribe: <a href="https://mail.python.org/mailman/options/python-dev/rwilliams%40lyft.com" rel="noreferrer" target="_blank">https://mail.python.org/mailman/options/python-dev/rwilliams%40lyft.com</a><br>
<br></blockquote></div><br></div>