def maybeDeferred(f, *args, **kw):
    """
    Invoke a function that may or may not return a L{Deferred}.

    Call the given function with the given arguments.  If the returned
    object is a L{Deferred}, return it.  If the returned object is a L{Failure},
    wrap it with L{fail} and return it.  Otherwise, wrap it in L{succeed} and
    return it.  If an exception is raised, convert it to a L{Failure}, wrap it
    in L{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: L{Deferred}
    @return: The result of the function call, wrapped in a L{Deferred} if
    necessary.
    """
    try:
        result = f(*args, **kw)
    except:
        return fail(failure.Failure(captureVars=Deferred.debug))

    if isinstance(result, Deferred):
        return result
    elif isinstance(result, failure.Failure):
        return fail(result)
    else:
        return succeed(result)

    Invoke a function that may or may not return a L{Deferred}.

    Call the given function with the given arguments.  If the returned
    object is a L{Deferred}, return it.  If the returned object is a L{Failure},
    wrap it with L{fail} and return it.  Otherwise, wrap it in L{succeed} and
    return it.  If an exception is raised, convert it to a L{Failure}, wrap it
    in L{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: L{Deferred}
    @return: The result of the function call, wrapped in a L{Deferred} if
    necessary.
    
stackoverflow/venv/lib/python3.6/site-packages/twisted/internet/defer.py