Hi. I didn't commit this, as it's a bit of a conceptual change. Please give feedback. Patch is at the end. This change allows web.widgets to call defer.Deferred's callback() with a list instead of a string, making it possible to stream a web page to the browser by returning a string and then a Deferred object. Here's a snippet of a web UI I'm doing that streams LDAP search results to the browser as soon as the server sends them -- see handle_entry(): class LDAPSearchAndPrint(ldap.LDAPSearch): def __init__(self, ldapclient, callback, filter=pureldap.LDAPFilterMatchAll): ldap.LDAPSearch.__init__(self, ldapclient, baseObject='dc=example, dc=com', filter=filter, ) self.result="" self.callback=callback self.count=0 def handle_success(self): self.callback(["<p>%d entries matched."%self.count]) def handle_entry(self, objectName, attributes): result="<p>%s\n<ul>\n"%objectName for a,l in attributes: assert len(l)>0 if len(l)==1: result=result+" <li>%s: %s\n"%(a, l[0]) else: result=result+" <li>%s:\n <ul>\n"%a for i in l: result=result+" <li>%s\n"%i result=result+" </ul>\n" result=result+"</ul>\n" c=self.callback d=defer.Deferred() self.callback=d.callback c([result, d]) self.count=self.count+1 def handle_fail(self, resultCode, errorMessage): self.callback("fail: %d: %s"%(resultCode, errorMessage or "Unknown error")) --- twisted/web/widgets.py 2001/09/10 17:13:24 1.8 +++ twisted/web/widgets.py 2001/09/10 17:18:37 @@ -283,12 +283,17 @@ def callback(self, result, position, decNeedsHeaders): if result != FORGET_IT: self.needsHeaders = self.needsHeaders - decNeedsHeaders - if isinstance(result, defer.Deferred): - self._addDeferred(result, position) - self.lst[position] = result + if not isinstance(result, types.ListType): + result=[result] + for i in xrange(len(result)): + if isinstance(result[i], defer.Deferred): + self._addDeferred(result[i], position+i) + self.lst[position:position+1] = result + assert self.position <= position self.keepRendering() - if isinstance(result, defer.Deferred): - result.arm() + for r in result: + if isinstance(r, defer.Deferred): + r.arm() def keepRendering(self): -- tv@{{hq.yok.utu,havoc,gaeshido}.fi,{debian,wanderer}.org,stonesoft.com} double a,b=4,c;main(){for(;++a<2e6;c-=(b=-b)/a++);printf("%f\n",c);}