This rule raises an issue when synchronous file operations like open() are used within asynchronous functions.

Why is this an issue?

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:

Using these constructs allows other tasks to continue executing while waiting for the potentially blocking file operation to complete.

How to fix it in Asyncio

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.

Code examples

Noncompliant code example

async def read_config():
    with open("config.json", "r") as file:  # Noncompliant
        data = file.read()
    return data

Compliant solution

import aiofiles

async def read_config():
    async with aiofiles.open("config.json", "r") as file: # Compliant
        data = await file.read()
    return data

How to fix it in Trio

Use trio.open_file() to handle file operations asynchronously.

Code examples

Noncompliant code example

async def read_config():
    with open("config.json", "r") as file:  # Noncompliant
        data = file.read()
    return data

Compliant solution

import trio

async def read_config():
    async with await trio.open_file("config.json", "r") as file: # Compliant
        data = await file.read()
    return data

How to fix it in AnyIO

Use anyio.open_file() to handle file operations asynchronously.

Code examples

Noncompliant code example

async def read_config():
    with open("config.json", "r") as file:  # Noncompliant
        data = file.read()
    return data

Compliant solution

import anyio

async def read_config():
    async with await anyio.open_file("config.json", "r") as file: # Compliant
        data = await file.read()
    return data

Resources

Documentation

Articles & blog posts