Futures¶
Source code: Lib/asyncio/futures.py, Lib/asyncio/base_futures.py
Future objects are used to bridge low-level callback-based code with high-level async/await code.
Future Functions¶
- asyncio.isfuture(obj)¶
- Return - Trueif obj is either of:- an instance of - asyncio.Future,
- an instance of - asyncio.Task,
- a Future-like object with a - _asyncio_future_blockingattribute.
 - Added in version 3.5. 
- asyncio.ensure_future(obj, *, loop=None)¶
- Return: - obj argument as is, if obj is a - Future, a- Task, or a Future-like object (- isfuture()is used for the test.)
- a - Taskobject wrapping obj, if obj is a coroutine (- iscoroutine()is used for the test); in this case the coroutine will be scheduled by- ensure_future().
- a - Taskobject that would await on obj, if obj is an awaitable (- inspect.isawaitable()is used for the test.)
 - If obj is neither of the above a - TypeErroris raised.- Important - See also the - create_task()function which is the preferred way for creating new Tasks.- Save a reference to the result of this function, to avoid a task disappearing mid-execution. - Changed in version 3.5.1: The function accepts any awaitable object. - Deprecated since version 3.10: Deprecation warning is emitted if obj is not a Future-like object and loop is not specified and there is no running event loop. 
- asyncio.wrap_future(future, *, loop=None)¶
- Wrap a - concurrent.futures.Futureobject in a- asyncio.Futureobject.- Deprecated since version 3.10: Deprecation warning is emitted if future is not a Future-like object and loop is not specified and there is no running event loop. 
Future Object¶
- class asyncio.Future(*, loop=None)¶
- A Future represents an eventual result of an asynchronous operation. Not thread-safe. - Future is an awaitable object. Coroutines can await on Future objects until they either have a result or an exception set, or until they are cancelled. A Future can be awaited multiple times and the result is same. - Typically Futures are used to enable low-level callback-based code (e.g. in protocols implemented using asyncio transports) to interoperate with high-level async/await code. - The rule of thumb is to never expose Future objects in user-facing APIs, and the recommended way to create a Future object is to call - loop.create_future(). This way alternative event loop implementations can inject their own optimized implementations of a Future object.- Changed in version 3.7: Added support for the - contextvarsmodule.- Deprecated since version 3.10: Deprecation warning is emitted if loop is not specified and there is no running event loop. - result()¶
- Return the result of the Future. - If the Future is done and has a result set by the - set_result()method, the result value is returned.- If the Future is done and has an exception set by the - set_exception()method, this method raises the exception.- If the Future has been cancelled, this method raises a - CancelledErrorexception.- If the Future’s result isn’t yet available, this method raises an - InvalidStateErrorexception.
 - set_result(result)¶
- Mark the Future as done and set its result. - Raises an - InvalidStateErrorerror if the Future is already done.
 - set_exception(exception)¶
- Mark the Future as done and set an exception. - Raises an - InvalidStateErrorerror if the Future is already done.
 - done()¶
- Return - Trueif the Future is done.- A Future is done if it was cancelled or if it has a result or an exception set with - set_result()or- set_exception()calls.
 - cancelled()¶
- Return - Trueif the Future was cancelled.- The method is usually used to check if a Future is not cancelled before setting a result or an exception for it: - if not fut.cancelled(): fut.set_result(42) 
 - add_done_callback(callback, *, context=None)¶
- Add a callback to be run when the Future is done. - The callback is called with the Future object as its only argument. - If the Future is already done when this method is called, the callback is scheduled with - loop.call_soon().- An optional keyword-only context argument allows specifying a custom - contextvars.Contextfor the callback to run in. The current context is used when no context is provided.- functools.partial()can be used to pass parameters to the callback, e.g.:- # Call 'print("Future:", fut)' when "fut" is done. fut.add_done_callback( functools.partial(print, "Future:")) - Changed in version 3.7: The context keyword-only parameter was added. See PEP 567 for more details. 
 - remove_done_callback(callback)¶
- Remove callback from the callbacks list. - Returns the number of callbacks removed, which is typically 1, unless a callback was added more than once. 
 - cancel(msg=None)¶
- Cancel the Future and schedule callbacks. - If the Future is already done or cancelled, return - False. Otherwise, change the Future’s state to cancelled, schedule the callbacks, and return- True.- Changed in version 3.9: Added the msg parameter. 
 - exception()¶
- Return the exception that was set on this Future. - The exception (or - Noneif no exception was set) is returned only if the Future is done.- If the Future has been cancelled, this method raises a - CancelledErrorexception.- If the Future isn’t done yet, this method raises an - InvalidStateErrorexception.
 - get_loop()¶
- Return the event loop the Future object is bound to. - Added in version 3.7. 
 
This example creates a Future object, creates and schedules an asynchronous Task to set result for the Future, and waits until the Future has a result:
async def set_after(fut, delay, value):
    # Sleep for *delay* seconds.
    await asyncio.sleep(delay)
    # Set *value* as a result of *fut* Future.
    fut.set_result(value)
async def main():
    # Get the current event loop.
    loop = asyncio.get_running_loop()
    # Create a new Future object.
    fut = loop.create_future()
    # Run "set_after()" coroutine in a parallel Task.
    # We are using the low-level "loop.create_task()" API here because
    # we already have a reference to the event loop at hand.
    # Otherwise we could have just used "asyncio.create_task()".
    loop.create_task(
        set_after(fut, 1, '... world'))
    print('hello ...')
    # Wait until *fut* has a result (1 second) and print it.
    print(await fut)
asyncio.run(main())
Important
The Future object was designed to mimic
concurrent.futures.Future.  Key differences include:
- unlike asyncio Futures, - concurrent.futures.Futureinstances cannot be awaited.
- asyncio.Future.result()and- asyncio.Future.exception()do not accept the timeout argument.
- asyncio.Future.result()and- asyncio.Future.exception()raise an- InvalidStateErrorexception when the Future is not done.
- Callbacks registered with - asyncio.Future.add_done_callback()are not called immediately. They are scheduled with- loop.call_soon()instead.
- asyncio Future is not compatible with the - concurrent.futures.wait()and- concurrent.futures.as_completed()functions.
- asyncio.Future.cancel()accepts an optional- msgargument, but- concurrent.futures.Future.cancel()does not.