Astral Toolchain¶
The Astral toolchain provides Rust-based replacements for the traditional Python validation stack. Where pip, Flake8, Pylint, and mypy each take seconds to run, the Astral equivalents finish in milliseconds.
Package Management: uv¶
uv installs dependencies 10-100x faster than pip. A uv pip install that takes 50ms lets an agent freely add packages mid-task. The same operation with pip taking 5 seconds makes the agent hesitate to install anything.
# Install a package
uv pip install requests
# Sync from pyproject.toml
uv sync
# Install from requirements file
uv pip install -r requirements.txt --no-interaction
uv also handles virtual environments and Python version management:
# Create a virtual environment with a specific Python version
uv venv --python 3.12
# Install a Python version
uv python install 3.12
Linting and Formatting: Ruff¶
Ruff runs 10-100x faster than Flake8 and Pylint combined. Most files lint in under 100ms.
# Check for issues
ruff check .
# Fix auto-fixable issues
ruff check --fix .
# Format code (replaces Black)
ruff format .
# Check and format in one pass
ruff check --fix . && ruff format .
Ruff replaces multiple tools
Ruff handles what previously required Flake8, Pylint, isort, and Black. One tool, one config.
For agent workflows, use machine-readable output:
# GitHub Actions format (one issue per line)
ruff check --output-format=github .
# JSON for programmatic parsing
ruff check --output-format=json .
Type Checking: ty¶
Astral's ty (announced early 2025) runs 10-60x faster than mypy. A 30-second mypy run becomes 1-2 seconds.
# Type check the current directory
ty check
# Type check specific files
ty check src/main.py src/utils.py
ty aims for mypy compatibility while dramatically improving speed. The faster feedback loop lets agents catch type errors immediately after each edit rather than waiting for a full type-check pass. The library is still fairly new, so you may need to stick to mypy depending on your usecase.
Unified Configuration¶
All three tools read from pyproject.toml:
[tool.ruff]
line-length = 88
target-version = "py312"
[tool.ruff.lint]
select = ["E", "F", "I", "UP"]
ignore = ["E501"]
[tool.ruff.format]
quote-style = "double"
[tool.ty]
python-version = "3.12"
This consolidation means one file to maintain instead of .flake8, .pylintrc, pyproject.toml for Black, and mypy.ini.
Agent Workflow Example¶
A typical Python validation hook:
{
"hooks": {
"PostToolUse": [
{
"matcher": { "tool_name": "edit", "file_path": "**/*.py" },
"command": "ruff check --fix $FILE_PATH && ruff format $FILE_PATH"
}
]
}
}
This auto-fixes lint issues and formats the file after every Python edit.