The real answer is that Guido likes the fact that asynchronous yield points are explicit in coroutines, because if you don't realize that a call can yield, then that's an invitation to concurrency problems -- like with threads. But if you have to write an explicit yield from
, it's fairly easy to make sure it doesn't land in the middle of two critical operations that should appear atomic to the rest of the code.
As he mentions in his PyCon 2013 keynote, there are other Python async frameworks like Gevent, which are async by default, and he doesn't like that approach. (at 11:58):
And unfortunately you're still not completely clear of the problem that the scheduler could at a random moment interrupt your task and switch to a different one. [...] Any function that you call today that you happen to know that it never switches, tomorrow someone could add a logging statement or a lazy caching or a consulting of a settings file. [...]