[Twisted-Python] Simpler Twisted deferred code via decorated callbacks

Terry Jones terry at jon.es
Mon Oct 15 12:54:04 MDT 2012


Hi Naveen

> This is a really nice approach.

I'm glad you like it. I've learned over the years to avoid decorators, but
I nevertheless think these ones are promising.

> Are there any downsides or functionality that can't be accomplished using
> this approach?

The main thing that's a little different is that it doesn't (yet) help with
situations where you might want finer-grained control over callbacks and
errbacks, or to use addBoth. I didn't want to tackle everything at once.
Because the approach is all just normal deferreds, there was no need to.

I wasn't sure what to do about addBoth - add a new decorator for it, let
people use both decorators, etc.  You can still just do this:

    def both(result):
        # do something

    @callback
    def first(result):
        # do something

    @callback
    def second(result):
        # do something

    second(first(getPage('http://www.something.com')).addBoth(both)

The regular non-decorated Twisted code would be:

    def both(result):
        # do something

    def first(result):
        # do something

    def second(result):
        # do something

    getPage('http://www.something.com').addCallback(first)
        .addBoth(both).addCallback(second)


As another example, in regular Twisted code you might want to do this:

    d = getDeferred()
    d.addCallback(f1)
    d.addCallbacks(f2, e1)

Many people don't understand that that's not the same as

    d = getDeferred()
    d.addCallback(f1)
    d.addCallback(f2)
    d.addErrback(e1)

The decorator approach doesn't provide directly for the former. You get the
latter of course by writing e1(f2(f1(getDeferred))).  You could have the
former via f1(getDeferred).addCallbacks(f2, e1) in which case the
decorators aren't buying you much.

So I think there's some way to go on that front, but I've not yet thought
about what would be most elegant/simple etc.  Given a nice way to do
addCallbacks, it can be used to implement addBoth (as in defer.py), so
these two examples are really just the same thing.

Glyph suggested I post with a simple example explaining exactly what the
decorators are doing. I plan do that.

Terry




More information about the Twisted-Python mailing list