AsyncIO for the Working Python Developer
By using yield from on another coroutine we declare that the coroutine may give the control back to the event loop, in this case sleep will yield and the event loop will switch contexts to the next task scheduled for execution: bar. Similarly the bar function yields from sleep which allows the event loop to pass control back to foo at the point where it yielded, as it happens with all generators.