Question about asyncio and blocking operations

Ian Kelly ian.g.kelly at gmail.com
Mon Jan 25 10:45:12 EST 2016


On Mon, Jan 25, 2016 at 8:32 AM, Ian Kelly <ian.g.kelly at gmail.com> wrote:
>
> On Jan 25, 2016 2:04 AM, "Frank Millman" <frank at chagford.com> wrote:
>>
>> "Ian Kelly"  wrote in message
>> news:CALwzidnGOgpx+CpMVBA8vpEFuq4-BwMVS0gZ3ShB0oWZi0Bw+Q at mail.gmail.com...
>>>
>>> This seems to be a common misapprehension about asyncio programming.
>>> While coroutines are the focus of the library, they're based on
>>> futures, and so by working at a slightly lower level you can also
>>> handle them as such. So  while this would be the typical way to use
>>> run_in_executor:
>>>
>>> async def my_coroutine(stuff):
>>>     value = await get_event_loop().run_in_executor(None,
>>> blocking_function, stuff)
>>>     result = await do_something_else_with(value)
>>>     return result
>>>
>>> This is also a perfectly valid way to use it:
>>>
>>> def normal_function(stuff):
>>>     loop = get_event_loop()
>>>     coro = loop.run_in_executor(None, blocking_function, stuff)
>>>     task = loop.create_task(coro)
>>>     task.add_done_callback(do_something_else)
>>>     return task
>>
>>
>> I am struggling to get my head around this.
>>
>> 1. In the second function, AFAICT coro is already a future. Why is it
>> necessary to turn it into a task? In fact when I tried that in my testing, I
>> got an assertion error -
>>
>> File: "C:\Python35\lib\asyncio\base_events.py", line 211, in create_task
>>    task = tasks.Task(coro, loop=self)
>> File: "C:\Python35\lib\asyncio\tasks.py", line 70, in __init__
>>    assert coroutines.iscoroutine(coro), repr(coro)
>> AssertionError: <Future pending ... >
>
> I didn't test this; it was based on the documentation, which says that
> run_in_executor is a coroutine. Looking at the source, it's actually a
> function that returns a future, so this may be a documentation bug.

And now I'm reminded of this note in the asyncio docs:

"""
Note: In this documentation, some methods are documented as
coroutines, even if they are plain Python functions returning a
Future. This is intentional to have a freedom of tweaking the
implementation of these functions in the future. If such a function is
needed to be used in a callback-style code, wrap its result with
ensure_future().
"""

IMO such methods should simply be documented as awaitables, not
coroutines. I wonder if that's already settled, or if it's worth
starting a discussion around.



More information about the Python-list mailing list