[Twisted-Python] t.i.task.Cooperator & inlineCallbacks mashup

I only just noticed today that if a generator passed to a CooperativeTask does: result = yield some_deferred() ...it doesn't work, because CooperativeTask doesn't .send() the result of the deferred bacn into the generator. Is this intentional? If not, would that behaviour be desirable? It seems like it would be a useful pattern to me.

On 02/11/11 12:39, Itamar Turner-Trauring wrote:
I meant this: from twisted.internet import task, reactor, defer def dowork(n): d = defer.Deferred() result = 'waited %i' % (n,) reactor.callLater(n, d.callback, result) return d def work(): for i in (1,2,3): rv = yield dowork(i) print rv task.coiterate(work()) reactor.run() ...prints: None None None rather than waited 1 waited 2 waited 3 i.e. the iterator that is yielding deferreds doesn't "see" the results emerge from the "yield" in the same way inlineCallbacks do. Obviously it's pretty trivial to get at the results: holder = {} def cb(r): holder['result'] = r return r yield dowork(i).addCallback(cb) print holder['result'] But the essential point I was missing is that Cooperator is for general purpose iterators, not just generators.

On 11:24 am, p.mayers@imperial.ac.uk wrote:
Yes. Cooperator is for iterators, not generators, making send unusable in the general case. Cooperator also isn't a replacement for inlineCallbacks. You can build a wrapper for a generator that works together with Cooperator and sends results back in. If it ends up being useful, it might be something to add to Twisted. Jean-Paul

On 02/11/11 12:39, Itamar Turner-Trauring wrote:
I meant this: from twisted.internet import task, reactor, defer def dowork(n): d = defer.Deferred() result = 'waited %i' % (n,) reactor.callLater(n, d.callback, result) return d def work(): for i in (1,2,3): rv = yield dowork(i) print rv task.coiterate(work()) reactor.run() ...prints: None None None rather than waited 1 waited 2 waited 3 i.e. the iterator that is yielding deferreds doesn't "see" the results emerge from the "yield" in the same way inlineCallbacks do. Obviously it's pretty trivial to get at the results: holder = {} def cb(r): holder['result'] = r return r yield dowork(i).addCallback(cb) print holder['result'] But the essential point I was missing is that Cooperator is for general purpose iterators, not just generators.

On 11:24 am, p.mayers@imperial.ac.uk wrote:
Yes. Cooperator is for iterators, not generators, making send unusable in the general case. Cooperator also isn't a replacement for inlineCallbacks. You can build a wrapper for a generator that works together with Cooperator and sends results back in. If it ends up being useful, it might be something to add to Twisted. Jean-Paul
participants (3)
-
exarkun@twistedmatrix.com
-
Itamar Turner-Trauring
-
Phil Mayers