できない.dev

Python で「coroutine was never awaited」の警告が出て非同期処理が実行されない

async 関数は呼び出しただけでは実行されず、コルーチンオブジェクトを返すだけである。
await するか asyncio でスケジュールすると解決する。

公開: 更新:

実行例あり(2026-09-10 に実環境で検証)

要約

RuntimeWarning: coroutine '...' was never awaited は、async 関数を呼び出したのに await もスケジュールもしていないときに出る。
async 関数は呼んだだけでは実行されず、コルーチンオブジェクトを返すだけである。await するか、asyncio.run()asyncio.create_task() でイベントループに乗せると解決する。

実行例

Python 3.12.14 で await を書き忘れた版を動かすと、RuntimeWarning が出るだけで終了コードは 0 のまま返り、task の中身は一度も実行されずに main だけが終わる。
await を付けた版と create_task でまとめた版はどちらも中身が実行され、呼び出しただけのコルーチンは coroutine クラスのオブジェクトとして残っていることも確認できる。

$ python -V
Python 3.12.14
$ python bad.py
/tmp/tmp.1P49T7pNB7/bad.py:9: RuntimeWarning: coroutine 'task' was never awaited
  task()  # await も create_task もしていない
RuntimeWarning: Enable tracemalloc to get the object allocation traceback
main は終了した
終了コード: 0(0 でも警告だけ出るのがこの問題の厄介な点)
$ python good_await.py
task が実行された
終了コード: 0
$ python good_tasks.py
task 1 が実行された
task 2 が実行された
終了コード: 0
$ python coroutine_object.py
型: <class 'coroutine'>

— 2026-09-10 時点の出力

検証環境

検証日
実行環境
python:3.12Debian GNU/Linux 13 (trixie)
バージョン
  • Python 3.12.14
  • Git 2.47.3

この記事の「実行例」は、上記の環境で実際にコマンドを実行して得られた出力をそのまま掲載しています。 再現手順はリポジトリの検証スクリプトとして管理し、定期的に再実行して出力を更新しています。

よくある原因

  1. await 忘れ: foo() と書いただけでは、コルーチンオブジェクトが作られるだけで中身は動かない。
  2. 同期コードから直接呼んでいる: 通常の関数の中で await は使えないため、コルーチンが宙に浮く。
  3. スケジュールしていない: create_task()run() を通さないと、イベントループが実行する対象にならない。

解決策

1. async 関数の中では await する

import asyncio
 
async def task():
    print("done")
 
async def main():
    await task()   # await を付ける
 
asyncio.run(main())

2. 同期コードの入口では asyncio.run を使う

スクリプトのトップレベルなど await できない場所からは、イベントループを起動する。

asyncio.run(main())

3. 並行に走らせたいなら create_task

複数のコルーチンを同時に進めたいときは、タスクとしてスケジュールしてから await する。

async def main():
    t1 = asyncio.create_task(task())
    t2 = asyncio.create_task(task())
    await t1
    await t2

公式のDeveloping with asyncio(新しいタブで開く)にも、未 await のコルーチンを検出する仕組みが説明されている。

この記事は役立ちましたか?