[Twisted-Python] Deferred instance has no attribute '__getitem__' ??????

I have a function and two convenience functions, like this: @defer.inlineCallbacks def round_value_and_percent(id, value, percent): daily = 1. params = dict(nutidin=id, valuein=value, dvin=daily) query = "ROUND_NUT_DV" q_result = yield named_query_param(ctx, "nut", query, params) // db query rounded = {} rounded["value"] = q_result[0][0] rounded["percent"] = q_result[0][1] defer.returnValue((rounded['value'], rounded['percent'])) @defer.inlineCallbacks def round_val(id, value, rule): """ Return first element of round_value_and_percent """ defer.returnValue(round_value_and_percent(id, value, 0, rule)[0]) @defer.inlineCallbacks def round_per(id, percent, rule): """ Return second element of round_value_and_percent. """ defer.returnValue(round_value_and_percent(id, 0, percent, rule)[1]) When I do: result = yield round_val(1, 2, 3) I get this: Deferred instance has no attribute '__getitem__' Clues appreciated! Ken

@defer.inlineCallbacks def round_val(id, value, rule): """ Return first element of round_value_and_percent """ defer.returnValue(round_value_and_percent(id, value, 0, rule)[0])
When I do: result = yield round_val(1, 2, 3)
I get this: Deferred instance has no attribute '__getitem__'
round_value_and_percent returns a Deferred. You probably want: @defer.inlineCallbacks def round_val(id, value, rule): """ Return first element of round_value_and_percent """ x = yield round_value_and_percent(id, value, 0, rule) defer.returnValue(x[0])

On Jul 15, 2010, at 4:32 PM, Ken MacDonald wrote:
@defer.inlineCallbacks def round_val(id, value, rule): """ Return first element of round_value_and_percent """ defer.returnValue(round_value_and_percent(id, value, 0, rule)[0])
When I do: result = yield round_val(1, 2, 3)
I get this: Deferred instance has no attribute '__getitem__'
Clues appreciated!
@inlineCallbacks must decorate only generator functions. Since 'yield' doesn't appear anywhere in the body of round_val (or, for that matter, round_per) this code will break in other ways. Allen Short's suggestion will fix your code because it added a 'yield', but you need to be aware of this issue in case there are other such functions in the future that don't actually handle any Deferreds. Also, inlineCallbacks adds some overhead, and really should only be used when the resulting code is easier to read. Personally, I think a simpler definition of round_val would be simply def round_val(id, value, rule): """ Return first element of round_value_and_percent """ return round_value_and_percent(id, value, 0, rule).addCallback( lambda valueAndPercent: valueAndPercent[0] ) no @inlineCallbacks required.

Thanks for the assist, we ended up using something quite similar to this. I'm refactoring a portion of an app that was originally all in python, but now some functions were required to use the DB stored procedures instead for compatibility, and they weren't designed to be used in Twisted-fashion! On to the next interesting Twisted problem..... Ken @inlineCallbacks must decorate only generator functions.
Since 'yield' doesn't appear anywhere in the body of round_val (or, for that matter, round_per) this code will break in other ways. Allen Short's suggestion will fix your code because it added a 'yield', but you need to be aware of this issue in case there are other such functions in the future that don't actually handle any Deferreds.
Also, inlineCallbacks adds some overhead, and really should only be used when the resulting code is easier to read. Personally, I think a simpler definition of round_val would be simply
def round_val(id, value, rule): """ Return first element of round_value_and_percent """ return round_value_and_percent(id, value, 0, rule).addCallback( lambda valueAndPercent: valueAndPercent[0] )
no @inlineCallbacks required.
_______________________________________________ Twisted-Python mailing list Twisted-Python@twistedmatrix.com http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python
participants (3)
-
Allen Short
-
Glyph Lefkowitz
-
Ken MacDonald