[Twisted-Python] inlineCallbacks yield tuple support

Сергей Магафуров smagafurov at naumen.ru
Thu Aug 5 21:06:04 MDT 2010


This example shows what i want:

@defer.inlineCallbacks
def create_audio_link(tel, addr1, addr2):
     try:
         connection1, connection2 = yield (tel.connect(addr1), tel.connect(addr2))
     except ConnectionError, exc:
         ... some error work ...
     else:
         return tel.create_audiolink(connection1, connection2)

At now we can do this with DeferredList but it is complex (compare with 
first example):

@defer.inlineCallbacks
def create_audio_link(tel, addr1, addr2):
     try:
         try:
             r = yield DeferredList([tel.connect(addr1), tel.connect(addr2)], fireOnOneErrback=1, consumeErrors=1)
         except FirstError, exc:
             raise exc.subFailure.value
         else:
             connection1, connection2 = tuple(_r for _s, _r in r)
     except ConnectionError, exc:
         ... some error work ...
     else:
         return tel.create_audiolink(connection1, connection2)

Approximate solution (idea) is patch in defer.py:

def _inlineCallbacks(result, g, deferred):
             ... skipped ...

         if isinstance(result, Deferred):
             # a deferred was yielded, get the result.

             ... skipped ...

             waiting[0] = True
             waiting[1] = None

         if isinstance(result, tuple):
             # a tuple was yielded, get the result.
             result = DeferredList(result, fireOnOneErrback=1, consumeErrors=1)
             def gotResult(r):
                 if isinstance(r, failure.Failure):
                     r = r.value.subFailure
                 else:
                     r = tuple(_r for _s, _r in r)
                 if waiting[0]:
                     waiting[0] = False
                     waiting[1] = r
                 else:
                     _inlineCallbacks(r, g, deferred)

             result.addBoth(gotResult)
             if waiting[0]:
                 # Haven't called back yet, set flag so that we get reinvoked
                 # and return from the loop
                 waiting[0] = False
                 return deferred

             result = waiting[1]
             # Reset waiting to initial values for next loop.  gotResult uses
             # waiting, but this isn't a problem because gotResult is only
             # executed once, and if it hasn't been executed yet, the return
             # branch above would have been taken.


             waiting[0] = True
             waiting[1] = None


     return deferred

I post this as ticket but was redirected to mailing-list
http://twistedmatrix.com/trac/ticket/4627

-------------- next part --------------
An HTML attachment was scrubbed...
URL: </pipermail/twisted-python/attachments/20100806/a23a3d0b/attachment.html>


More information about the Twisted-Python mailing list