On Fri, Nov 24, 2017 at 9:35 AM, Ian Kelly <ian.g.ke...@gmail.com> wrote: > On Fri, Nov 24, 2017 at 6:31 AM, Frank Millman <fr...@chagford.com> wrote: >> "Frank Millman" wrote in message news:ov5v3s$bv7$1...@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.
By the way, this is what you get instead when you replace run_forever() with run_until_complete(cnt2): $ 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 Traceback (most recent call last): File "test.py", line 27, in <module> loop.run_until_complete(cnt2) File "/usr/lib/python3.5/asyncio/base_events.py", line 387, in run_until_complete return future.result() File "/usr/lib/python3.5/asyncio/futures.py", line 274, in result raise self._exception 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' No need for Ctrl-C in this case because the loop notices that counter2 died and stops on its own, and you get a nice traceback explaining what happened. -- https://mail.python.org/mailman/listinfo/python-list