This rule raises an issue when a function is declared async but does not use any asynchronous features.
Declaring a function with async def signals that it’s a coroutine, typically because it needs to use await for
non-blocking operations (like I/O), or employs other asynchronous features like async for or async with.
If none of these asynchronous mechanisms are utilized within the function’s body, the async declaration is superfluous.
Using async unnecessarily can:
async def function creates a coroutine object. While modern Python is
efficient, this still incurs more overhead than a direct synchronous function call if the asynchronicity isn’t actually leveraged. The function’s
body will execute synchronously until an await (if any) is encountered. If there’s no await or other async feature, it
essentially runs synchronously but wrapped as a coroutine. await (or schedule it as a task) to execute the coroutine and get its result.
This is an unnecessary ceremony if the function itself isn’t truly asynchronous. Either remove the async keyword, or start using the appropriate asynchronous features.
async def my_function(): # Noncompliant
print("Hello from my function")
def my_function(): # Compliant
print("Hello from my function")
def another_function(): ...
async def my_function(): # Noncompliant
return another_function()
async def another_function(): ...
async def my_function(): # Compliant
return await another_function()