This rule raises an issue when synchronous file operations like open() are used within asynchronous functions.
Using synchronous file operations like open() in asynchronous code blocks the entire event loop. This undermines the primary advantage
of asynchronous programming - the ability to perform concurrent operations without blocking execution.
When an async function makes a synchronous file operation:
Instead, async libraries provide mechanisms to handle file operations asynchronously:
aiofiles library for asyncio trio.open_file() for Trio anyio.open_file() for AnyIO Using these constructs allows other tasks to continue executing while waiting for the potentially blocking file operation to complete.
The standard library’s asyncio package doesn’t provide built-in asynchronous file I/O operations. Use the aiofiles
library to handle file operations asynchronously.
async def read_config():
with open("config.json", "r") as file: # Noncompliant
data = file.read()
return data
import aiofiles
async def read_config():
async with aiofiles.open("config.json", "r") as file: # Compliant
data = await file.read()
return data
Use trio.open_file() to handle file operations asynchronously.
async def read_config():
with open("config.json", "r") as file: # Noncompliant
data = file.read()
return data
import trio
async def read_config():
async with await trio.open_file("config.json", "r") as file: # Compliant
data = await file.read()
return data
Use anyio.open_file() to handle file operations asynchronously.
async def read_config():
with open("config.json", "r") as file: # Noncompliant
data = file.read()
return data
import anyio
async def read_config():
async with await anyio.open_file("config.json", "r") as file: # Compliant
data = await file.read()
return data