Sunday, August 29, 2004

How I Spent My Summer Vacation

My two weeks off from work have come to an end. I didn't go anywhere, as I like to do on my vacations, due to various (uninteresting) concerns (which I will not relate here). I did do a bit of programming for fun, though.



  • Improved telnet implementation for Twisted

    Twisted has had a telnet protocol implementation forever. It is pretty lame, though. It makes you format outgoing IAC and such yourself, it doesn't handle \r\0 properly, it's got all kinds of abstraction leaks, and it has no unit tests. So I wrote a new one. And tests for it. Actually I wrote the tests, then the protocol. Hooray test driven development. The new code is still in my sandbox until the backwards compatibility issues get worked out.


  • A VT102 protocol implementation

    This provides a moderately high-level API for manipulating a vt102-compatible terminal. For example, the cursor can be positioned, scroll regions can be defined, the character set can be changed, etc. Together with the improved telnet implementation, this gives a server a convenient way to manipulate the display of a dumb client.


  • Twisted Manhole replacement

    Twisted has had a subpackage named "manhole" for a long time. A manhole in a Twisted application gives you an interactive Python prompt inside that application, as it runs. The state of the program can be inspected and modified using arbitrary Python code. This is quite powerful, and worked pretty well. One could connect to it via PB using the Gtk client, or via telnet. Unfortunately, the Gtk client is not conducive to shared debugging, and the telnet version was uncomfortable to use, since it lacked line editing features. Using the improved telnet implementation and the vt102 protocol, I wrote a replacement for the telnet part of this that supports line editing, line history, and syntax coloring. All using just a telnet client. It can also be hooked up to stdin, making a reactor-friendly readline-replacement. Since Twisted includes an SSH server, this can all be hooked up to that, too.


  • Gravitation Simulation

    I've been trying to write a particular game for a number of years now. It involves some amount of space travel, so of course I need a way to model bodies moving through space with some accuracy. This involves handling gravitational effects. I've written n-body gravitation simulations before, but they were all in crummy languages I'd rather not use any more, or dead slow. This time, I used the opportunity to learn a few things about Numarray, and implemented the simulation with no Python loops. It's probably still not fast enough to use, but it's a lot closer than any of my other Python attempts. (Also it's just a dumb geometric solution instead of a smart integral solution, oh well).


  • Python Oct Tree

    A simple little octree implementation. radix has been fiddling with 3d graphics lately. He wanted an octree to speed up visibility culling. So I wrote one. It was fun struggling to remember high school geometry. Since I'd just finished playing with numarray, I threw in some uses of it here, too. One thing that was frustrating was that I couldn't find a cross product function in numarray. I know I must be missing something. How could there not be a cross product function?


Friday, August 20, 2004

Things I didn't know Python could do


>>> class x:
... y = 0
...
>>> for x.y in range(5):
... print x.y,
...
0 1 2 3 4
>>>
>>> x = [None]
>>> for x[0] in range(5):
... print x,
...
[0] [1] [2] [3] [4]
>>>

Monday, August 2, 2004

Python Developers Considered Harmful

This morning I learned that the '@decorator' patch had been applied and would be distributed as part of Python 2.4a2. I fumed and wasted a good couple hours going back and forth about it with the denizens of #twisted. We go nowhere, except frustrated, disappointed, and disillusioned (You thought we were jaded before? You ain't seen nothing yet). Afterwards I went and tried to catch up on all the python-dev discussion of the feature. Not much to be found. Where was '@decorator' discussed? I see one post that mentions it offhand, and no followup. Numerous developers I spoke with felt the same way. So I stewed about it all day.

I took out the trash and went for a run at about 11pm tonight. When I got back I sat down and wrote this.

http://divmod.org/users/exarkun/decorate.py

In brief, it defines a function "decorate" and a metaclass "DecoratableType" which may be used in this manner:


class Demo(object):
__metaclass__ = DecoratableType

decorate(staticmethod)
def foo(x, y):
print 'Static method foo called with', x, y


This closely parallels the '@decorator' syntax, but requires no changes to the interpreter.

What are its advantages over the '@decorator' syntax?

1) It's pure-python.

2) It requires no syntax changes.

3) It works in Python 2.2, 2.3, and yes, 2.4a1, three times as many Python versions as will support the new syntax (once 2.4 is actually released ;).

4) It supports arbitrary expressions to specify decorators (The '@' patch only supports "dotted names". For example, "@foo" and "@foo.bar(baz)" will work, but "@foo or bar" will not)

What are its disadantages (and there sure are some)

1) It depends on source line numbers. It's possible that this information could be unavailable in certain environments (I can't think of any, but I'm sure there are some). The posted version also will not deal with intervening whitespace, comments, or decorate() calls well. This can be fixed without very much difficulty.

2) The posted version only works for classes that use the defined metaclass. It would be possible to remove this restriction, but only by hooking into some other mechanism for performing additional processing to the objects involved. This could be in the form of an import hook or a function which is manually invoked.

Hardly anyone generally comments on my blog posts. I hope that everyone who reads this and thinks a solution along the lines of the one described here will comment and let me know, and everyone who thinks the '@decorator' proposal is better will comment and tell me why I'm wrong.