Here is a homemade Future class:class Future:    Represent sn asynchronous result.    Use add_callback to construct a chain of callbacks to be called when the    Future's result is ready.        def __init__(self):        self.callbacks = []        self._fired = False        self.result = None    def add_callback(self, callback):        Add a callback.        Args:            callback (function): A function taking one variable.                self.callbacks.append(callback)        if self._fired:            self._execute_callbacks(self.result)    def set_result(self, result=None):        Set the initial result of the Future, starting the callback chain.        Args:            result: The result of the Future. This result is passed to the first                callback, and then each callback's result is passed to the next.                if self._fired == True:            raise RuntimeError(Cannot fire Future twice)        self._fired = True        self._execute_callbacks(result)    def _execute_callbacks(self, result):        self.result = result        while len(self.callbacks):            cb = self.callbacks.pop(0)            self.result = cb(self.result)            if isinstance(self.result, Future):                self.result.add_callback(self._execute_callbacks)                breakdef call_as_future(func, *args):    Call a function, guaranteeing the result is a Future.    result = func(*args)    if isinstance(result, Future):        return result    else:        f = Future()        f.set_result(result)        return fIt seems to work (i.e. it passes some basic tests).However, I'd like review of _execute_callbacks, particularly in the case that a callback returns a Future.In that case, we chain the outer Future's _execute_callbacks method to the end of the inner Future's list of callbacks. That way, when the inner Future fires, it will eventually pass its result back to the outer Future so the outer Future can keep going. If the inner Future has already fired, then adding a callback invokes that callback immediately (synchronously).This seems a bit weird because then the inner Future can call the outer Future's _execute_callbacks method before the first call to the outer Future's _execute_callbacks completes!I think this is ok because chaining _execute_callbacks to the inner Future is the last thing _execute_callbacks does, but I wonder whether there's a funky race condition lurking here.
Chainable futures in Python
python;asynchronous;callback