拡張

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

注釈

Third-parties should reuse existing asyncio code with caution, a new Python version is free to break backward compatibility in the internal part of the API.

Writing a custom event loop

asyncio.AbstractEventLoop declares very many methods. See イベントループのメソッド for the full list. Implementing them all from scratch is a tedious job.

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() の実行直後に呼び出してください。