[Twisted-Python] Twisted and ipython

Glyph Lefkowitz glyph at twistedmatrix.com
Mon Jan 17 00:07:42 EST 2011

On Jan 16, 2011, at 6:12 PM, Alessandro Dentella wrote:

> thanks Jean-Paul for the hints,
> On Sun, Jan 16, 2011 at 12:50:05AM -0000, exarkun at twistedmatrix.com wrote:
>> On 13 Jan, 11:43 pm, sandro at e-den.it wrote:
>>> thanks,
>>> short abstact: manhole is very good, thanks. But I'd need to add 
>>> readline to
>>> make it usable and I'd need tab-completion too.
>> If by "add readline" you mean handle input using the stdlib readline 
>> module, you can't really do this (or, I'm sure you can, but it would 
>> involve a ton of coding).  If you only mean "have some commonly useful 
>> line editing features" then you have at least a couple options:
> Well, in fact I intended mainly up/down arrows *and* tab-completion, like
> ipython have. 
>>  * invective includes a fully unit-tested line input widget (for the 
>> insults widget library).  This really belongs somewhere other than 
>> invective, it'd be nice if someone pushed it back into Twisted. 
>> However, you can find invective at 
>> svn://svn.twistedmatrix.com/svn/Twisted/sandbox/exarkun/invective/trunk 
>> until that happens.
>>  * urwid supports Twisted and has lots of fancy things, including an 
>> input editing widget.
> From what you say I don't know if completion is something I'd
> get with invective of urwid.

Invective is an IRC client (with a useful text-editing widget for Twisted's "insults" module).  urwid is a client library.  Completion is something that you'd need to implement yourself with either of these (as is a functional Python interpreter...)

>> Also, we really should get rid of twisted.manhole, because these days 
>> manhole is supposed to refer to the stuff in twisted.conch.  I'm not 
>> sure if you found the latter, but from the warning you got about 
>> twisted.protocols.telnet it seems like you may have only found the 
>> former.
> I was able to use only manhole.telnet. I wan't able to understand how to
> make twisted.protocols.telnet work in the same way and was not able to fine
> a demo snippet (more for completeness that else I'm still interested in
> this).

twisted.protocols.telnet is old and really should not be used.  The new, good telnet implementation is in twisted.conch.telnet.  You can find code that uses this (both a runnable application and an instructive example) in twisted.conch.manhole_tap, which also happens to include a python interpreter as its application.

> On the other hand I managed to use ipython and twisted as I wanted and
> everitying is working like a charm (but I still have a question that I'll
> leave for next chapter).
> Twisted in a thread - working setup
> -----------------------------------
> Following a hint in the ipython ml I started a second thread for twisted and
> I'm using blockingcallFromThread to dispatch commands to the reactor:

You can do this in pretty much any interactive Python interpreter, including the default one.  It's not very convenient, though :).

> What I can't understand is why I can't put "q.discover_modules()" inside
> callWhenRunning() command: if I do that it just blocks at the first
> iteration of the 'for' loop.

Because callWhenRunning will schedule start_command to be run on the main (reactor) thread.  (callWhenRunning may only be called _from_ the main thread, too, which it seems like you might not be doing).

Since start_command is running on the main thread, when it gets around to blockingCallFromThread, it puts some work into the queue for the reactor to do, then goes to sleep forever, trusting that the main thread will do the work and then wake it up.  Except - oops! - it just put the main thread to sleep forever, so it will never wake up.

If you'd like, you can file a ticket for blockingCallFromThread to raise a loud, angry exception if it is invoked from the reactor thread.

(Also, in the simple example you gave, you're invoking blockingCallFromThread with the wrong signature; the first argument must be a reactor.  The rest of my explanation was based on the assumption that this is not the exact code you're running, since that would log a traceback immediately.  Or, perhaps the fact that you're calling callWhenRunning from a non-main thread is blowing up in some more insidious way and that's the real problem.)

Hope this helps,


More information about the Twisted-Python mailing list