Corotwine 0.2

As is my tradition, I'm doing extremely rapid releases of my software.

Here's Corotwine 0.2, which contains the following changes:

  • Returning from a connection-handling function now closes the connection
  • A bug was fixed in the example Chat server

The API documentation has been updated.

Please post any feedback.

Corotwine 0.1

I've just released Corotwine, a set of Coroutine APIs for Twisted. You can download Corotwine-0.1.tar.gz. There is very thorough API documentation.

Here's a complete example chat server. Start it up and telnet to port 1025 a couple of times and you'll be able to chat.


from twisted.internet import reactor
from twisted.internet.error import ConnectionClosed
from corotwine.protocol import gListenTCP, LineBuffer


class Chat(object):
def __init__(self):
self.clients = []

def handleConnection(self, transport):
transport = LineBuffer(transport)
self.clients.append(transport)
try:
try:
for line in transport:
for client in self.clients:
if client is not transport:
client.writeLine(line)
finally:
self.clients.remove(transport)
except ConnectionClosed:
return

from twisted.python.log import startLogging
import sys
startLogging(sys.stdout)

gListenTCP(1025, Chat().handleConnection)

reactor.run()

There are more examples in the corotwine/examples.py file.

Twisted 8.0.1 is out

Hey all. The release of Twisted 8.0 is finally done, and I was so excited about it that I just had to do another one: 8.0.1. The release announcement has been posted to the TM Labs blog.

Download and enjoy.

Twisted Isn't Specific

I was googling for some stuff related to Twisted and greenlet and I came across this post from last year by Jean-Paul Calderone: Twisted Isn't Specific. That subject is a reference to a quote in the Twisted.Quotes file:

<sayke> Acapnotic: don't make it twisted-specific
<dash> sayke: pffft
<dash> sayke: twisted isn't specific

The post is kind of relevant to some poking around I've been doing with integrating greenlet and Twisted again, but that's not really why I wanted to point it out on my blog. I just had a really good time reading it again. I think it's really well-written, and is fairly quotable. Just to warn you: this is one of those "quote posts" that contain more quotations than commentary, often perpetrated by ineffectual bloggers with nothing original to say. I'm sorry.

The email that Jean-Paul is responding to is by Andrew Dalke, and is about how he wants to magically replace the built-in Python socket module with something that switches to an event loop and allows other application code to run at the same time. This isn't terribly reliable, of course, and Jean-Paul gives a nice explanation of the dangers of implicit context switching (which applies to pre-emptive threading just as well as the controlled but still implicit switching of stackless or greenlet).
Consider this extremely trivial example:
  x = 0
def foo(conn):
global x
a = x + 1
b = ord(conn.recv(1))
x = a + b
return x
Clearly, foo is not threadsafe. Global mutable state is a terrible, terrible thing. The point to note is that by introducing a context switch at the conn.recv(1) call, the same effect is achieved as by any other context switch: it becomes possible for foo to return an inconsistent result or otherwise corrupt its own state if another piece of code violates its assumptions and changes x while it is waiting for the recv call to complete.
Asyncore was also brought up. It's often compared to Twisted, since in the past it was the only prevalent event system for Python. Twisted has pretty much obsoleted it by now, or so I like to think:
2) asyncore is smaller and easier to understand than Twisted, [-- Dalke]

While I hear this a lot, applications written with Twisted _are_ shorter and contain less irrelevant noise in the form of boilerplate than the equivalent asyncore programs. This may not mean that Twisted programs are easier to understand, but it is at least an objectively measurable metric.

Andrew goes on to talk about how great it would be if we could just use the existing built-in Python libraries for NNTP and POP3. That was pretty amusing, because those were some of the first protocol implementations (client and server) that Jean-Paul did for Twisted. And you know what? He had a reason for doing them with Twisted, instead of using the standard library versions:
Yet by using the Stackless socket monkeypatch, this same code works in an async framework. And the underlying libraries have a much larger developer base than Twisted. Want NNTP? "import nntplib" Want POP3? "import poplib" Plenty of documentation about them too. [-- Dalke]

