asyncio
asyncio copied to clipboard
RuntimeError when reading from stream right after a cancellation
The following code produces a RuntimeError
if the first readline
operation times out:
try:
return await asyncio.wait_for(reader.readline(), 1.)
except asyncio.TimeoutError:
print('Timeout!')
# await asyncio.sleep(0)
return await reader.readline()
The corresponding error:
File "/usr/local/lib/python3.5/asyncio/streams.py", line 419, in _wait_for_data
'already waiting for incoming data' % func_name)
RuntimeError: readline() called while another coroutine is already waiting for
incoming data
That doesn't happen if the await asyncio.sleep(0)
line is uncommented.
That's because wait_for
cancels the reader.readline()
task but doesn't give the control back to the event loop. Then we try to read again and _wait_for_data
check if reader._waiter is None
. That fails because the finally
clause of the previous _wait_for_data
still hasn't cleared reader._waiter
.
I guess this could be solved by either checking for cancelled _waiter
at the beginning of _wait_for_data
or giving the control back to the event loop after a failed wait_for
.
I can confirm this behavior and I'd say it can be filed as a bug.