<html><body>On 08:32 pm, ellisonbg.net@gmail.com wrote:<br /><br />>>I am very curious about your 0.00001% case.  Not that I don't believe such<br />>>cases exist, but in every case but one (twisted ticket #2545) the issue has<br />>>actually been a documentation problem with Twisted, where it wasn't clear<br />>>how to do something the "normal" way with Deferreds and such.  I'd like to<br />>>know if there is another such doc bug we should be filing :).<br />><br />>The cases I am thinking about is not an example of a doc bug.  The<br />>most relevant one is related to using Twisted in an interactive python<br />>(really IPython most of the time) session.  There are two difficulties<br />>we keep running into:<br /><br />Hmm.  I hope you're not the guy I talked to at PyCon (I didn't catch his/your name) because I'm about to feel very foolish repeating myself here, especially if at some point in the interim you responded to this and I didn't notice.<br /><br />>1.  The interactive python interpreter is a completely synchronous<br />>universe - getting the reactor running in this context seems like a<br />>hack.  The only way I have seen this done is by running the reactor in<br />>a different thread.  The problem with this is that it is inevitable<br />>that you end up wanting to do things with Deferreds in the main thread<br />>where user code is running.  But, as I understand it, Twisted is not<br />>thread safe, so at that point, you are playing with (threaded) fire.<br /><br />IPython's shell is not the same as the standard Python interpreter.  It's already its own program and therefore has a fair amount of freedom in what it does with user input.<br /><br />Run "python -m twisted/conch/stdio" for an example of an interactive session that is held in a non-blocking way.  Not blocking in the code *doesn't* mean not blocking for the user - it just means having the option not to block.<br /><br />>2.  Users expect certain things in an interactive python session that<br />>don't mesh well with Twisted and the asynchronous universe:<br /><br />This is _exactly_ the documentation issue I was talking about :).<br /><br />>>>>psi = computeWavefunctionForHydrogen()<br />>>>>psi.getEnergy(1)<br />>-13.6<br />># here the user looks at the energy (a human if statement) and decides<br />>if they actually want to<br />># make the following plot.  If the answer were not -13.6, they would<br />>not make the plot.<br />>>>>plot(psi.getState(1))<br />><br />>Even if you could get the reactor running in an interactive python<br />>session it would be crazy to have to write something like (in an<br />>interactive session):<br />>>>>d = computeWavefunctionForHydrogen()<br />>>>>def printAndPlot(psi, n):<br />>>>>     print psi.getEnergy(n)<br />>>>>     if abs(psi.getEnergy(n) - (psi.getEnergy(n)) < 1.0e-4:<br />>>>>         plot(psi.getState(n))<br />>>>>d.addCallback(printAndPlot, 1)<br /><br />Here's a screenshot of an interactive session using the command above:<br /><br />http://twistedmatrix.com/users/glyph/images/content/screenshots/psi-energy.png<br /><br />Unfortunately it doesn't animate, but there is a 1-second pause between "<Deferred #0>" and "Deferred #0 called back:".  It's a bit crude since it is "deferred-oriented" right now, rather than result oriented, but a few clever implementation tricks could easily eliminate the distinction (like the "_.result" line).<br /><br />Is that the kind of user-interaction you want?<br /></body></html>