Ruff is an extremely fast Python linter and formatter, written in Rust. It combines the functionality of many Python linting and formatting tools into a single, high-performance package.
Ruff provides:
- Linting capabilities similar to flake8, pylint, and many other linters
- Code formatting similar to black
- Import sorting similar to isort
- Automatic code fixes for many issues
- Extensible rule system with over 700 built-in rules
- Blazing fast performance (10-100x faster than other tools)
Ruff is included as a development dependency:
# Install with other development dependencies
uv sync --devTo install it directly:
uv pip install ruffIn this project, Ruff is used for:
- Linting Python code to catch errors and enforce style
- Formatting code to maintain consistent style
- Sorting imports
- Automatically fixing common issues
- Running as part of the pre-commit hooks and CI/CD pipeline
Ruff is configured in the pyproject.toml file:
[tool.ruff]
exclude = [
".bzr",
".direnv",
".eggs",
".git",
".git-rewrite",
".hg",
".ipynb_checkpoints",
".mypy_cache",
".nox",
".pants.d",
".pyenv",
".pytest_cache",
".pytype",
".ruff_cache",
".svn",
".tox",
".venv",
".vscode",
"__pypackages__",
"_build",
"buck-out",
"build",
"dist",
"node_modules",
"site-packages",
"venv",
"__init__.py",
]
fix = true
line-length = 120
src = ["src"]
target-version = "py311"
[tool.ruff.format]
docstring-code-format = true
docstring-code-line-length = "dynamic"
indent-style = "space"
line-ending = "auto"
quote-style = "double"
skip-magic-trailing-comma = false
[tool.ruff.lint]
extend-ignore = [
"E203", # Not PEP8 compliant and black insert space around slice
"E501", # Line too long. Disable it to allow long lines of comments
"D401", # First line should be in imperative mood
"D203", # Removed incompatible rule (keep D211 instead)
"D213", # Removed incompatible rule (keep D212 instead)
"COM812", # Removed rule that may conflict with formatter
"F811", # Redefined variable from import
"ISC001",
"BLE001",
"PGH",
"C901", # Too complex
"PLR",
"TRY300",
]
extend-select = [
"ALL",
]
[tool.ruff.lint.per-file-ignores]
"__init__.py" = ["D104"] # Allow __init__.py stuff
"tests/**/*.py" = [
"S101",
"ARG001",
"FBT001",
] # Allow assert statements in tests, unused function arguments, and boolean positional argumentsRuff is also configured as poethepoet tasks:
[tool.poe.tasks]
ruff = "ruff check"
ruff-format = "ruff format"To run Ruff linter on the project:
# Run via poethepoet
uv run poe ruff-check
# Run directly
uv run ruff checkTo format code with Ruff:
# Run via poethepoet
uv run poe ruff-format
# Run directly
uv run ruff format# Check specific files or directories
uv run ruff check path/to/file.py
# Format specific files or directories
uv run ruff format path/to/file.py
# Fix issues automatically
uv run ruff check --fix
# Show error codes
uv run ruff check --show-fixes
# Select specific rule categories
uv run ruff check --select E,F,W
# Ignore specific rule categories
uv run ruff check --ignore E501,F401Ruff includes rules from many different linters, each with its own prefix:
E,F,W: flake8 errors, fatal errors, and warningsI: isort import sortingN: pep8-namingD: pydocstyleUP: pyupgradeB: flake8-bugbearC: flake8-comprehensionsSIM: flake8-simplifyARG: flake8-unused-argumentsPTH: flake8-use-pathlibERA: eradicatePD: pandas-vetPL: PylintTRY: tryceratopsRUF: Ruff-specific rules
And many more. See the Ruff documentation for a complete list.
- Run Ruff before committing: Use pre-commit hooks to run Ruff automatically.
- Use
--fixfor automatic fixes: Let Ruff fix simple issues automatically. - Customize rules for your project: Adjust the rule set to match your project's needs.
- Use per-file ignores for special cases: Some files may need different rules.
- Keep configuration in pyproject.toml: Centralize all tool configurations in one file.
- Update Ruff regularly: Newer versions often include performance improvements and new rules.
If you're getting too many errors when first adding Ruff:
- Start with a smaller rule set:
--select E,F,W - Gradually add more rules as you fix issues
- Use
--fixto automatically fix simple issues - Add specific ignores for rules that don't apply to your project
If Ruff conflicts with other tools:
- Consider replacing the other tools with Ruff
- Adjust Ruff's configuration to match the other tools
- Use per-file ignores to handle special cases
If Ruff is running slowly (which is rare):
- Exclude large directories that don't need linting
- Use a more specific file selection
- Update to the latest version of Ruff