trio-asyncio
trio-asyncio copied to clipboard
Monkeypatching of loop functions doesn't cover all cases
A user on Gitter discovered that this simple-seeming code doesn't work:
from asyncio import get_running_loop
from trio import run
from trio_asyncio import aio_as_trio, open_loop
async def main():
async def inner():
return get_running_loop()
async with open_loop():
print(await aio_as_trio(inner)())
run(main)
There are two issues here:
- If you import individual names from asyncio before importing trio-asyncio, you won't see the monkeypatched versions. This is relevant in practice because of the stylistic convention to put stdlib imports before third-party imports. We can fix this for functions whose originals are defined in Python by changing the
__code__on the same function object, rather than changing which function object the module refers to. For functions defined in C, we can't do that, but we might be able to do something like checksys.getrefcount()of the originals and warn if it's higher than what you get from justimport asyncio. - We aren't updating
asyncio.get_running_looporasyncio._get_running_loopfrom our monkeypatching; we're only updating the references inasyncio.events. This is just an oversight and can easily be fixed. The result is that asyncio internally sees our monkeypatch but users who directly callget_running_loopdon't.