Skip to content

PY-ASYN0004 · default_executor_to_thread_candidate

Count default-executor calls that can usually use asyncio.to_thread.

This is a deterministic rule for python. Read its implementation.

For Python 3.9 or newer, find run_in_executor(None, callable, *args) calls on a loop obtained from asyncio.get_running_loop or get_event_loop. The first None selects the default thread executor. The value is the number of candidates.

Every finding identifies the call and its nearest enclosing function. The value is the number of default-executor calls that could become asyncio.to_thread.

Keep run_in_executor when selecting a custom executor, retaining a specific Future contract, or deliberately avoiding contextvars propagation. asyncio.to_thread is for blocking work that should not block the event loop. It does not turn coroutine execution into threading and does not generally make CPU-bound Python code parallel on a GIL-enabled build. python_minor is the Python 3 minor version the project targets, and the rule reports nothing below 9 because asyncio.to_thread does not exist there.

await loop.run_in_executor(None, read_file, path) is reported and can usually become await asyncio.to_thread(read_file, path). Passing an explicit process, interpreter, or thread executor is accepted.

  • Cites “The Python Standard Library”, asyncio.to_thread. Open reference
  • Cites “The Python Standard Library”, asyncio multithreading guidance. Open reference