trio-asyncio
trio-asyncio copied to clipboard
aio_as_trio does not work on generator functions and context factory functions
I was a little surprised that, when using aio_as_trio as a decorator, it only works on regular coroutine functions. For the followig test, only the non-commented parts work:
async with trio_asyncio.open_loop():
@trio_asyncio.aio_as_trio
async def func():
await asyncio.sleep(0.1)
return 1
# @trio_asyncio.aio_as_trio
# async def gen():
# yield 1
# await asyncio.sleep(0.1)
# yield 2
# @trio_asyncio.aio_as_trio
# @asynccontextmanager
# async def ctx():
# await asyncio.sleep(0.1)
# yield 1
assert await func() == 1
# assert [item async for item in gen()] == [1, 2]
# async with ctx() as value:
# assert value == 1
I found that the (maybe naive?) fix was not too hard; the following works as a replacement and makes the test above work:
def aio_as_trio(proc, *, loop=None):
@functools.wraps(proc)
def wrapper(*args, **kwargs):
return Asyncio_Trio_Wrapper(proc(*args, **kwargs), loop=loop)
return wrapper
If there is nothing I'm missing in this adaptation, I think this would make cross calling a lot cleaner.
Nest function call by trio_asyncio.aio_as_trio, instead of using decorator, and it worked.
async def test():
async with trio_asyncio.open_loop():
async def func():
await asyncio.sleep(0.1)
return 1
assert await trio_asyncio.aio_as_trio(func()) == 1
async def gen():
yield 1
await asyncio.sleep(0.1)
yield 2
assert [item async for item in trio_asyncio.aio_as_trio(gen())] == [1, 2]
@asynccontextmanager
async def ctx():
await asyncio.sleep(0.1)
yield 1
async with trio_asyncio.aio_as_trio(ctx()) as value:
assert value == 1
This behavior is described here:
- https://github.com/python-trio/trio-asyncio/blob/4990c61/trio_asyncio/base.py#L240-L242
Yes, but decorator would be nicer to write, because it's at the declaration site instead of at every call site. At least having the option would be good.