aiopath: Async pathlib for Python
raw JSON → 0.7.7 verified Thu Apr 16 auth: no python
aiopath provides an asynchronous implementation of Python's standard `pathlib` module, enabling non-blocking file system operations within `asyncio`, `trio`, and other `async`/`await` compatible frameworks. It mirrors `pathlib`'s API, making it familiar for users who need to perform I/O-bound tasks concurrently without blocking the event loop. The library is currently at version 0.7.7 and maintains an active development, addressing compatibility with newer Python versions and bug fixes.
pip install aiopath Common errors
error ImportError: cannot import name '_NormalAccessor' from 'pathlib' (Python 3.11) ↓
cause An older version of `aiopath` attempted to import a private internal class from `pathlib` that was removed in Python 3.11.
fix
Upgrade
aiopath to the latest version using pip install --upgrade aiopath. Version 0.7.0 and newer are designed for Python 3.11+ compatibility. error TypeError: 'async for' requires an object with __aiter__ method, got generator ↓
cause This error occurs when attempting to use `async for` with `AsyncPath.walk()`, indicating that the method returned a regular (synchronous) generator instead of an asynchronous one.
fix
Verify your
aiopath version. If the issue persists, manually iterate using AsyncPath.iterdir() and is_dir() for a recursive async walk, or await an official fix/workaround for AsyncPath.walk() in the library. error RuntimeWarning: coroutine '...' was never awaited ↓
cause You called an asynchronous method on an `AsyncPath` object (e.g., `my_path.exists()`) but forgot to `await` its result.
fix
Ensure all I/O-performing methods of
AsyncPath are properly awaited, like await my_path.exists() or await my_path.resolve(). Warnings
breaking Older `aiopath` versions (prior to 0.7.x) are incompatible with Python 3.11+ due to reliance on internal `pathlib` APIs that were removed, leading to `ImportError`. ↓
fix Upgrade `aiopath` to version `0.7.0` or higher to ensure compatibility with Python 3.11 and newer. For Python 3.12, version `0.7.6` or higher is recommended.
gotcha The `AsyncPath.walk()` method, as of some versions, may incorrectly return a synchronous generator, causing a `TypeError` when used with `async for`. ↓
fix Check for updates to `aiopath` that fix `AsyncPath.walk()` to return an `AsyncGenerator`. If not fixed, consider implementing a custom async walk or using `AsyncPath.iterdir()` for recursive traversal.
gotcha Calling asynchronous methods (e.g., `resolve()`, `exists()`, `read_text()`) on `AsyncPath` objects without `await` will result in a `RuntimeWarning` (coroutine '...' was never awaited) and the operation will not execute. ↓
fix Always prepend `await` to `AsyncPath` methods that perform I/O operations, such as `await my_path.exists()` or `await my_path.read_text()`.
Imports
- AsyncPath
from aiopath import AsyncPath
Quickstart
import asyncio
from aiopath import AsyncPath
from pathlib import Path
import os
async def main():
# Ensure a directory for testing exists
test_dir = AsyncPath("aiopath_test_dir")
if await test_dir.exists():
await test_dir.rmdir()
await test_dir.mkdir()
file_path = test_dir / "my_async_file.txt"
content = "Hello, async world!\nThis is a test."
# Write text asynchronously
await file_path.write_text(content)
print(f"Wrote to {file_path.name}:")
# Read text asynchronously
read_content = await file_path.read_text()
print(f"Read from {file_path.name}:\n---\n{read_content}--- ")
# Check if file exists and is a file
print(f"Does {file_path.name} exist? {await file_path.exists()}")
print(f"Is {file_path.name} a file? {await file_path.is_file()}")
# Clean up
await file_path.unlink()
await test_dir.rmdir()
print(f"Cleaned up {file_path.name} and {test_dir.name}.")
if __name__ == "__main__":
asyncio.run(main())