[Twisted-Python] Inline Callbacks

Jason J. W. Williams jasonjwwilliams at gmail.com
Fri Apr 2 02:46:57 EDT 2010


Hi Christopher,

Apologize for the sloppy language. So would this be a better way of putting it?

Assuming a function func_a that has the inlineCallbacks decorator...

If func_a were added as a callback for a deferred (deferred 1), when
func_a was called another deferred would be returned (deferred 2)
which would only fire once func_a had run to the end of the function
and returned.

While func_a is running, every time yield is called, this would
operate similarly to writing a separate callback for the contents of
each of those yield statements and chaining them normally to each
other as callbacks.

That is this:

@defer.inlineCallbacks
def func_a(value):
   num = yield do_something(value)
   num2 = yield do_something_more(num)
   return num2

is equivalent to:

def func_a(value):
    return do_something(value).addCallback(cb_step_1)

def cb_step_1(num):
    return do_something_more(num).addCallback(cb_step_2)

def cb_step_2(num2):
    return num2


Thank you very much for your help in understanding this.  I've always
used a combination of deferreds and callbacks/errbacks to this point.

-J


On Thu, Apr 1, 2010 at 10:33 PM, Christopher Armstrong
<radix at twistedmatrix.com> wrote:
> On Thu, Apr 1, 2010 at 8:20 PM, Jason J. W. Williams
> <jasonjwwilliams at gmail.com> wrote:
>> Would it be fair to say that when developing code that utilizes
>> inlineCallbacks, your function is a generator that returns a deferred
>> whose callback is the coroutine that's yielding?
>
> It pays to be very very specific about all the different objects and
> interactions going on with generators in Python and especially with
> inlineCallbacks to avoid confusion.There are a couple of inaccuracies
> in this statement, some which I think are just about poor wording and
> some which come from misunderstanding.
>
> In Python, there are generator functions and there are generators.
> Calling a generator function returns a generator, which has next() and
> send() methods. Generators do not return things, though a generator's
> next() or send() methods do (I say this because you mentioned a
> "generator that returns a deferred").
>
> Also, there's nothing called a "coroutine" that's related to
> inlineCallbacks at all, and the word is fraught with ambiguities in
> Python, so it's best to just avoid it entirely.
>
> In inlineCallbacks, nobody but the person writing the
> inlineCallbacks-using function knows that there's a generator
> involved. The person calling your inlineCallbacks-using function can't
> see any generators; they just get a Deferred object which fires when
> the generator is exhausted. The interesting part is that
> inlineCallbacks is the thing responsible for iterating the generator,
> not user-code. It is responsible for calling .send() on the generator
> object when previously yielded deferreds have fired. The value of the
> Deferred returned will be whatever is passed to returnValue in the
> inlineCallbacks-using function.
>
> --
> Christopher Armstrong
> http://radix.twistedmatrix.com/
> http://planet-if.com/
>
> _______________________________________________
> Twisted-Python mailing list
> Twisted-Python at twistedmatrix.com
> http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python
>



More information about the Twisted-Python mailing list