Future
******

**ソースコード:** Lib/asyncio/futures.py, Lib/asyncio/base_futures.py

======================================================================

*Future* オブジェクトは **低水準のコールバックベースのコード** と高水
準の async/await コードとの間を橋渡しします。


Future の関数
=============

asyncio.isfuture(obj)

   オブジェクト *obj* が下記のいずれかであれば "True" を返します:

   * "asyncio.Future" クラスのインスタンス

   * "asyncio.Task" クラスのインスタンス

   * "_asyncio_future_blocking" 属性を持った Future 的なオブジェクト

   バージョン 3.5 で追加.

asyncio.ensure_future(obj, *, loop=None)

   下記のいずれかを返します:

   * *obj* が "Future" オブジェクト、 "Task" オブジェクト、または
     Future 的なオブジェクト ("isfuture()" 関数を使って検査します) で
     ある場合には *obj* そのもの

   * 引数 *obj* がコルーチンである ("iscoroutine()" 関数を使って検査し
     ます) 場合には *obj* をラップした "Task" オブジェクト; この場合コ
     ルーチンは "ensure_future()" によりスケジュールされます。

   * 引数 *obj* が awaitable である ("inspect.isawaitable()" 関数を使
     って検査します) 場合には *obj* を await する "Task" オブジェクト

   引数 *obj* が上記のいずれにもあてはまらない場合は "TypeError" 例外
   を送出します。

   重要:

     Task を生成するより好ましい方法である "create_task()" 関数も参照
     してください。Save a reference to the result of this function, to
     avoid a task disappearing mid execution.

   バージョン 3.5.1 で変更: この関数はどんな *awaitable* なオブジェク
   トでも受け入れるようになりました。

asyncio.wrap_future(future, *, loop=None)

   "concurrent.futures.Future" オブジェクトを "asyncio.Future" オブジ
   ェクトでラップします。


Future オブジェクト
===================

class asyncio.Future(*, loop=None)

   Future は非同期処理の最終結果を表すクラスです。スレッドセーフではあ
   りません。

   Future は *awaitable* オブジェクトです。コルーチンは Future オブジ
   ェクトが結果を返すか、例外をセットするか、もしくはキャンセルされる
   まで待機する (await) ことができます。

   典型的には、 Future は低水準のコールバックベースのコード (たとえば
   asyncio の transports を使って実装されたプロトコル) が高水準の
   async/await と相互運用することを可能にするために利用されます。

   経験則は Future オブジェクトをユーザー向けの API であらわに利用しな
   いことです。推奨される Future オブジェクトの生成方法は
   "loop.create_future()" を呼び出すことです。これによりイベントループ
   の代替実装は、自身に最適化された Future オブジェクトの実装を合わせ
   て提供することができます。

   バージョン 3.7 で変更: "contextvars" モジュールのサポートを追加。

   result()

      Future の結果を返します。

      Future が *完了* していて、 "set_result()" メソッドにより設定さ
      れた結果を持っている場合は結果の値を返します。

      Future が *完了* していて、 "set_exception()" メソッドにより設定
      された例外を持っている場合はその例外を送出します。

      Future が *キャンセルされた* 場合、このメソッドは
      "CancelledError" 例外を送出します。

      Future の結果が未設定の場合、このメソッドは "InvalidStateError"
      例外を送出します。

   set_result(result)

      Future を *完了* とマークし、結果を設定します。

      Future がすでに *完了* している場合 "InvalidStateError" 例外を送
      出します。

   set_exception(exception)

      Future を *完了* とマークし、例外を設定します。

      Future がすでに *完了* している場合 "InvalidStateError" 例外を送
      出します。

   done()

      Future が *完了* しているなら "True" を返します。

      Future は *キャンセルされた* か、または "set_result()" メソッド
      や "set_exception()" メソッドの呼び出しにより結果や例外が設定さ
      れた場合に *完了* とみなされます。

   cancelled()

      Future が *キャンセルされた* 場合に "True" を返します。

      通常の場合、このメソッドは Future に処理結果や例外を設定する前に
      Future が *キャンセルされていない* ことを確認するために使用され
      ます:

         if not fut.cancelled():
             fut.set_result(42)

   add_done_callback(callback, *, context=None)

      Future が *完了* したときに実行されるコールバックを追加します。

      *callback* は Future オブジェクトだけを引数にとって呼び出されま
      す。

      このメソッドが呼び出される時点ですでに Future が *完了* している
      場合、コールバックは "loop.call_soon()" メソッドによりスケジュー
      ルされます。

      オプションのキーワード引数 *context* を使って、コールバック
      *callback* を実行する際のコンテキスト "contextvars.Context" を設
      定することができます。コンテキスト *context* が指定されない場合
      は現在のコンテキストが使われます。

      コールバックにパラメータを渡すには、次の例のように
      "functools.partial()" を使うことができます:

         # Call 'print("Future:", fut)' when "fut" is done.
         fut.add_done_callback(
             functools.partial(print, "Future:"))

      バージョン 3.7 で変更: キーワード引数 *context* が追加されました
      。詳細は **PEP 567** を参照してください。

   remove_done_callback(callback)

      コールバックリストから *callback* を削除します。

      削除されたコールバックの数を返します。コールバックが複数回追加さ
      れていない限り、通常は1が返ります。

   cancel(msg=None)

      Future をキャンセルし、コールバックをスケジュールします。

      Future がすでに *完了* または *キャンセル* された場合、 "False"
      を返します。そうでない場合 Future の状態を *キャンセル* に変更し
      た上でコールバックをスケジュールし、 "True" を返します。

      バージョン 3.9 で変更: Added the "msg" parameter.

   exception()

      この Future オブジェクトに設定された例外を返します。

      例外 (または例外が設定されていないときは "None") は Future が *
      完了* している場合のみ返されます。

      Future が *キャンセルされた* 場合、このメソッドは
      "CancelledError" 例外を送出します。

      Future が *未完了* の場合、このメソッドは "InvalidStateError" 例
      外を送出します。

   get_loop()

      Future オブジェクトが束縛されているイベントループを返します。

      バージョン 3.7 で追加.

この例は Future オブジェクトを生成し、Future に結果を設定するための非
同期タスクを生成してスケジュールし、そして Future に結果が設定されるま
で待機します:

   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())

重要:

  Future オブジェクトは "concurrent.futures.Future" を模倣してデザイン
  されました。両者の重要な違いは以下の通りです:

  * asyncio の Futures と異なり、 "concurrent.futures.Future" インスタ
    ンスは待ち受けできません。

  * "asyncio.Future.result()" と "asyncio.Future.exception()"  は
    *timeout* 引数を取りません。

  * "asyncio.Future.result()" と "asyncio.Future.exception()" は
    Future が *未完了* の場合に "InvalidStateError" 例外を送出します。

  * "asyncio.Future.add_done_callback()" メソッドによって登録されたコ
    ールバックは、即座に呼び出されません。代わりにコールバックは
    "loop.call_soon()" によりスケジュールされます。

  * asyncio の Future は "concurrent.futures.wait()" および
    "concurrent.futures.as_completed()" との互換性がありません。

  * "asyncio.Future.cancel()" メソッドはオプションの "msg" 引数を指定
    できますが、 "concurrent.futures.cancel()" では指定することはでき
    ません。
