1

The following code works fine:

import asyncio loop = asyncio.get_event_loop() async def a (): print('hello') def b (): yield from asyncio.sleep(1) loop.run_until_complete(b()) loop.close() print('done') 

But, the following fails:

import asyncio loop = asyncio.get_event_loop() async def a (): print('hello') def b (): yield from a() # <=========== only 1 tiny change loop.run_until_complete(b()) loop.close() print('done') 

Decorating b with @asyncio.coroutine makes it work.

But, the question is why does the first piece of code work fine without the @asyncio.coroutine decorator? The docs clearly say that asyncio.sleep is a coroutine, and so is a, so why does the code fail in one case and work fine for the other case?

1 Answer 1

4

Your code produces the following error:

... yield from a() # <=========== only 1 tiny change TypeError: cannot 'yield from' a coroutine object in a non-coroutine generator 

As clearly stated in the error message, when using asyncio, you should either use @coroutine or async def to mark your coroutines. In async defs, await should be used instead of yield from:

import asyncio async def a(): print('hello') async def b(): await a() loop = asyncio.get_event_loop() loop.run_until_complete(b()) loop.close() print('done') 

or, for python 3.4:

import asyncio @asyncio.coroutine def a(): print('hello') @asyncio.coroutine def b(): yield from a() loop = asyncio.get_event_loop() loop.run_until_complete(b()) loop.close() print('done') 

Your first example is considered "buggy", but it is executing "properly" because run_until_complete calls iscoroutine which currently returns True for generators (any def with a yield/yield from), but this is an implementation detail that might change in a future version of python. Using @couroutine on def a() (instead of async def a()), or even just adding yield from asyncio.sleep(1) to a regular def a() would make your second example run as well. Currently python might be "merciful" when using generators which are not marked as coroutines in asyncio, but not when using async defs.

Sign up to request clarification or add additional context in comments.

1 Comment

thanks @udi here's another puzzle that might be of interest: stackoverflow.com/questions/41708609/…

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.