该警告表明创建了协程对象但未await或调度执行;python 3.8+在垃圾回收时触发runtimewarning;主因是直接调用异步函数不await、同步方法中误调异步函数、或遗漏上下文管理器的await。

为什么 asyncio.run() 会报 “coroutine ‘xxx’ was never awaited” 警告?
这个警告不是错误,但说明你创建了一个 coroutine 对象却没用 await 或 asyncio.create_task() 等方式驱动它执行。Python 3.8+ 默认开启协程未等待检测,一旦函数返回协程对象(比如调用了异步函数但没 await),解释器会在垃圾回收时触发 RuntimeWarning。
如何快速禁用该警告(不推荐长期使用)
仅在调试或临时绕过时可用,本质是掩盖问题而非解决:
- 用
warnings.filterwarnings("ignore", category=RuntimeWarning, message="coroutine.*was never awaited") - 或启动 Python 时加参数:
python -W ignore::RuntimeWarning:asyncio:.*was never awaited - 注意:该过滤对所有协程未 await 场景一并屏蔽,可能错过真正疏漏
真正安全的修复方式:检查协程调用链
90% 的情况源于以下三类误用:
- 直接调用异步函数却不
await:my_async_func()→ 应改为await my_async_func()或asyncio.create_task(my_async_func()) - 在同步函数中调用异步函数(如
__init__、__str__),无法用await→ 必须重构,例如把异步初始化逻辑移到async def init()并显式 await - 忘记在
asyncio.run()外层包裹整个入口协程:写成asyncio.run(main())是对的,但若写成asyncio.run(main)(没加括号),则传入的是函数对象而非协程对象,不会报此警告,但也不会执行 —— 这是另一个常见混淆点
用 pytest 或日志确认是否还有残留协程未 await
开发阶段可主动探测:
- 在程序退出前插入检查:
import asyncio; assert not asyncio.all_tasks(), "uncleaned tasks remain" - 用
pytest-asyncio时,确保测试函数本身是async def test_xxx(),且未在setup_method等同步钩子中调用异步函数 - 启用 asyncio 调试模式:
asyncio.run(main(), debug=True),它会在未 await 协程被销毁时输出更详细的栈帧
aiohttp 或 httpx.AsyncClient)的上下文管理器退出时会返回协程,必须 await 其 __aexit__,否则也会触发该警告。Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











