LWN.net Logo

A proposal for "rebooted" Python asynchronous I/O support

A proposal for "rebooted" Python asynchronous I/O support

Posted Dec 29, 2012 11:38 UTC (Sat) by cglass (subscriber, #52152)
Parent article: A proposal for "rebooted" Python asynchronous I/O support

I'll go ahead and ask the obvious question here, apologies if this seems obvious to people more familiar with the topic at hand:
Why not twisted? Why reimplement the same functionality with a slightly different interface?
It certainly isn't perfect, but I would be interested in understanding the reasons.


(Log in to post comments)

A proposal for "rebooted" Python asynchronous I/O support

Posted Dec 29, 2012 13:30 UTC (Sat) by marduk (subscriber, #3831) [Link]

I didn't read the entire PEP but it seems that Twisted, ZeroMQ and Tornado were thought of and can easily implement the interface for the PEP. It seems that one of the goals is to have a a common interface (think wsgi or the db-api) while a second goal is to have a reference implementation included in the standard library.

A proposal for "rebooted" Python asynchronous I/O support

Posted Dec 29, 2012 14:32 UTC (Sat) by njs (guest, #40338) [Link]

Twisted is seriously awesome. But I would be very surprised to see it end up in the standard library. Just to start with, twisted as a whole is a huge sprawling mess of variable quality code, so you'd have to extract some small pieces (just the reactor interface?), and even those interfaces probably have stuff in them that you'd want to clean up given how many years its been since they were first designed. And twisted relies heavily on zope-style interfaces, which have been rejected from the stdlib before. And twisted is still a long way from running on Python 3.

A proposal for "rebooted" Python asynchronous I/O support

Posted Dec 29, 2012 16:26 UTC (Sat) by tack (subscriber, #12542) [Link]

With a model like Twisted's, you have a twisty little maze of callbacks.

So one of the primary drivers of this PEP is coroutines, which let us solve the callback hell problem seen in languages like Javascript (especially with node.js). To standardize on coroutines used for async IO, you also need to standardize a bunch of other things like a Future-like object and a minimal event loop.

Once these things are defined and codified, libraries like Twisted and Kaa can conform to them, and this just might, if we play our cards right, pave the way for async library interoperability in Python land. Today each library takes a different and incompatible approach.

Also Twisted's API is not PEP8 compliant. :)

A proposal for "rebooted" Python asynchronous I/O support

Posted Dec 30, 2012 3:35 UTC (Sun) by wahern (subscriber, #37304) [Link]

From the PEP Guido says they're basically just generators underneath, which means these aren't like more modern coroutine implementations which can yield from sub-subroutine invocations. Being restricted to the first-level invocation will hardly remove the necessity for callbacks in high-level application code, unfortunately.

This is why I much prefer Lua. It might not have the huge library, but at least the VM is done right.

A proposal for "rebooted" Python asynchronous I/O support

Posted Dec 30, 2012 4:36 UTC (Sun) by tack (subscriber, #12542) [Link]

You've misunderstood the PEP. Coroutines are implemented using generators, yes, but they can be arbitrarily nested (within runtime stack depth limits of course). In other words, coroutine A can "yield from" coroutine B which can "yield from" coroutine C and so on. If C yields a Future object, the stack unravels -- through B and A -- and the coroutine scheduler will resume C's execution when the Future it yielded is done.

A proposal for "rebooted" Python asynchronous I/O support

Posted Dec 31, 2012 23:47 UTC (Mon) by wahern (subscriber, #37304) [Link]

I think you misunderstood what I was saying. To understand the fundamental problem in the CPython (and Jython) VM, just think about the difference between CPython and Stackless. You can't `yield from' inside a new function invocation because of the way call frames are implemented in CPython. Only the callee of a `yield from' statement can yield. But you can explicitly stack yield froms in a call chain. Kinda messy, but it's a fundamental limitation of CPython.

Coroutines in languages like Lua are implemented more like threads, so coroutine semantics aren't limited to a single callee invocation. In Lua, invocation C in A->B->C can yield, even though coroutine resumption began in A. In CPython, when resuming A only A can yield. A can, however, _explicitly_ invoke B as a coroutine. But B (perhaps a library call) can't hide the details. A needs to adorn it's call to B in order to get coroutine semantics. Again, not so in Lua or some other languages.

A proposal for "rebooted" Python asynchronous I/O support

Posted Jan 1, 2013 0:10 UTC (Tue) by wahern (subscriber, #37304) [Link]

FWIW, I believe Python coroutines will work much like Javascript generator trampolines: http://www.neilmix.com/2007/02/07/threading-in-javascript...

Copyright © 2013, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds