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

_______________________________________________
Twisted-Python mailing list
Twisted-Python@twistedmatrix.com
http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python

Reply via email to