Yury Selivanov added the comment:

> 2) Awaitable.register(Coroutine)
> I think this is incorrect. A Coroutine is not Awaitable unless it also 
> implements "__await__". How else should it be awaited?

It *is* correct, see PEP 492.  Awaitable is either a coroutine *or* an object 
with an __await__ method.  Generally, being an awaitable means that the object 
can be used in "await" expression.

> 3)
> I propose to use this wrapping code as a fallback for types.coroutine() in 
> the case that a Generator (ABC) is passed instead of a generator (yield):

Just implement tp_await/__await__ for coroutine-like objects coming from C-API 
or Cython.  In general, iteration protocol is still the foundation for 
Future-like objects, so there is nothing wrong with this.

Generator ABC isn't supposed to be used with "await" expression.

> 4)
>     def test_func_2(self):
>         async def foo():
>             raise StopIteration
>         with self.assertRaisesRegex(
>                 RuntimeError, "generator raised StopIteration"):
>             run_async(foo())

> Why is this actually necessary? I'm aware that it's also mentioned in the 
> PEP, but is there an actual reason why a coroutine should behave the same as 
> a generator here? Is it just an implementation detail for legacy reasons 
> because generators and coroutines happen to share the same type 
> implementation? (I don't think they need to, BTW.)

Coroutines are implemented on top of generators.  Until we clearly separate 
them (in 3.6?) I don't think we should allow coroutines to bubble up 

> 5)
>     def test_func_8(self):
>         @types.coroutine
>         def bar():
>             return (yield from foo())
>        async def foo():
>             return 'spam'
>         self.assertEqual(run_async(bar()), ([], 'spam') )
> I find it surprising that this works at all. Yield-from iterates, and a 
> coroutine is not supposed to be iterable, only awaitable (at least, that's 
> what all error messages tell me when I try it). So why should "yield from" 
> work on them? What if foo() was not an Iterable but a Coroutine? Should 
> "yield from" then call "__await__" on it internally? I would find that 
> *really* surprising, but given the above, I think it would be necessary to 
> achieve consistency.

This is a special backwards-compatibility thing.  In general, generators cannot 
yield-from coroutines (unless they are decorated with @types.coroutine).


Python tracker <rep...@bugs.python.org>
Python-bugs-list mailing list

Reply via email to