I wanted to use a ThreadPoolExecutor from a python coroutine, to delegate some blocking network calls to a separate thread. However, running the following code:
from concurrent.futures import ThreadPoolExecutor import asyncio def work(): # do some blocking io pass async def main(): executor = ThreadPoolExecutor() await executor.submit(work) loop = asyncio.get_event_loop() loop.run_until_complete(main()) loop.close()
causes error:
TypeError: object Future can't be used in 'await' expression
Aren't Future
objects awaitable? Why does it say they aren't?
How can I await
a Future
object returned by executor.submit
?
Python 3.5.0
EDIT
Using executor.submit
is not my decision. This is used internally by several libraries, like requests-futures
. I am searching for a way to interop with those modules from coroutines.
You should use loop.run_in_executor
:
from concurrent.futures import ThreadPoolExecutor import asyncio def work(): # do some blocking io pass async def main(loop): executor = ThreadPoolExecutor() await loop.run_in_executor(executor, work) loop = asyncio.get_event_loop() loop.run_until_complete(main(loop)) loop.close()
EDIT
concurrent.futures.Future
object are different from asyncio.Future
. The asyncio.Future
is intended to be used with event loops and is awaitable, while the former isn't. loop.run_in_executor
provides the necessary interoperability between the two.
EDIT #2
Using executor.submit is not my decision. This is used internally by several libraries, like requests-futures. I am searching for a way to interop with those modules from coroutines.
Although undocumented, you can use asyncio.wrap_future(future, *, loop=None)
to convert a concurrent.futures.Future
to a asyncio.Future
.