python-trio / trio-asyncio

a re-implementation of the asyncio mainloop on top of Trio
Other
188 stars 37 forks source link

Maybe a problem with trio-asyncio & python 3.8 #63

Closed OliverTED closed 4 years ago

OliverTED commented 4 years ago

Hey there! I have problems calling asyncio code from trio using trio_asyncio in python 3.8.

The following example is almost identical to the one from the docs. It works in python 3.7, but fails in python 3.8. After adding the monkeypatching flagged by the 'if False', it also works in python 3.8. Am I doing something wrong?

Thanks!

import trio
import asyncio
import trio_asyncio

if False:  # set to true to make it work in python 3.8
        from asyncio import events as _aio_event
        try:
            _orig_run_get = _aio_event.get_running_loop
        except AttributeError:
            pass
        else:
            def _new_run_get():
                return _aio_event._get_running_loop()
            _aio_event.get_running_loop = _new_run_get

async def some_asyncio_code():
        await asyncio.sleep(1)

async def some_trio_code():
        async with trio_asyncio.open_loop() as loop:
                await trio_asyncio.aio_as_trio(some_asyncio_code)()

trio.run(some_trio_code)

Here is the error in python 3.8:

.../python3.8/site-packages/trio_asyncio/base.py:718: TrioDeprecationWarning: trio.Event.clear is deprecated since Trio 0.12.0; use multiple Event objects or other synchronization primitives instead (https://github.com/python-trio/trio/issues/637) self._stopped.clear() Traceback (most recent call last): File "bugtest1/bugfix_2.py", line 28, in trio.run(some_trio_code) File ".../python3.8/site-packages/trio/_core/_run.py", line 1804, in run raise runner.main_task_outcome.error File "bugtest1/bugfix_2.py", line 26, in some_trio_code await trio_asyncio.aio_as_trio(some_asyncio_code)() File ".../python3.8/site-packages/trio_asyncio/adapter.py", line 76, in call return await self.loop.run_aio_coroutine(f) File ".../python3.8/site-packages/trio_asyncio/base.py", line 229, in run_aio_coroutine return await run_aio_future(coro) File ".../python3.8/site-packages/trio_asyncio/util.py", line 39, in run_aio_future res = await trio.hazmat.wait_task_rescheduled(abort_cb) File ".../python3.8/site-packages/trio/_core/_traps.py", line 165, in wait_task_rescheduled return (await _async_yield(WaitTaskRescheduled(abort_func))).unwrap() File ".../python3.8/site-packages/outcome/_sync.py", line 111, in unwrap raise captured_error File ".../python3.8/site-packages/trio_asyncio/adapter.py", line 39, in _call_defer return await proc(*args, kwargs) File "bugtest1/bugfix_2.py", line 22, in some_asyncio_code await asyncio.sleep(1) File ".../python3.8/asyncio/tasks.py", line 637, in sleep loop = events.get_running_loop() RuntimeError: no running event loop**

smurfix commented 4 years ago

trio-asyncio is currently semi-maintained at best, and hasn't been adapted to the last two Trio releases (nor the 3.8 Python release).

Feel free to submit patches. :-/

OliverTED commented 4 years ago

Good to know. Well I can wrap my fix together and submit a patch. It lets trio_asyncio run again on python 3.8. But honestly I do not know if the solutions is a good one.

ssfdust commented 4 years ago

@OliverTED Hello, could you share your workaround? It freaks me out these days.

OliverTED commented 4 years ago

Sure. Here is the code that worked for me (I tested this only on little and only on python 3.8):

import trio_asyncio

from trio_asyncio import *
from asyncio import events as _aio_event

# the following workaround is apparaently necessary in python 3.8
try:
    _orig_run_get = _aio_event.get_running_loop
except AttributeError:
    pass
else:
    def _new_run_get():
        return _aio_event._get_running_loop()
    _aio_event.get_running_loop = _new_run_get
parity3 commented 4 years ago

Not sure if related, but I had to put the following at the top of my first async function (called by trio_asyncio.run):

# noinspection PyProtectedMember
asyncio._set_running_loop(asyncio.get_event_loop())
ssfdust commented 4 years ago

@OliverTED Really sorry for the slow response. At the end of 2019, I'm a little busy, some from life, some from work. Your workaround works for my project too, Thank you very much.

pelid commented 4 years ago

Same problem with Python 3.7.5 when use aioredis==1.3.1. Code sample:

import aioredis
import trio_asyncio
from functools import partial

async def main():
    create_redis_pool = partial(
        aioredis.create_redis_pool,
        address='...',
        encoding='utf-8'
    )

    redis = await trio_asyncio.run_asyncio(create_redis_pool)
    print('Redis connected')

trio_asyncio.run(main)

Got similar traceback:

  File ".../aioredis/stream.py", line 23, in open_connection
    transport, _ = await get_event_loop().create_connection(
RuntimeError: no running event loop

Workaround suggested above works fine. Thanks to @parity3 !

pquentin commented 4 years ago

Can you please try the 0.11.0 release and tell us if it helps?

oremanj commented 4 years ago

This error appears to be resolved in 0.11.0, so closing. Please feel free to reopen if your issue is indeed unresolved.