user1475412 user1475412 - 1 year ago 58
Python Question

How does asyncio.sleep work with negative values?

I decided to implement sleep sort ( using Python's

when I made a strange discovery: it works with negative values (and returns immediately with 0)!

Here is the code (you can run it here

import asyncio
import random

async def sleepy(value):
return await asyncio.sleep(value, result=value)

async def main(input_values):
result = []
for sleeper in asyncio.as_completed(map(sleepy, input_values)):
result.append(await sleeper)

if __name__ == '__main__':
loop = asyncio.get_event_loop()
input_values = list(range(-5, 6))

The code takes 5 seconds to execute, as expected, but the result is always
[0, -5, -4, -3, -2, -1, 1, 2, 3, 4, 5]
. I can understand 0 returning immediately, but how are the negative values coming back in the right order?

Answer Source

If you take a look at the asyncio source, sleep special cases 0 and returns immediately.

if delay == 0:
    return result

If you continue through the source, you'll see that any other value gets passed through to the event loop's call_later method. Looking at how call_later is implemented for the default loop (BaseEventLoop), you'll see that call_later passes a time to call_at.

self.call_at(self.time() + delay, callback, *args)

The reason the values are turned in order is that the times created with negative delays occur before those with positive delays.