[Twisted-Python] deferred proposed update
![](https://secure.gravatar.com/avatar/1ea1e7c4b19133819dafe3ac8275406f.jpg?s=120&d=mm&r=g)
Hi, I 'd like to add a pre-processing and post-processing callback in a deferred callback list. I did somthing like this : my_defer = getADeferredForSomething() new_defer = defer.Deferred() new_defer.addCallback(preprocessing) new_defer.chainDeferred(my_defer) new_defer.addCallback(postprocessing) my_defer = new_defer My problem is that postprocessing doesn't receive the result of the last callback in my_defer, but it reveive None. This can be explained in twisted source by that chainDeferred(d) is equivalent to addCallbacks(d.callback, d.errback), but this two methods are not really sort of callback methods for deferred coz they didn't return a result. So I patched Deferred class to add "return self.result", and it works well : Deferred_old = defer.Deferred class Deferred_new(Deferred_old): def callback(self, result): Deferred_old.callback(self, result) return self.result def errback(self, fail=None): Deferred_old.errback(self, fail) return self.result defer.Deferred = Deferred_new Notes by doing this you can also get final result when firing the callbacks : final_result = my_defer.callback(result) I dunno if this patch will fail something else in twisted. fc.
![](https://secure.gravatar.com/avatar/155223fdbc42c65d06b3d6223d8ad1e6.jpg?s=120&d=mm&r=g)
Fabrice Coudert wrote:
You are using Deferreds incorrectly. For example, nothing here makes new_defer ever trigger. You haven't stated clearly what you want to do, but I don't see why you aren't just doing this: d = getADeferredForSomething() d.addCallback(preprocessing) d.addCallback(theRealMcCoy) d.addCallback(postprocessing)
![](https://secure.gravatar.com/avatar/6a0339c6a46d1d6662cebcd79abeabdb.jpg?s=120&d=mm&r=g)
Tommi Virtanen a écrit :
It is a sample code to show inconcistency of chainDeferred, not a real case. Add my_defer.callback(True) after the sample code if you'd like and trace it. You should see that postprocessing() is called with None argument, but not with the result of previous callback as it should be with a normal behaviour of deferred callbacks (read the tutorial)
Same as before, it is a *sample code*. In real case theRealMcCoy (and some more methodes) is added before I need to add a post/preprocessing to that defer. So, I restate the probleme with chainDeferred : chainDeferred(d) is equivalent to addCallbacks(d.callback, d.errback), but this two methods are not really sort of callback methods for deferred coz they didn't return a result. effcy.
![](https://secure.gravatar.com/avatar/56e4cc78ea7fcf3bb37888ebf23bc1f0.jpg?s=120&d=mm&r=g)
On Wed, Jan 28, 2004 at 07:22:40PM +0100, Fabrice Coudert wrote:
Without a use case, there's no chance of the behavior changing. False consistency is the hobgoblin of, etc.
If the code you included in your message isn't equivalent to the code you're using in your actual application, then it's a waste of time to discuss it. If it is equivalent, I don't see why you can't use the code glyph suggested.
If it doesn't do what you want, don't use it. For that matter, even if it does, you can probably avoid using it. As glyph stated, it is a hold-over from times past. If you can share the real use case, maybe someone can help you reformulate it in terms of more recent APIs.
effcy.
Jp
![](https://secure.gravatar.com/avatar/1ea1e7c4b19133819dafe3ac8275406f.jpg?s=120&d=mm&r=g)
Tommi Virtanen a écrit :
It is a sample code to show inconcistency of chainDeferred, not a real case. Add my_defer.callback(True) after the sample code if you'd like and trace it. You should see that postprocessing() is called with None argument, but not with the result of previous callback as it should be with a normal behaviour of deferred callbacks (read the tutorial)
Same as before, it is a *sample code*. In real case theRealMcCoy (and some more methodes) is added before I need to add a post/preprocessing to that defer. So, I restate the probleme with chainDeferred : chainDeferred(d) is equivalent to addCallbacks(d.callback, d.errback), but this two methods are not really sort of callback methods for deferred coz they didn't return a result. effcy.
![](https://secure.gravatar.com/avatar/15fa47f2847592672210af8a25cd1f34.jpg?s=120&d=mm&r=g)
On Jan 29, 2004, at 10:09 AM, Glyph Lefkowitz wrote:
So, the right way to do what he asks is...? Perhaps this? my_defer = getADeferredForSomething() new_defer = defer.Deferred() new_defer.addCallback(preprocessing) new_defer.addCallback(lambda x: return my_defer) new_defer.addCallback(postprocessing) my_defer = new_defer James
![](https://secure.gravatar.com/avatar/155223fdbc42c65d06b3d6223d8ad1e6.jpg?s=120&d=mm&r=g)
Fabrice Coudert wrote:
You are using Deferreds incorrectly. For example, nothing here makes new_defer ever trigger. You haven't stated clearly what you want to do, but I don't see why you aren't just doing this: d = getADeferredForSomething() d.addCallback(preprocessing) d.addCallback(theRealMcCoy) d.addCallback(postprocessing)
![](https://secure.gravatar.com/avatar/6a0339c6a46d1d6662cebcd79abeabdb.jpg?s=120&d=mm&r=g)
Tommi Virtanen a écrit :
It is a sample code to show inconcistency of chainDeferred, not a real case. Add my_defer.callback(True) after the sample code if you'd like and trace it. You should see that postprocessing() is called with None argument, but not with the result of previous callback as it should be with a normal behaviour of deferred callbacks (read the tutorial)
Same as before, it is a *sample code*. In real case theRealMcCoy (and some more methodes) is added before I need to add a post/preprocessing to that defer. So, I restate the probleme with chainDeferred : chainDeferred(d) is equivalent to addCallbacks(d.callback, d.errback), but this two methods are not really sort of callback methods for deferred coz they didn't return a result. effcy.
![](https://secure.gravatar.com/avatar/56e4cc78ea7fcf3bb37888ebf23bc1f0.jpg?s=120&d=mm&r=g)
On Wed, Jan 28, 2004 at 07:22:40PM +0100, Fabrice Coudert wrote:
Without a use case, there's no chance of the behavior changing. False consistency is the hobgoblin of, etc.
If the code you included in your message isn't equivalent to the code you're using in your actual application, then it's a waste of time to discuss it. If it is equivalent, I don't see why you can't use the code glyph suggested.
If it doesn't do what you want, don't use it. For that matter, even if it does, you can probably avoid using it. As glyph stated, it is a hold-over from times past. If you can share the real use case, maybe someone can help you reformulate it in terms of more recent APIs.
effcy.
Jp
![](https://secure.gravatar.com/avatar/1ea1e7c4b19133819dafe3ac8275406f.jpg?s=120&d=mm&r=g)
Tommi Virtanen a écrit :
It is a sample code to show inconcistency of chainDeferred, not a real case. Add my_defer.callback(True) after the sample code if you'd like and trace it. You should see that postprocessing() is called with None argument, but not with the result of previous callback as it should be with a normal behaviour of deferred callbacks (read the tutorial)
Same as before, it is a *sample code*. In real case theRealMcCoy (and some more methodes) is added before I need to add a post/preprocessing to that defer. So, I restate the probleme with chainDeferred : chainDeferred(d) is equivalent to addCallbacks(d.callback, d.errback), but this two methods are not really sort of callback methods for deferred coz they didn't return a result. effcy.
![](https://secure.gravatar.com/avatar/15fa47f2847592672210af8a25cd1f34.jpg?s=120&d=mm&r=g)
On Jan 29, 2004, at 10:09 AM, Glyph Lefkowitz wrote:
So, the right way to do what he asks is...? Perhaps this? my_defer = getADeferredForSomething() new_defer = defer.Deferred() new_defer.addCallback(preprocessing) new_defer.addCallback(lambda x: return my_defer) new_defer.addCallback(postprocessing) my_defer = new_defer James
participants (6)
-
Fabrice Coudert
-
Fabrice Coudert
-
Glyph Lefkowitz
-
James Y Knight
-
Jp Calderone
-
Tommi Virtanen