This is going to come out pretty harshly, for which I can only apologize in advance, but it bears mention. The quality of protocol implementations in the standard library is bad. As in "not good". Twisted's NNTP support is better (even if I do say so myself - despite only having been working on by myself, when I knew almost nothing about Twisted, and having essentially never been touched since). Twisted's POP3 support is fantastically awesome. Next to imaplib, twisted.mail.imap4 is a sparkling diamond. And each of these implements the server end of the protocol as well: you won't find that in the standard library for almost any protocol.

He went on to compare the Twisted POP3 client documentation to the Python poplib. Neither were very good.

Jean-Paul even had a nice bit of wisdom about our culture as programmers in general:
I feel that using the phrase "just a" in the previously quoted text is an understatement. [-- Dalke]

I think you're right. We throw around "just" a lot in our line of work, don't we? :) Twisted does also account for a raft of platform-specific quirks and inconsistencies. I take this to be a good thing.

And what a classy closing.
I apologize for writing such a long message, but I didn't have time to write a shorter one.

pyOpenSSL 0.7a1

Jean-Paul Calderone has recently taken over maintenance of the pyOpenSSL project. He's doing development with bzr on launchpad.net/pyopenssl, but still maintaining the web site and downloads at pyopenssl.sf.net.

He's already fixed a bunch of bugs, like segfaults and things. There was a cool Open Space meeting at PyCon where he asked the community what kind of stuff they'd like to see in the bindings. I think he has plans for extending them a bit to make them more useful specifically for Twisted, but he's also very receptive to the community's patches and bug reports -- I think he's closed several bugs and patches since becoming maintainer.

Anyway, please go check out the new release - it's less buggy!

Another Twisted 8 pre-release

I just put out Twisted 8.0.0 pre-release 2 (that link is temporary and will definitely not last past the release of Twisted 8). The changes are in the NEWS file.

It comes with newly improved Windows IOCP support as well as support for easy_install. You can easy_install the main Twisted-8.0.0pre2.tar.bz2, but not the subprojects. When the final 8.0 release is out I'll register it on PyPI so that you can just type "easy_install Twisted" to get it.

Please check out this pre-release and report bugs.

PyCon 2k8

I'm not sure what to say. I was really happy to be at PyCon. It was bigger than ever. I only attended one talk, other than a couple of keynotes. The most important Keynote, of course, was the announcement of Twisted's membership in the Software Freedom Conservancy. You can now give Twisted tax-deductible money. Please donate!

I also released Twisted 8.0 prerelease 1. Please download it and check it out. I hope to have a second prerelease soon, which will include a much improved IOCP reactor and easy_install support.

Amazon MP3 Store now supports Ubuntu

So, I noticed that Nine Inch Nails released their new album, Ghosts. The official web site that sells FLACs was slashdotted at the time but I noticed that they were also selling the album on Amazon MP3. Clicking around randomly for a while I noticed that they finally released their downloader software for Linux, including packages for Ubuntu. I think previously it was impossible (or at least hard) to buy and download entire albums without this downloader, so this is basically the first time that Linux users can use Amazon's MP3 service.

I had a problem with it, though: when I downloaded one of the .amz files to run with the downloader app, the application failed to do anything but display a blank download window. Long story short: it refuses to open files that it doesn't have write permission to. I guess firefox 3 or Hardy saves downloaded files as mode 400. Amazon downloader fails to report any error, unfortunately, so the only way I figured this out was by stracing it. Just chmod u+w foo.azw and then the downloader will happily work. I've reported the bug to Amazon support, hopefully there will be a fix soon before they start losing loads of customers who waste their money on something they can't download.

Other than this technical glitch I'm very happy with Amazon's MP3 service so far. It's great that there's actually a high-profile DRM-free music service. I just wish they would do the same thing with their eBooks.