non-local inlineCallbacks exit from returnValue being called in the wrong function is very confusing
[email protected] Mon, 07 Dec 2009 18:09:24 -0000
| Newsgroups | gmane.comp.python.twisted.bugs |
|---|---|
| Message-ID | <[email protected]> |
New submission from glyph <[email protected]>: Let's say we have a chunk of code like this: {{{ from twisted.internet.defer import inlineCallbacks, returnValue, succeed def asyncOperation(): return succeed(1) @inlineCallbacks def thunk(): value = yield asyncOperation() if value: returnValue(value) @inlineCallbacks def main(): print "Result:", (yield thunk()) main() }}} This is reasonably straightforward. However, let's say we wanted to refactor it, and we end up with this definition of 'thunk': {{{ def thunk2(value): if value: returnValue(value) @inlineCallbacks def thunk(): value = yield asyncOperation() returnValue((yield thunk2(value)) + 1) }}} (I realize that at such a small scale, a copy/paste error of this type seems ludicrous, but in a larger function, especially if it's spread across many functions and methods decorated with @inlineCallbacks, it's quite feasible.) The second version exits immediately with the "wrong" value, and it's very difficult to tell why. Worse yet, it fails even if remember to decorate `thunk2` with `inlineCallbacks`; it only starts to give us the "right" value when `thunk2` is properly a generator ''and'' decorated. Debugging this is tricky, because it looks like returnValue is causing `thunk` to exist, just with the wrong value! ---------- Type : enhancement Component: core Keywords : Priority : normal Nosy : ---------- http://twistedmatrix.com/trac/ticket/4157