{"id":8164,"library":"flake8-async","title":"flake8-async","description":"flake8-async is a highly opinionated Flake8 plugin designed to identify common problems, potential bugs, dead code, performance issues, and idiom violations specific to asynchronous programming with Trio, AnyIO, and asyncio. It is actively maintained, with frequent releases following a CalVer (YY.month.patch) scheme. The plugin integrates with the standard `flake8` tool and some of its checks are also incorporated into the `ruff` linter.","status":"active","version":"25.7.1","language":"en","source_language":"en","source_url":"https://github.com/python-trio/flake8-async","tags":["flake8","linting","async","asyncio","trio","anyio","code quality","static analysis"],"install":[{"cmd":"pip install flake8-async","lang":"bash","label":"Basic Installation"},{"cmd":"pip install \"flake8-async[flake8]\"","lang":"bash","label":"With Flake8 for config file support"}],"dependencies":[{"reason":"Required for configuration file parsing (e.g., pyproject.toml, setup.cfg); otherwise, command-line usage is sufficient. Install via 'flake8-async[flake8]'.","package":"flake8","optional":true},{"reason":"Often recommended as a complementary plugin for additional bug-finding checks.","package":"flake8-bugbear","optional":true}],"imports":[],"quickstart":{"code":"import trio\n\nasync def busy_wait_function():\n    done = False\n    while not done:\n        await trio.sleep(0.001) # ASYNC110: async-busy-wait\n        # In a real scenario, 'done' would be set by some other async operation\n\nasync def main():\n    async with trio.open_nursery() as nursery:\n        nursery.start_soon(busy_wait_function)\n\nif __name__ == '__main__':\n    # To run flake8-async, save this as a .py file (e.g., 'my_async_code.py')\n    # and then run: flake8 my_async_code.py\n    # It should report ASYNC110.\n    pass","lang":"python","description":"To use flake8-async, install it and then run the `flake8` command on your Python files. The plugin will automatically detect and report issues. This example demonstrates a `busy_wait_function` that would trigger the `ASYNC110` warning, which suggests replacing `await trio.sleep()` in a `while` loop with an event-based mechanism for better efficiency."},"warnings":[{"fix":"Update all `TRIOxxx` error codes to their `ASYNCxxx` equivalents in your `flake8` configuration files or inline `# noqa` comments. Ensure you are installing `flake8-async`.","message":"The library was renamed from `flake8-trio` to `flake8-async` around version 24.3.1. Consequently, all error codes were renamed from `TRIOxxx` to `ASYNCxxx` (e.g., `TRIO100` became `ASYNC100`). Users upgrading from `flake8-trio` or older `flake8-async` versions need to update their configurations and `# noqa` comments.","severity":"breaking","affected_versions":"Before 24.3.1"},{"fix":"Install the library with the `flake8` extra: `pip install \"flake8-async[flake8]\"`.","message":"For `flake8-async` to correctly parse and apply configurations from `pyproject.toml`, `setup.cfg`, or other Flake8 configuration files, you must install `flake8` as an optional dependency using the `[flake8]` extra. Without this, the plugin will only respect command-line arguments.","severity":"gotcha","affected_versions":"All versions >= 25.2.3"},{"fix":"Ensure that any `fail_after` or `move_on_after` blocks contain at least one `await` expression. If the block genuinely requires no `await`, consider if the timeout is truly necessary or refactor to include an `await` that enables cancellation.","message":"The `ASYNC100` rule warns about `with trio.fail_after(...)` or `with trio.move_on_after(...):` context managers that do not contain any `await` statements. This renders the timeout context ineffective, as timeouts can only be triggered by explicit checkpoints (like `await`).","severity":"gotcha","affected_versions":"All versions"},{"fix":"Replace blocking calls with their asynchronous equivalents (e.g., `aiofiles` for file I/O, `httpx.AsyncClient` for HTTP requests) or offload them to a thread pool using functions like `trio.to_thread.run_sync()`, `anyio.to_thread.run_sync()`, or `asyncio.loop.run_in_executor()`.","message":"Rules like `ASYNC210-ASYNC251` detect blocking synchronous I/O, process, or OS calls (e.g., `time.sleep()`, `open()`, `subprocess.run()`, `requests.get()`) within `async def` functions. These calls will block the event loop, severely degrading concurrency and application responsiveness.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-04-16T00:00:00.000Z","next_check":"2026-07-15T00:00:00.000Z","problems":[{"fix":"Ensure that the `with` block includes at least one `await` call. For example, add an `await trio.sleep(0)` if a checkpoint is needed without blocking for time.","cause":"A `trio.fail_after` or `trio.move_on_after` block does not contain any `await` expressions, meaning the timeout cannot take effect.","error":"flake8: ASYNC100 No await statements in timeout context"},{"fix":"Refactor the code to use an event object (e.g., `trio.Event`, `anyio.Event`, `asyncio.Event`). Instead of `while not condition: await trio.sleep(...)`, use `await event.wait()` to pause until the condition is met efficiently.","cause":"The code is using a `while` loop with `await trio.sleep()` for busy-waiting, which is inefficient and leads to a trade-off between responsiveness and CPU usage.","error":"flake8: ASYNC110 while <condition>: await trio.sleep() should be replaced by a trio.Event"},{"fix":"Update all instances of `TRIOxxx` error codes (e.g., in `pyproject.toml`, `.flake8` config, or inline `# noqa` comments) to their new `ASYNCxxx` counterparts. Consult the `flake8-async` documentation for the mapping if needed.","cause":"You are using old `TRIOxxx` error codes from `flake8-trio` after upgrading to `flake8-async` (or newer `flake8-async` which was a merge). The codes were renamed to `ASYNCxxx`.","error":"flake8: TRIOxxx (or similar 'undefined name') while using old TRIO error codes after upgrade."}]}