[Twisted-Python] Oddity(?) with zero-length Deferred lists

Jean-Paul Calderone exarkun at divmod.com
Fri May 9 15:46:53 EDT 2008


On Fri, 09 May 2008 14:33:19 -0500, Gregg Lind <gregg at renesys.com> wrote:
>Good afternoon!
>
>I notice an oddity with zero-length DeferredLists.
>
>The example script (http://dpaste.com/49099/) should just return the 
>contents of a bunch of URLs given at the command line, or some errors like 
>so:
>
>$ python test.py a b c
>[(False, <twisted.python.failure.Failure twisted.web.error.Error>), (False, 
><twisted.python.failure.Failure twisted.web.error.Error>), (False, 
><twisted.python.failure.Failure twisted.web.error.Error>)]
>
>*but*
>
>$ python test.py     # no arguments
>[]
># then hangs, never reaching "quit"
>

You can do this in a simpler way without involving DeferredList:

    >>> from twisted.internet.defer import succeed
    >>> from twisted.internet import reactor
    >>> d = succeed(None)
    >>> d.addCallback(lambda ign: reactor.stop())
    <Deferred at 0xB7D1F12CL  current result: <twisted.python.failure.Failure twisted.internet.error.ReactorNotRunning>>
    >>> reactor.run()
    <hang>

As you can see from this example, the Deferred already has a result (a
Failure) by the time reactor.run() is called.  Adding a callback to a
Deferred which already has a result (such as succeed(None) or
DeferredList([])) calls the callback immediately.  So your sample program
is trying to stop the reactor before it starts.  Then nothing tries to
stop the reactor after you actually do start it.  If you add an errback
to your Deferred, you'll see the problem reported.  One solution to this
is to use reactor.callWhenRunning(reactor.stop) instead of reactor.stop().

Jean-Paul




More information about the Twisted-Python mailing list