Содержание
Ruff и другие линтеры на Python: что это и их роль в написании кода
Черновик готовит редакция с помощью ИИ. За стандарт издания отвечает главный редактор — Валерий Курземнек.
Ruff — это чрезвычайно быстрый линтер и форматтер кода для Python, написанный на языке Rust компанией Astral. Один инструмент заменяет связку из Flake8, Black, isort, pyupgrade и десятков плагинов, выполняя ту же работу в разы быстрее. Ruff проверяет код на ошибки и стиль и умеет исправлять их автоматически.
Что такое линтер и зачем он нужен
Линтер — это инструмент статического анализа исходного кода. Он читает программу, не запуская её, и сверяет с набором правил: ищет ошибки, нарушения стиля и подозрительные конструкции, которые снижают читаемость, надёжность и поддерживаемость кода. Типичные находки линтера:
- потенциальные баги — неиспользуемые переменные, недостижимый код, обращение к необъявленным именам;
- отклонения от PEP 8 — стандарта оформления кода на Python;
- устаревшие конструкции, которые стоит переписать под современный синтаксис.
Форматтер решает смежную задачу: он приводит код к единому стилю оформления (отступы, кавычки, переносы строк), убирая споры о форматировании из код-ревью. Раньше линтинг и форматирование в Python закрывали разными утилитами. Ruff объединяет обе роли в одном бинарнике.
Линтеры Python до Ruff
Экосистема Python много лет опиралась на набор специализированных инструментов, каждый из которых закрывал свою часть задачи:
- Pylint — глубокий статический анализ: стиль, корректность и потенциальные ошибки. Мощный, но медленный.
- Flake8 — обёртка над pyflakes, pycodestyle и mccabe. Проверяет соответствие PEP 8 и расширяется плагинами.
- Black — бескомпромиссный автоформаттер, приводящий код к единому виду.
- isort — сортировка и группировка импортов.
- Mypy — проверка аннотаций типов.
Проблема этого набора — производительность и разрозненность конфигурации. На больших проектах прогон нескольких утилит подряд занимает заметное время, а настройки приходится держать в разных файлах. Именно эту боль и закрывает Ruff.
Ruff — самый быстрый линтер на Python
Ruff — линтер и форматтер Python, написанный на Rust. По собственной формулировке проекта, он «в 10–100 раз быстрее существующих линтеров (вроде Flake8) и форматтеров (вроде Black)». Скорость достигается за счёт нативной реализации на Rust, распараллеливания и встроенного кэширования: Ruff не анализирует повторно те файлы, которые не менялись.
Наглядную иллюстрацию скорости приводил Ник Шрок, основатель Elementl и соавтор GraphQL:
«На нашем самом большом модуле Pylint занимает около 2.5 минут, распараллеленный на 4 ядра на моём M1. Запуск Ruff для всей нашей кодовой базы занимает 0.4 секунды».
Скорость — не единственное достоинство. Ruff предлагает более 900 встроенных правил, включая нативные переработки популярных плагинов Flake8, и умеет автоматически исправлять значительную часть находок. Правила сгруппированы по инструменту-источнику и обозначаются префиксами: E/W — pycodestyle, F — Pyflakes, I — isort, UP — pyupgrade, B — flake8-bugbear. Благодаря этому Ruff заменяет сразу несколько инструментов — Flake8 с плагинами, Black, isort, pydocstyle, pyupgrade, autoflake — упрощая цепочку разработки и снижая её общую сложность.

