Why does asyncio.wait_for() need a timeout?

Ian Kelly ian.g.kelly at gmail.com
Fri Nov 24 11:35:57 EST 2017


On Fri, Nov 24, 2017 at 6:31 AM, Frank Millman <frank at chagford.com> wrote:
> "Frank Millman"  wrote in message news:ov5v3s$bv7$1 at blaine.gmane.org...
>
>> Below is a simple asyncio loop that runs two background tasks.
>>
> [...]
>>
>>
>> Both take an optional timeout.
>>
>> If I use the first method without a timeout, the cancellation completes
>> and the loop stops.
>>
>> If I use the second method without a timeout, the future is cancelled, but
>> the program hangs.
>>
>> If I add a timeout to the second one, it behaves the same as the first
>> one.
>>
>> Is there a reason for this?
>>
>
> I have figured out half of the answer.
>
> 'timeout' is an optional argument when using wait(), but a required one when
> using wait_for().
>
> Therefore asyncio is raising an exception.
>
> However, I do not understand why no traceback appears.

Here's the output I get when I try it and then interrupt with Ctrl-C:

$ python3 test.py
>From 1: 1
>From 2: 1
>From 1: 2
>From 2: 2
>From 1: 3
>From 2: 3
>From 1: 4
>From 2: 4
>From 1: 5
>From 2: 5
>From 1: 6
counter1 cancelled
^CTraceback (most recent call last):
  File "test.py", line 27, in <module>
    loop.run_forever()
  File "/usr/lib/python3.5/asyncio/base_events.py", line 345, in run_forever
    self._run_once()
  File "/usr/lib/python3.5/asyncio/base_events.py", line 1276, in _run_once
    event_list = self._selector.select(timeout)
  File "/usr/lib/python3.5/selectors.py", line 441, in select
    fd_event_list = self._epoll.poll(timeout, max_ev)
KeyboardInterrupt
Task exception was never retrieved
future: <Task finished coro=<counter2() done, defined at test.py:13>
exception=TypeError("wait_for() missing 1 required positional
argument: 'timeout'",)>
Traceback (most recent call last):
  File "/usr/lib/python3.5/asyncio/tasks.py", line 239, in _step
    result = coro.send(None)
  File "test.py", line 20, in counter2
    await asyncio.wait_for(cnt1)  # hangs
TypeError: wait_for() missing 1 required positional argument: 'timeout'


The unhandled exception is shown as a warning when the loop exits. It
can't be shown prior to that because there could be some other task,
even one that hasn't been scheduled yet, that might try to get the
result of the counter2 task and handle the exception.



More information about the Python-list mailing list