拡張
****

"asyncio" を拡張する主な方法は、独自の *イベントループ* クラスを書くこ
とです。 asyncio には、この作業を簡単にするための補助機能があります。

注釈:

  サードパーティーが既存の asyncio コードを再利用する際は注意してくだ
  さい。 新しい Python バージョンでは、API の *内部的な* 部分について
  後方互換性が失われる可能性があります。


独自のイベントループを書く
==========================

"asyncio.AbstractEventLoop" には非常に多くのメソッドが宣言されており、
すべてを一から実装するのは大変な作業です。

"asyncio.BaseEventLoop" を継承すれば、多くの共通メソッドの実装をそのま
ま利用できます。

その代わり、サブクラスでは "asyncio.BaseEventLoop" に宣言されているも
のの実装されていない *非公開* メソッドを実装する必要があります。

例えば "loop.create_connection()" は、引数の検査と DNS によるアドレス
解決を行い、サブクラスで実装すべき "loop._make_socket_transport()" を
呼び出します。 "_make_socket_transport()" は文書化されておらず、*内部*
API とみなされます。


Future と Task の非公開コンストラクター
=======================================

"asyncio.Future" と "asyncio.Task" は直接作成しないでください。 代わり
に、それぞれに対応するファクトリー "loop.create_future()" と
"loop.create_task()"、または "asyncio.create_task()" を使ってください
。

ただし、サードパーティーの *イベントループ* は、複雑で高度に最適化され
たコードを自前で実装せずに利用するために、組み込みの Future と Task の
実装を *再利用* してもかまいません。

この目的のために、以下の *非公開* コンストラクターを紹介します。

Future.__init__(*, loop=None)

   組み込みの Future インスタンスを作成します。

   *loop* は省略可能なイベントループのインスタンスです。

Task.__init__(coro, *, loop=None, name=None, context=None)

   組み込みの Task インスタンスを作成します。

   *loop* は省略可能なイベントループのインスタンスです。 他の引数につ
   いては "loop.create_task()" を参照してください。

   バージョン 3.11 で変更: *context* 引数が追加されました。


タスクの生存期間の管理
======================

サードパーティーのタスク実装では、"asyncio.all_tasks()" と
"asyncio.current_task()" でタスクを取得できるように、次の関数を呼び出
す必要があります。

asyncio._register_task(task)

   新しい *task* を *asyncio* が管理するタスクとして登録します。

   タスクのコンストラクターから呼び出してください。

asyncio._unregister_task(task)

   *asyncio* の内部データ構造から *task* の登録を解除します。

   タスクが終了する直前に呼び出してください。

asyncio._enter_task(loop, task)

   現在のタスクを、引数 *task* に切り替えます。

   タスク内の *コルーチン* を部分的に実行する直前 ("coroutine.send()"
   または "coroutine.throw()" の呼び出し直前) に呼び出してください。

asyncio._leave_task(loop, task)

   現在のタスクを *task* から "None" に戻します。

   "coroutine.send()" または "coroutine.throw()" の実行直後に呼び出し
   てください。
