Why does asyncio.wait_for() need a timeout?

Frank Millman frank at chagford.com
Thu Nov 23 02:58:58 EST 2017


Hi all

Below is a simple asyncio loop that runs two background tasks.

They both perform a simple count. The first one counts forever, wrapped in a 
try/except. The second one counts up to 5, then cancels the first one and 
stops the loop.

There are two ways of ensuring that then cancellation is complete -

    asyncio.wait([a sequence of futures])

    asyncio.wait_for(a single future)

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 am using version 3.6.0.

Thanks

Frank Millman

import asyncio
from itertools import count

async def counter1():
    cnt = count(1)
    try:
        while True:
            print('From 1:', next(cnt))
            await asyncio.sleep(1)
    except asyncio.CancelledError:
        print('counter1 cancelled')

async def counter2():
    cnt = count(1)
    for i in range(5):
        print('From 2:', next(cnt))
        await asyncio.sleep(1)
    cnt1.cancel()
#   await asyncio.wait([cnt1])  # works
#   await asyncio.wait_for(cnt1)  # hangs
    await asyncio.wait_for(cnt1, 1)  # works
    loop.stop()

loop = asyncio.get_event_loop()
cnt1 = asyncio.ensure_future(counter1())
cnt2 = asyncio.ensure_future(counter2())
loop.run_forever()





More information about the Python-list mailing list