title: Precise specification of __await__
body: <p>The Python Language Reference specifies <a href="https://docs.python.org/3/reference/datamodel.html?highlight=__await__#object.__await__" rel="noreferrer"><code>object.__await__</code></a> as follows:</p>
  <blockquote>
  <p><code>object.__await__(self)</code></p>
  <p>Must return an iterator. Should be used to implement awaitable objects. For instance, <code>asyncio.Future</code> implements this method to be compatible with the await expression.</p>
  </blockquote>
  <p>That's it. I find this specification very vague and not very specific (ironically). Ok, it should return an iterator, but can it be an arbitrary iterator? Obviously not:</p>
  <pre class="lang-py prettyprint-override"><code>import asyncio
  
  
  class Spam:
      def __await__(self):
          yield from range(10)
  
  
  async def main():
      await Spam()
  
  
  asyncio.run(main())
  </code></pre>
  <pre class="lang-none prettyprint-override"><code>RuntimeError: Task got bad yield: 0
  </code></pre>
  <p>I'm assuming the <code>asyncio</code> event loop expects a specific kind of object being yielded by the iterator. Then what <em>exactly</em> should it yield? (And why isn't this documented?)</p>
  <hr />
  <p><strong>Edit:</strong> as far as I can see, this isn't documented anywhere. But I've been investigating on my own, and I think that the key to understanding what objects the <code>asyncio</code> expects its coroutines to yield lies in <a href="https://github.com/python/cpython/blob/529f42645d38b6b0075f256814dfb3d220ac7d92/Modules/_asynciomodule.c#L2624-L2973" rel="noreferrer"><code>task_step_impl</code></a> in <code>_asynciomodule.c</code>.</p>
  <hr />
  <p><strong>Update:</strong> I've made a PR to the cpython repository with the aim of clarifying this: <a href="https://github.com/python/cpython/pull/22320" rel="noreferrer">&quot;Clarify the vague specification of <code>object.__await__</code>&quot;</a>. It's currently in the process of being reviewed.</p>