watch this The wheels are turning, slowly turning. home
Python Developers Considered Harmful 2004-08-02

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.