<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Fri, Jun 3, 2016 at 8:48 PM, Guido van Rossum <span dir="ltr"><<a href="mailto:guido@python.org" target="_blank">guido@python.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">OK, that helps. Could you talk me through the crucial<br>
incompatibilities here? (If that's too  much to ask I'm also happy to<br>
leave this up to the experts -- I trust that there's more than enough<br>
brainpower here to come up with a solution that works for all<br>
concerned.)<br></blockquote><div><br></div><div>Coroutines that are chained together with either `yield from` or `await` are essentially one big generator with one shared coroutine runner. At the bottom, though, are the actual objects that are yielded by this generator (in asyncio, this happens in `Future.__iter__`). If the coroutine runner is asyncio.Task, it will raise if any part of this chain of coroutines yields anything but None or an asyncio.Future. The Tornado coroutine runner is more liberal: it accepts its own futures as well as asyncio and concurrent futures or twisted deferreds. </div><div><br></div><div>In other words, this works with tornado, but not with asyncio:</div><div><br></div><div><div>import asyncio</div><div>import tornado.gen</div><div>import tornado.ioloop</div><div>import tornado.platform.asyncio</div><div><br></div><div>use_tornado = False</div><div><br></div><div>async def f():</div><div>    await asyncio.sleep(0.1)</div><div>    await tornado.gen.sleep(0.1)</div><div><br></div><div>if use_tornado:</div><div>    tornado.platform.asyncio.AsyncIOMainLoop().install()</div><div>    tornado.ioloop.IOLoop.current().run_sync(f)</div><div>else:</div><div>    asyncio.get_event_loop().run_until_complete(f())</div></div><div><br></div><div><br></div><div><br></div><div><br></div><div>There were more incompatibilities with the yield-based syntax than with the await-based syntax. Tornado's coroutine runner allowed you to yield objects like lists and dicts (yielding a container was a kind of fork/join) that were not allowed in asyncio (thanks mainly to asyncio's use of `yield from`). The introduction of `await` has imposed similar restrictions on both systems, so there is no more yielding of lists or dicts in either case; explicit wrapper objects must be used. (but there's still a difference in that asyncio.Task allows None but tornado coroutines do not)</div><div><br></div><div><br></div><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">
<div class=""><div class="h5"><br>
On Fri, Jun 3, 2016 at 5:45 PM, Ben Darnell <<a href="mailto:ben@bendarnell.com">ben@bendarnell.com</a>> wrote:<br>
> On Fri, Jun 3, 2016 at 8:43 PM, Guido van Rossum <<a href="mailto:guido@python.org">guido@python.org</a>> wrote:<br>
>><br>
>> Could someone point me to the specific code that's considered the<br>
>> coroutine runner in asyncio and Tornado? I've been immersed in asyncio<br>
>> for so long that I don't know which part you're talking about. :-(<br>
><br>
><br>
> asyncio.Task and tornado.gen.Runner. Basically the thing that calls next()<br>
> and send() on generator objects.<br>
><br>
>><br>
>><br>
>> On Fri, Jun 3, 2016 at 5:26 PM, Nathaniel Smith <<a href="mailto:njs@pobox.com">njs@pobox.com</a>> wrote:<br>
>> > On Fri, Jun 3, 2016 at 5:14 PM, Ben Darnell <<a href="mailto:ben@bendarnell.com">ben@bendarnell.com</a>> wrote:<br>
>> >> I think this could be useful, but's answering the question of "what<br>
>> >> coroutine runner is this", not "what event loop is this".<br>
>> ><br>
>> > Thanks, that's definitely a better way to put it.<br>
>> ><br>
>> > -n<br>
>> ><br>
>> > --<br>
>> > Nathaniel J. Smith -- <a href="https://vorpus.org" rel="noreferrer" target="_blank">https://vorpus.org</a><br>
>> > _______________________________________________<br>
>> > Async-sig mailing list<br>
>> > <a href="mailto:Async-sig@python.org">Async-sig@python.org</a><br>
>> > <a href="https://mail.python.org/mailman/listinfo/async-sig" rel="noreferrer" target="_blank">https://mail.python.org/mailman/listinfo/async-sig</a><br>
>> > Code of Conduct: <a href="https://www.python.org/psf/codeofconduct/" rel="noreferrer" target="_blank">https://www.python.org/psf/codeofconduct/</a><br>
>><br>
>><br>
>><br>
>> --<br>
>> --Guido van Rossum (<a href="http://python.org/~guido" rel="noreferrer" target="_blank">python.org/~guido</a>)<br>
><br>
><br>
<br>
<br>
<br>
--<br>
--Guido van Rossum (<a href="http://python.org/~guido" rel="noreferrer" target="_blank">python.org/~guido</a>)<br>
</div></div></blockquote></div><br></div></div>