{"id":236,"library":"ruff","title":"Ruff","description":"Extremely fast Python linter and formatter written in Rust by Astral. Current version is 0.15.7. Two separate subcommands: ruff check (linting, replaces Flake8/isort/pyupgrade) and ruff format (formatting, replaces Black). Not a Python library to import — CLI tool only. The format setting and RUFF_FORMAT env var were repurposed/removed; use output-format and RUFF_OUTPUT_FORMAT instead. 2026 style guide introduced in 0.15.0 changes lambda formatting.","status":"active","version":"0.15.7","language":"python","source_language":"en","source_url":"https://docs.astral.sh/ruff/","tags":["linting","formatting","code-quality","flake8","black","isort","astral","rust"],"install":[{"cmd":"uv tool install ruff@latest","lang":"bash","label":"Via uv (recommended — system-wide)"},{"cmd":"uv add --dev ruff","lang":"bash","label":"Add to project as dev dependency"},{"cmd":"pip install ruff","lang":"bash","label":"Via pip"},{"cmd":"pipx install ruff","lang":"bash","label":"Via pipx (isolated)"}],"dependencies":[],"imports":[{"note":"ruff is a CLI tool only. Configure via pyproject.toml [tool.ruff] or ruff.toml. Two subcommands: ruff check for linting, ruff format for formatting.","wrong":"import ruff  # ModuleNotFoundError — ruff is a CLI tool\nfrom ruff import check  # ModuleNotFoundError","symbol":"ruff (CLI)","correct":"# ruff is a CLI tool — not a Python library to import\n# Two separate subcommands:\n\n# Linting (replaces flake8, isort, pyupgrade, etc.)\nruff check .                  # lint all files\nruff check . --fix            # lint and auto-fix safe issues\nruff check . --unsafe-fixes   # also apply unsafe fixes\n\n# Formatting (replaces Black)\nruff format .                 # format all files\nruff format . --check         # check only, no changes\n\n# Configuration in pyproject.toml:\n# [tool.ruff]\n# line-length = 88\n# [tool.ruff.lint]\n# select = [\"E\", \"F\", \"B\", \"I\"]\n# [tool.ruff.format]\n# quote-style = \"double\""}],"quickstart":{"code":"# Install\npip install ruff\n\n# Lint all Python files in current directory\nruff check .\n\n# Lint with auto-fix\nruff check . --fix\n\n# Format all Python files\nruff format .\n\n# Check formatting without modifying (for CI)\nruff format . --check\n\n# Minimal pyproject.toml config\n# [tool.ruff]\n# line-length = 88\n# target-version = \"py311\"\n#\n# [tool.ruff.lint]\n# select = [\"E\", \"F\", \"B\", \"I\", \"UP\"]\n# ignore = [\"E501\"]\n#\n# [tool.ruff.format]\n# quote-style = \"double\"\n# indent-style = \"space\"\n\n# Pre-commit hook (pin the version!)\n# - repo: https://github.com/astral-sh/ruff-pre-commit\n#   rev: v0.15.7\n#   hooks:\n#     - id: ruff-check\n#       args: [--fix]\n#     - id: ruff-format","lang":"bash","description":"ruff check for linting, ruff format for formatting. Configure in pyproject.toml [tool.ruff]."},"warnings":[{"fix":"Replace [tool.ruff] format = 'json' with [tool.ruff] output-format = 'json'. Replace RUFF_FORMAT=json with RUFF_OUTPUT_FORMAT=json.","message":"The format setting in [tool.ruff] was repurposed: it no longer controls CLI output format. Use output-format instead. The RUFF_FORMAT env var was removed — use RUFF_OUTPUT_FORMAT. Old configs using format = 'json' to get JSON output are silently broken.","severity":"breaking","affected_versions":">= 0.2.0"},{"fix":"Run ruff format . after upgrading to reformat under the 2026 style guide. Review diffs carefully, especially for lambdas as function arguments.","message":"2026 style guide (introduced in 0.15.0) changes lambda formatting — lambda bodies are now parenthesized instead of breaking parameters across lines. Reformatting existing code will produce diffs.","severity":"breaking","affected_versions":">= 0.15.0"},{"fix":"If you relied on build/ being excluded, add it explicitly: [tool.ruff] extend-exclude = ['build']","message":"build/ directory no longer excluded by default. Previously ruff excluded build/, which caused confusion when projects had a legitimate build/ directory. Now build/ is only excluded if in .gitignore or extend-exclude.","severity":"breaking","affected_versions":">= 0.4.0"},{"fix":"Use both subcommands. In pre-commit: - id: ruff-check then - id: ruff-format. ruff-check must come BEFORE ruff-format when using --fix.","message":"ruff check and ruff format are separate subcommands — running ruff check does NOT format code. Need both: ruff check --fix && ruff format. In pre-commit, two separate hooks are needed: ruff-check and ruff-format.","severity":"gotcha","affected_versions":"all"},{"fix":"Add to [tool.ruff.lint]: select = ['E', 'F', 'B', 'I', 'UP', 'RUF']. Or use select = ['ALL'] with specific ignores.","message":"Ruff only enables F (Pyflakes) and a subset of E (pycodestyle) rules by default. Common rules like isort (I), bugbear (B), pyupgrade (UP) must be explicitly selected. Not specifying select means most linting power is unused.","severity":"gotcha","affected_versions":"all"},{"fix":"Replace ruff check --format json with ruff check --output-format json.","message":"--format flag on ruff check and ruff linter was renamed to --output-format. Using --format raises an error.","severity":"gotcha","affected_versions":">= 0.2.0"},{"fix":"Execute `pip install ruff` directly in your shell environment or, if running from a Python script, use `subprocess.run(['pip', 'install', 'ruff'], check=True)`.","message":"The command 'pip install ruff' was executed as Python code, leading to a SyntaxError. Pip commands should be run directly in the shell or via a subprocess call, not as part of a Python script.","severity":"gotcha","affected_versions":"all"},{"fix":"To execute shell commands like `pip install ruff` from within a Python script, use `import subprocess; subprocess.run(['pip', 'install', 'ruff'])` or `import os; os.system('pip install ruff')`.","message":"Running shell commands (like `pip install`) directly within a Python script will raise a `SyntaxError: invalid syntax`. Python interprets such lines as invalid Python code rather than shell commands.","severity":"gotcha","affected_versions":"all"}],"env_vars":null,"last_verified":"2026-05-12T12:10:35.321Z","next_check":"2026-06-27T00:00:00.000Z","problems":[{"fix":"Replace `format = \"...\"` with `output-format = \"...\"` in your Ruff configuration file.","cause":"The `format` configuration option in `ruff.toml` (or `pyproject.toml`) was removed in Ruff 0.0.267 and replaced by `output-format` to avoid confusion with the `ruff format` command.","error":"Unknown configuration option: `format`"},{"fix":"Change the string value to a list of strings. For example, `select = \"E,F\"` should become `select = [\"E\", \"F\"]`.","cause":"Configuration options like `select`, `ignore`, or `extend-select` expect a TOML array (list of strings) but received a single string.","error":"Error: Invalid configuration file pyproject.toml: invalid type: string, expected a sequence for key `select`"},{"fix":"Do not attempt to import `ruff` in Python code. To use Ruff, execute it as a command from your terminal (e.g., `ruff check .` or `ruff format .`).","cause":"Ruff is a standalone command-line interface (CLI) tool written in Rust, not a Python library intended for direct `import` within Python scripts.","error":"ModuleNotFoundError: No module named 'ruff'"},{"fix":"Consult the Ruff documentation for a list of valid lint codes and adjust your configuration (e.g., `pyproject.toml`, `ruff.toml`, or command-line arguments) to use correct codes.","cause":"The specified lint code (e.g., `E9999`) does not exist or is not recognized by Ruff. This often happens when migrating from other linters or due to typos.","error":"error: Unknown lint code: E9999"}],"ecosystem":"pypi","meta_description":null,"install_score":80,"install_tag":"verified","quickstart_score":0,"quickstart_tag":"stale","pypi_latest":null,"install_checks":{"last_tested":"2026-05-12","tag":"verified","tag_description":"installs cleanly on critical runtimes, fast import, recently tested","results":[{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":"17.8M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":"18M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":"19.7M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":"20M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":"11.6M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":"12M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":"11.2M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":"12M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":"17.3M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":"18M"}]},"quickstart_checks":{"last_tested":"2026-04-23","tag":"stale","tag_description":"widespread failures or data too old to trust","results":[{"runtime":"python:3.10-alpine","exit_code":1},{"runtime":"python:3.10-slim","exit_code":1},{"runtime":"python:3.11-alpine","exit_code":1},{"runtime":"python:3.11-slim","exit_code":1},{"runtime":"python:3.12-alpine","exit_code":1},{"runtime":"python:3.12-slim","exit_code":1},{"runtime":"python:3.13-alpine","exit_code":1},{"runtime":"python:3.13-slim","exit_code":1},{"runtime":"python:3.9-alpine","exit_code":1},{"runtime":"python:3.9-slim","exit_code":1}]}}