Search code examples
pythontwisted

Callback chain with independent data, not related to the chain


I am trying to perform a simple callback sequence in twisted. The idea is that I login to a service, and when the login has succeeded, I start sending commands. This is my code:

from   twisted.internet          import reactor, defer

class MyService:

    def __init__ (self):
        self.handle = None

    def login(self):
        def onConnect(handle):
            self.handle = handle
            return
        df = defer.Deferred().addCallback(onConnect)
        reactor.callLater(2, df.callback, "dummyhandle")
        return df

    def sendCommand(self, command):
        def onResult(result):
            print result
            return result

        if self.handle == None:
            print "Not logged in"
            return
        else:
            df = defer.Deferred().addCallback(onResult, result ="xxx")
        return df

my = MyService ()

my.login().addCallback(my.sendCommand, command = "format")
reactor.run()

Running that code produces the following stacktrace:

Unhandled error in Deferred: Traceback (most recent call last):   File "/usr/lib/python2.6/dist-packages/twisted/internet/base.py", line 1179, in mainLoop
    self.runUntilCurrent()   File "/usr/lib/python2.6/dist-packages/twisted/internet/base.py", line 778, in runUntilCurrent
    call.func(*call.args, **call.kw)   File "/usr/lib/python2.6/dist-packages/twisted/internet/defer.py", line 280, in callback
    self._startRunCallbacks(result)   File "/usr/lib/python2.6/dist-packages/twisted/internet/defer.py", line 354, in _startRunCallbacks
    self._runCallbacks()
--- <exception caught here> ---   File "/usr/lib/python2.6/dist-packages/twisted/internet/defer.py", line 371, in _runCallbacks
    self.result = callback(self.result, *args, **kw) exceptions.TypeError: sendCommand() got multiple values for keyword argument 'command'

The important thing here is that sendCommand does not need the result of the login, but different data. It needs that login has completed (that is why I want it in the callback chain), but it is not interested on the result of the login (as long as it is not an error, which will be handled in the error chain anyway).

What am I doing wrong here?


Solution

  • Easy, the handler must have result as its first argument:

    def sendCommand(self, in_result, command):
        do_the_stuff