A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from http://mail.python.org/pipermail/python-dev/attachments/20171127/69b80a13/attachment.html below:

<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On 27 November 2017 at 14:53, Yury Selivanov <span dir="ltr"><<a href="mailto:yselivanov.ml@gmail.com" target="_blank">yselivanov.ml@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">It is correct.  While 'yield from coro()', where 'coro()' is an 'async<br>
def' coroutine would make sense in some contexts, it would require<br>
coroutines to implement the iteration protocol.  That would mean that<br>
you could write 'for x in coro()', which is meaningless for coroutines<br>
in all contexts.  Therefore, coroutines do not implement the iterator<br>
protocol.</blockquote><div><br></div><div>The two worlds (iterating vs awaiting) collide in an interesting way when one plays with custom Awaitables. </div><div>From your PEP, an awaitable is either a coroutine, or an object implementing __await__,</div><div>*and* that __await__  returns an iterator.</div><div> </div><div>The PEP only says that __await__ must return an iterator, but it turns out that it's also required that that iterator</div><div>should not return any intermediate values.  This requirement is only enforced in the event loop, not</div><div>in the `await` call itself.  I was surprised by that:</div><div><br></div></div></div><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div class="gmail_extra"><div class="gmail_quote"><div>>>> class A:</div></div></div><div class="gmail_extra"><div class="gmail_quote"><div>...  Â  Â def __await__(self):</div></div></div><div class="gmail_extra"><div class="gmail_quote"><div>...  Â  Â  Â  Â for i in range(3):</div></div></div><div class="gmail_extra"><div class="gmail_quote"><div>...  Â  Â  Â  Â  Â  Â yield i  Â  Â  Â  Â  Â  Â  Â # <--- breaking the rules, returning a value</div></div></div><div class="gmail_extra"><div class="gmail_quote"><div>...  Â  Â  Â  Â return 123</div></div></div><div class="gmail_extra"><div class="gmail_quote"><div><br></div></div></div><div class="gmail_extra"><div class="gmail_quote"><div>>>> async def cf():</div></div></div><div class="gmail_extra"><div class="gmail_quote"><div>...  Â  Â x = await A()</div></div></div><div class="gmail_extra"><div class="gmail_quote"><div>...  Â  Â return x</div></div></div><div class="gmail_extra"><div class="gmail_quote"><div><br></div></div></div><div class="gmail_extra"><div class="gmail_quote"><div>>>> c = cf()</div></div></div><div class="gmail_extra"><div class="gmail_quote"><div>>>> c.send(None)</div></div></div><div class="gmail_extra"><div class="gmail_quote"><div>0</div></div></div><div class="gmail_extra"><div class="gmail_quote"><div>>>> c.send(None)</div></div></div><div class="gmail_extra"><div class="gmail_quote"><div>1</div></div></div><div class="gmail_extra"><div class="gmail_quote"><div>>>> c.send(None)</div></div></div><div class="gmail_extra"><div class="gmail_quote"><div>2</div></div></div><div class="gmail_extra"><div class="gmail_quote"><div>>>> c.send(None)</div></div></div><div class="gmail_extra"><div class="gmail_quote"><div>Traceback (most recent call last):</div></div></div><div class="gmail_extra"><div class="gmail_quote"><div>  File "<stdin>", line 1, in <module></div></div></div><div class="gmail_extra"><div class="gmail_quote"><div>StopIteration: 123</div></div></div><div class="gmail_extra"><div class="gmail_quote"><div>123</div></div></div></blockquote><div class="gmail_extra"><div class="gmail_quote"><div><br></div><div>So we drive the coroutine manually using send(), and we see that intermediate calls return the illegally-yielded values.  I broke the rules because my __await__ iterator is returning values (via `yield i`) on each iteration, and that isn't allowed because the event loop wouldn't know what to do with these intermediate values; it only knows that "awaiting" is finished when a value is returned via StopIteration.  However, you only find out that it isn't allowed if you use the loop to run the coroutine function:</div><div><br></div></div></div><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div class="gmail_extra"><div class="gmail_quote"><div><div>>>> import asyncio</div></div></div></div><div class="gmail_extra"><div class="gmail_quote"><div><div>>>> loop = asyncio.get_event_loop()</div></div></div></div><div class="gmail_extra"><div class="gmail_quote"><div><div>>>> loop.run_until_complete(f())</div></div></div></div><div class="gmail_extra"><div class="gmail_quote"><div><div>Traceback (most recent call last):</div></div></div></div><div class="gmail_extra"><div class="gmail_quote"><div><div>  File "<stdin>", line 1, in <module></div></div></div></div><div class="gmail_extra"><div class="gmail_quote"><div><div>  File "/usr/lib64/python3.6/asyncio/base_events.py", line 467, in run_until_complete</div></div></div></div><div class="gmail_extra"><div class="gmail_quote"><div><div>  Â  return future.result()</div></div></div></div><div class="gmail_extra"><div class="gmail_quote"><div><div>  File "<stdin>", line 2, in f</div></div></div></div><div class="gmail_extra"><div class="gmail_quote"><div><div>  File "<stdin>", line 4, in __await__</div></div></div></div><div class="gmail_extra"><div class="gmail_quote"><div><div>RuntimeError: Task got bad yield: 0</div></div></div></div><div class="gmail_extra"><div class="gmail_quote"><div><div>Task got bad yield: 0</div></div></div></div></blockquote><div class="gmail_extra"><div class="gmail_quote"><div><br></div><div>I found this quite confusing when I first came across it, before I understood how asyncio/async/await was put together. The __await__ method  implementation must return an iterator that specifically doesn't return any intermediate values.  This should probably be explained in the docs. I'm happy to help with any documentation improvements if help is desired.</div><div><br></div><div>rgds</div><div>Caleb</div></div></div></div>

RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4