trio-asyncio icon indicating copy to clipboard operation
trio-asyncio copied to clipboard

aio_as_trio does not work on generator functions and context factory functions

Open SillyFreak opened this issue 7 years ago • 2 comments

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.

SillyFreak avatar Nov 13 '18 11:11 SillyFreak

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

ledmonster avatar Aug 26 '19 09:08 ledmonster

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.

SillyFreak avatar Aug 26 '19 09:08 SillyFreak