This question related to the same question in a synchronous version. The goal is to design decorator that would take as input either a generator or a coroutine as parameter. The code I have looks like:
import asyncio
def say_hello(function):
async def decorated(*args, **kwargs):
return_value = function(*args, **kwargs)
if isinstance(return_value, types.AsyncGeneratorType):
print("Hello async generator!")
async for v in return_value:
yield v
else:
print("Hello coroutine!")
return await return_value
return decorated
@helpers.say_hello
async def generator():
for i in range(5):
await asyncio.sleep(0.2)
yield i
@helpers.say_hello
async def coroutine():
await asyncio.sleep(1)
return list(range(5))
async def test():
for v in generator():
print(v)
for v in coroutine():
print(v)
The error this gives is:
'return' with value in async generator
Which I guess is just checked statically on the fact that decorated
contains both a yield
and a return
with a value.
Is there any way to make this work? (Other than having a parameter in say_hello
to specify if function
is a generator or a coroutine).