On 5 May 2015 at 23:28, Guido van Rossum
At this point, *all* I'm thinking of is a toy. So, an implementation somewhat parallel to asyncio, but where the event loop just passes control to the next task - so no IO multiplexing. Essentially Greg Ewing's example up to, but not including, "Waiting for External Events". And ideally I'd like to think that "Waiting for Resources" can be omitted in favour of reusing https://docs.python.org/3/library/asyncio-sync.html and https://docs.python.org/3/library/asyncio-queue.html. My fear is, however, that those parts of asyncio aren't reusable for other event loops, and every event loop implementation has to reinvent those wheels.
It was never a goal of asyncio to have parts that were directly reusable by other event loops without pulling in (almost) all of asyncio. The interoperability offered by asyncio allows other event loops to implement the same low-level interface as asyncio, or to build on top of asyncio. (This is why the event loop uses callbacks and isn't coroutines/generators all the way down.) Note that asyncio.get_event_loop() may return a loop implemented by some other framework, and the rest of asyncio will then use that event loop. This is enabled by the EventLoopPolicy interface.
OK, that's an entirely fair comment. It's difficult to tell from the docs - there's nothing obviously io-related about the task abstraction, or the synchronisation or queue primitives. But there's equally no reason to assume that they would work with another implementation. As I mentioned somewhere else, maybe refactoring the bits of asyncio that can be reused into an asynclib module would be useful. But based on what you said, there's no reason to assume that would be an easy job. And without another event loop implementation, it's not obvious that there's a justification for doing so.
What do you hope to learn or teach by creating this toy example? And how do you define "a complete event loop"?
Well, one thing I hope to learn, I guess, is what "a complete event loop" consists of :-) More broadly, I'd like to get a better feel for what methods are fundamental to an event loop. IIRC, we had this discussion way back at the beginning of the asyncio development when I was unclear about why create_connection had to be an event loop method. In the asyncio context, it has to be because the event loop needs to know when connections get created (excuse me probably misremembering the exact reason from back then). But conversely, it's easy to imagine an event loop unrelated to socket IO that doesn't have a create_connection method. On the other hand, an event loop with no call_soon method seems unlikely. So in essence I'm thinking about what a "sensible minimum" event loop might be. An event loop ABC, if you like. And following on from there, what useful abstractions (tasks, synchronisation and queue primitives) can be built on top of such a minimal interface. Basically, that's what I'm hoping to learn - what is fundamental (or at least generally applicable) and what is related to the purpose of a given implementation. I've probably got enough from this discussion to try writing up some code and see where it leads me. Paul PS You mentioned that a the callback-based nature of the asyncio event loop is to simplify interoperability with callback-based frameworks like Twisted. I guess the above ignores the possibility of event loops that *aren't* callback-based. Or maybe it doesn't - that's possibly another class of methods (callback-focused ones) that maybe can be separated into their own ABC.