I have observed that the asyncio.run_coroutine_threadsafe function does not accept general awaitable objects, and I do not understand the reason for this restriction. Observe
import asyncio async def native_coro(): return @asyncio.coroutine def generator_based_coro(): return class Awaitable: def __await__(self): return asyncio.Future() loop = asyncio.get_event_loop() asyncio.run_coroutine_threadsafe(native_coro(), loop) asyncio.run_coroutine_threadsafe(generator_based_coro(), loop) asyncio.run_coroutine_threadsafe(Awaitable(), loop) Running this with Python 3.6.6 yields
Traceback (most recent call last): File "awaitable.py", line 24, in <module> asyncio.run_coroutine_threadsafe(Awaitable(), loop) File "~/.local/python3.6/lib/python3.6/asyncio/tasks.py", line 714, in run_coroutine_threadsafe raise TypeError('A coroutine object is required') TypeError: A coroutine object is required where line 24 is asyncio.run_coroutine_threadsafe(Awaitable(), loop).
I know I can wrap my awaitable object in a coroutine defined like
awaitable = Awaitable() async def wrapper(): return await awaitable asyncio.run_coroutine_threadsafe(wrapper(), loop) however my expectation was that the awaitable would be a valid argument directly to run_coroutine_threadsafe.
My questions are:
- What is the reason for this restriction?
- Is the
wrapperfunction defined above the most conventional way to pass an awaitable torun_coroutine_threadsafeand other APIs that demand anasync defor generator-defined coroutine?