Example #1
0
def maybeDeferred(f, *args, **kw):
    """Invoke a function that may or may not return a deferred.

    Call the given function with the given arguments.  If the returned
    object is a C{Deferred}, return it.  If the returned object is a C{Failure},
    wrap it with C{fail} and return it.  Otherwise, wrap it in C{succeed} and
    return it.  If an exception is raised, convert it to a C{Failure}, wrap it
    in C{fail}, and then return it.

    @type f: Any callable
    @param f: The callable to invoke

    @param args: The arguments to pass to C{f}
    @param kw: The keyword arguments to pass to C{f}

    @rtype: C{Deferred}
    @return: The result of the function call, wrapped in a C{Deferred} if
    necessary.
    """
    try:
        result = f(*args, **kw)
    except:
        return fail(Failure())

    if isinstance(result, Deferred):
        return result
    elif isinstance(result, Failure):
        return fail(result)
    else:
        return succeed(result)
Example #2
0
    def _cbDeferred(self, result, index, succeeded):
        """(internal) Callback for when one of my deferreds fires.
        """
        self.resultList[index] = (succeeded, result)

        self.finishedCount += 1
        if not self.called:
            if succeeded == SUCCESS and self.fireOnOneCallback:
                self.callback((result, index))
            elif succeeded == FAILURE and self.fireOnOneErrback:
                self.errback(Failure(FirstError(result, index)))
            elif self.finishedCount == len(self.resultList):
                self.callback(self.resultList)

        if succeeded == FAILURE and self.consumeErrors:
            result = None

        return result
Example #3
0
    def _runCallbacks(self):
        if self._runningCallbacks:
            # Don't recursively run callbacks
            return
        if not self.paused:
            while self.callbacks:
                item = self.callbacks.pop(0)
                callback, args, kw = item[
                    isinstance(self.result, Failure)]
                args = args or ()
                kw = kw or {}
                try:
                    self._runningCallbacks = True
                    try:
                        self.result = callback(self.result, *args, **kw)
                    finally:
                        self._runningCallbacks = False
                    if isinstance(self.result, Deferred):
                        # note: this will cause _runCallbacks to be called
                        # recursively if self.result already has a result.
                        # This shouldn't cause any problems, since there is no
                        # relevant state in this stack frame at this point.
                        # The recursive call will continue to process
                        # self.callbacks until it is empty, then return here,
                        # where there is no more work to be done, so this call
                        # will return as well.
                        self.pause()
                        self.result.addBoth(self._continue)
                        break
                except:
                    self.result = Failure()

        if isinstance(self.result, Failure):
            self.result.cleanFailure()
            if self._debugInfo is None:
                self._debugInfo = DebugInfo()
            self._debugInfo.failResult = self.result
        else:
            if self._debugInfo is not None:
                self._debugInfo.failResult = None
Example #4
0
    def errback(self, fail=None):
        """
        Run all error callbacks that have been added to this Deferred.

        Each callback will have its result passed as the first
        argument to the next; this way, the callbacks act as a
        'processing chain'. Also, if the error-callback returns a non-Failure
        or doesn't raise an Exception, processing will continue on the
        *success*-callback chain.

        If the argument that's passed to me is not a Failure instance,
        it will be embedded in one. If no argument is passed, a Failure
        instance will be created based on the current traceback stack.

        Passing a string as `fail' is deprecated, and will be punished with
        a warning message.

        @raise NoCurrentExceptionError: If C{fail} is C{None} but there is
            no current exception state.
        """
        if not isinstance(fail, Failure):
            fail = Failure(fail)

        self._startRunCallbacks(fail)
Example #5
0
def timeout(deferred):
    deferred.errback(Failure(TimeoutError("Callback timed out")))