Установка Ruff
Самый простой способ — установить Ruff из PyPI через pip:
pip install ruff
На macOS и Linux можно использовать автономный установщик, не требующий Python в системе:
curl -LsSf https://astral.sh/ruff/install.sh | sh
Если вы работаете с менеджером пакетов uv от той же Astral, Ruff подключается как обычная dev-зависимость. После установки проверьте версию:
ruff --version
Базовые команды: ruff check и ruff format
У Ruff две основные подкоманды. Линтинг запускается через ruff check — он проверяет все файлы в текущем каталоге и вложенных папках:
ruff check .
Чтобы Ruff не только нашёл, но и автоматически исправил безопасные проблемы, добавьте флаг --fix:
ruff check --fix .
Форматирование кода (аналог Black) выполняет подкоманда ruff format:
ruff format .
В CI-пайплайне удобно проверять форматирование без изменения файлов — команда завершится с ошибкой, если код отформатирован неправильно:
ruff format --check .
Настройка через pyproject.toml
Ruff настраивается в файле pyproject.toml (либо в отдельном ruff.toml). Глобальные параметры задаются в секции [tool.ruff], набор правил — в [tool.ruff.lint], а поведение форматтера — в [tool.ruff.format]. Правила выбираются по префиксу: select = ["E"] включает все правила pycodestyle.
[tool.ruff]
line-length = 88
target-version = "py310"
exclude = [".git", ".venv", "build", "dist"]
[tool.ruff.lint]
select = ["E4", "E7", "E9", "F", "I"]
ignore = []
fixable = ["ALL"]
[tool.ruff.lint.per-file-ignores]
"__init__.py" = ["E402"]
[tool.ruff.format]
quote-style = "double"
indent-style = "space"
Секция per-file-ignores позволяет отключать конкретные правила для отдельных файлов — например, разрешить импорты не в начале файла в __init__.py. Отдельную строку можно исключить из проверки комментарием # noqa.
Ruff против Flake8, Pylint и Black
Ключевое отличие Ruff — он совмещает роли, которые раньше делили между собой три-четыре утилиты, и делает это заметно быстрее.
| Критерий | Ruff | Flake8 | Pylint | Black |
|---|---|---|---|---|
| Язык реализации | Rust | Python | Python | Python |
| Роль | Линтер + форматтер | Линтер | Линтер | Форматтер |
| Скорость | Очень высокая | Средняя | Низкая | Средняя |
| Автоисправление | Да | Нет | Частично | Да (форматирование) |
| Форматирование | Встроено | Нет | Нет | Да |
| Сортировка импортов | Встроено | Плагин | Нет | Нет |
| Конфигурация | pyproject.toml | setup.cfg / .flake8 | .pylintrc | pyproject.toml |
Большинство кодов правил Flake8 (например, E501, F401) напрямую сопоставляются с правилами Ruff, а форматтер выдаёт результат, близкий к Black. Это делает миграцию на Ruff несложной: чаще всего достаточно перенести список правил в pyproject.toml и удалить старые зависимости.
Интеграция в рабочий процесс
Ruff встраивается в редакторы и CI. Для разных IDE и редакторов кода существуют официальные расширения — например, для VS Code проверки и автоформат срабатывают прямо при сохранении файла. В командной работе Ruff обычно подключают как хук pre-commit, чтобы линтинг и форматирование выполнялись автоматически перед каждым коммитом, а также запускают в CI-пайплайне отдельным шагом.
Зрелость инструмента подтверждают его пользователи: Ruff применяют такие проекты, как Apache Airflow, FastAPI, Hugging Face, Pandas и SciPy. Исходный код и трекер задач открыты на GitHub.
Часто задаваемые вопросы
Ruff — это линтер или форматтер?
И то, и другое. Ruff совмещает роль линтера (поиск ошибок и нарушений стиля через ruff check) и форматтера кода (ruff format, аналог Black). Одна утилита закрывает обе задачи.
Может ли Ruff полностью заменить Flake8 и Black?
В большинстве проектов — да. Ruff воспроизводит функциональность Flake8 с плагинами, isort и Black. Коды правил Flake8 напрямую переносятся, а форматтер выдаёт результат, близкий к Black с минимальными отличиями в краевых случаях.
Почему Ruff такой быстрый?
Ruff написан на Rust, обрабатывает файлы параллельно и агрессивно кэширует результаты, не анализируя повторно неизменённые файлы. По оценке проекта, он в 10–100 раз быстрее инструментов, написанных на Python.
Как установить Ruff?
Проще всего командой pip install ruff. На macOS и Linux также доступен автономный установщик curl -LsSf https://astral.sh/ruff/install.sh | sh.
Заменяет ли Ruff проверку типов Mypy?
Нет. Ruff — линтер и форматтер, он не выполняет полноценную проверку типов. Для статической типизации по-прежнему нужен Mypy или отдельный тайп-чекер.
