[Twisted-Python] modal wxPython, Twisted, xml-rpc; example code

Andrew Dalke dalke at dalkescientific.com
Tue Jun 3 21:43:57 EDT 2003

> I've attached some example code which shows how to use
> a modal wxPython dialog and Twisted to produce a responsive
> GUI which uses XML-RPC to query a remote XML-RPC service to
> get a US state name given it's position in a sorted list.
> I've also contributed this as an ActiveState recipe.

However, it fails for some cases of a modal in a modal.

I have a set of error cases in the code, which looks like this (except
the last one, which I added today).

         if TEST_ERRORS:
             i = self.i
             if i == 3:
                 proxy = Proxy("http://illegal-host_name/")
             elif i == 6:
                 proxy = Proxy("http://beatty.userland.com/")
             elif i == 8:
                 proxy = 
             elif i == 9:
                 proxy = Proxy("http://beatty.userland.com:9876/")

The last one cases an error during making the connection, and so I get
a "unable to connect to remote host" message.  Now, I want to show that 
in another modal, which doesn't use Twisted, so I just opened the modal 

This starts up the wxPython event loop again, which triggers another 
event, which calls back to the Twisted reactor to run another iteration.

It appears that my defered is still active, because I then get an 
Here's the full stack trace.

Traceback (most recent call last):
   File "Progress.py", line 158, in Bad
     try_again = task.bad(fail)
   File "Progress.py", line 52, in bad
   File "Progress.py", line 208, in OnTimer
   File "E:\Python22\Lib\site-packages\twisted\internet\default.py", 
line 473, in
     _logrun(selectable, _drdw, selectable, method, dict)
--- <exception caught here> ---
   File "E:\Python22\Lib\site-packages\twisted\python\log.py", line 64, 
in callWithLogger
     callWithContext({"system": lp}, func, *args, **kw)
   File "E:\Python22\Lib\site-packages\twisted\python\log.py", line 51, 
in callWithContext
     return context.call({ILogContext: newCtx}, func, *args, **kw)
   File "E:\Python22\Lib\site-packages\twisted\python\context.py", line 
32, in callWithContext
     return func(*args,**kw)
   File "E:\Python22\Lib\site-packages\twisted\internet\default.py", 
line 498, in _doReadOrWrite
   File "E:\Python22\Lib\site-packages\twisted\internet\tcp.py", line 
396, in connectionLost
   File "E:\Python22\Lib\site-packages\twisted\internet\tcp.py", line 
315, in failIfNotConnected
   File "E:\Python22\Lib\site-packages\twisted\internet\base.py", line 
527, in connectionFailed
     self.factory.clientConnectionFailed(self, reason)
   File "E:\Python22\Lib\site-packages\twisted\web\xmlrpc.py", line 209, 
in clientConnectionLost
   File "E:\Python22\lib\site-packages\twisted\internet\defer.py", line 
215, in errback
     self._startRunCallbacks(fail, 1)
   File "E:\Python22\lib\site-packages\twisted\internet\defer.py", line 
244, in _startRunCallbacks
     raise AlreadyCalledError()

I can't figure out what's going on.  The code I could find for the 
reactor is very
careful to take defereds off the pending list before calling, so 
there's no way to
call them twice.

There's a clue in that only the last of these trigger this error 
condition.  This
suggests something with how the connection is established, and not 
after it's
put into place.  What I think is happening is that that
twisted.internet.base.BaseConnector allows the factory to reattempt the 
when the intial connection failed, and there isn't a guard in case the 
gets called again.

I still haven't grokked how the deep part of Twisted works - tried for 
the last
while to track this bug further - so I'll leave it up to you all.

In the meanwhile, since I don't need Twisted in the new (sub)modal, my 
is to do

     def OnTimer(self, event):
         if self.recursive:
         self.recursive = 1
             self.recursive = 0

					dalke at dalkescientific.com

More information about the Twisted-Python mailing list