Debugging Asyncio Applications
メニューを表示するにはスワイプしてください
Async bugs are harder to track than synchronous ones. A forgotten await, a blocking call inside a coroutine, or a task that silently fails can all cause subtle, hard-to-reproduce issues. Asyncio provides several built-in tools to catch these problems early.
Debug Mode
Enable asyncio's debug mode to surface common mistakes that are silent in production:
1234567891011import asyncio import nest_asyncio nest_asyncio.apply() # Enabling debug mode to catch slow callbacks and missing awaits async def main(): await asyncio.sleep(0.1) print("Running in debug mode") asyncio.run(main(), debug=True)
In debug mode, asyncio:
- Warns about coroutines that were created but never awaited;
- Logs callbacks that take longer than 100ms (slow callback detection);
- Enables more detailed
repr()output for tasks and futures.
Detecting a Forgotten await
The most common asyncio mistake is calling an async function without await. The coroutine object is created but never executed:
12345678910111213141516171819import asyncio import warnings import nest_asyncio nest_asyncio.apply() async def fetch_data(): await asyncio.sleep(0.1) return "data" # Forgetting await – coroutine is never executed async def main(): result = fetch_data() # Missing await print(result) # <coroutine object fetch_data at 0x...> # Converting the warning to an error so it cannot be missed warnings.filterwarnings("error", category=RuntimeWarning) asyncio.run(main(), debug=True)
Python emits RuntimeWarning: coroutine 'fetch_data' was never awaited. Running with warnings.filterwarnings("error") converts this warning into an exception, making it impossible to miss.
Inspecting Running Tasks
Use asyncio.all_tasks() to see what is currently running – useful for identifying stuck or leaked tasks:
12345678910111213141516171819202122232425262728import asyncio import httpx import nest_asyncio nest_asyncio.apply() # Inspecting all running tasks mid-execution async def fetch_post(client, post_id): response = await client.get( f"https://jsonplaceholder.typicode.com/posts/{post_id}" ) return response.json()["title"] async def main(): async with httpx.AsyncClient() as client: tasks = [ asyncio.create_task(fetch_post(client, post_id)) for post_id in range(1, 4) ] print(f"Running tasks: {len(asyncio.all_tasks())}") results = await asyncio.gather(*tasks) for result in results: print(result) asyncio.run(main())
Tracing Slow Callbacks
A slow synchronous call inside a coroutine blocks the event loop without raising any error. Debug mode catches it:
12345678910111213141516import asyncio import time import nest_asyncio nest_asyncio.apply() # Detecting a slow callback with a custom threshold async def main(): loop = asyncio.get_event_loop() loop.slow_callback_duration = 0.05 # Warning threshold: 50ms await asyncio.sleep(0) time.sleep(0.2) # Blocking call – triggers a slow callback warning await asyncio.sleep(0) asyncio.run(main(), debug=True)
Common Asyncio Bugs and Fixes
フィードバックありがとうございます!
AIに質問する
AIに質問する
何でも質問するか、提案された質問の1つを試してチャットを始めてください