Что такое Ruff и зачем он нужен
Ruff — один инструмент вместо пяти. Линтер, форматировщик и замена целого зоопарка Python-утилит.
Что такое Ruff
Ruff — это линтер и форматировщик для Python, написанный на Rust. Он проверяет код на соответствие стандартам, находит ошибки и форматирует файлы — и всё это в 10–100 раз быстрее, чем аналогичные Python-инструменты.
Ruff реализует правила из более чем 50 популярных плагинов и линтеров в одном бинарнике без единой внешней зависимости. Это означает, что вам больше не нужно устанавливать flake8, black, isort, pyupgrade, autoflake и десятки плагинов по отдельности — один pip install ruff заменяет всё.
Будучи написанным на Rust, Ruff компилируется в нативный машинный код, который работает без интерпретатора и сборщика мусора. Это даёт ему колоссальное преимущество в скорости перед инструментами, написанными на Python. Помимо скорости, Ruff предлагает первоклассную интеграцию с редакторами кода через Language Server Protocol (LSP), встроенное кеширование для повторных запусков, параллельную обработку файлов и полную совместимость с конфигурацией через pyproject.toml.
Ruff — это проект компании Astral, основанной Чарли Маршем. Та же компания создала uv — сверхбыстрый менеджер пакетов для Python, который также написан на Rust. Экосистема Astral стремится переосмыслить инструментарий Python-разработчика, делая его быстрее, надёжнее и удобнее.
Первая стабильная версия Ruff (0.0.0) была выпущена в августе 2022 года, и уже к концу 2023 года проект насчитывал более 15 000 звёзд на GitHub и использовался тысячами организаций по всему миру. К 2025 году Ruff стал стандартом де-факто для линтинга и форматирования Python-кода, заменив legacy-инструменты в большинстве современных проектов.
Что Ruff заменяет
Ruff — это не просто ещё один инструмент. Это консолидация целой экосистемы в один бинарник. Вот список того, что Ruff заменяет «из коробки»:
flake8
→
Линтинг стиля кода (PEP 8), неиспользуемые импорты, логические ошибки
black
→
Автоматическое форматирование кода
isort
→
Сортировка и группировка импортов
pyupgrade
→
Обновление синтаксиса до современного Python
autoflake
→
Автоматическое удаление неиспользуемого кода
bandit
→
Проверка на уязвимости безопасности
pydocstyle
→
Проверка docstring-ов
50+ плагинов
→
flake8-bugbear, pep8-naming, flake8-docstrings и другие
Каждый из перечисленных инструментов требует отдельной установки, отдельной конфигурации и отдельного запуска. Ruff объединяет их в одной команде. Вот наглядное сравнение: чтобы покрыть ту же функциональность без Ruff, вам потребуется установить 5–10 разных пакетов, согласовать их конфигурации (а они часто конфликтуют!), и запускать их последовательно — что занимает в десятки раз больше времени.
Полный список правил и их источников
На момент написания курса Ruff поддерживает более 900 встроенных правил, разделённых на категории. Каждая категория соответствует определённому плагину или источнику:
| Префикс | Источник | Описание |
|---|---|---|
E/W | pycodestyle | Ошибки и предупреждения стиля PEP 8 |
F | Pyflakes | Логические ошибки: неиспользуемые импорты, неопределённые переменные |
I | isort | Порядок и группировка импортов |
N | pep8-naming | Именование: CamelCase, snake_case, UPPER_CASE |
UP | pyupgrade | Современный синтаксис Python |
B | flake8-bugbear | Распространённые баги |
S | flake8-bandit | Проверка безопасности |
SIM | flake8-simplify | Упрощение кода |
D | pydocstyle | Стиль документации |
RUF | Ruff-specific | Уникальные правила Ruff |
Почему Ruff такой быстрый
Скорость Ruff — не маркетинговая уловка, а результат архитектурных решений. Давайте разберём их подробно.
1. Написан на Rust
Rust — компилируемый язык системного программирования без сборщика мусора и без накладных расходов на интерпретацию. Ruff компилируется в один бинарник (ELF/PE/Mach-O), который запускается напрямую процессором. Для сравнения: flake8 написан на Python и при каждом запуске интерпретатор Python загружает и парсит исходный код flake8, его зависимости и плагины — это занимает больше времени, чем сам анализ!
2. Параллельная обработка
Ruff использует многопоточность для параллельной проверки файлов. В то время как flake8 обрабатывает файлы последовательно (один за другим), Ruff распределяет файлы по нескольким потокам, используя все доступные ядра процессора. На 8-ядерной машине Ruff может проверять 8 файлов одновременно.
3. Кеширование
Ruff сохраняет результаты анализа в кеше. При повторном запуске он проверяет, изменился ли файл (по времени модификации и содержимому). Если файл не изменился — Ruff пропускает его и использует закешированный результат. На практике второй и последующие запуски Ruff на том же проекте выполняются за миллисекунды.
4. Один процесс вместо пяти
Без Ruff типичный пайплайн «проверка кода» выглядит так: запустить flake8 (3 секунды), запустить black --check (2 секунды), запустить isort --check (1 секунда), запустить pyupgrade (0.5 секунды), запустить bandit (2 секунды). Итого ~8.5 секунд. И каждый инструмент загружает свой интерпретатор Python. Ruff делает всё это в одном процессе за доли секунды.
5. Эффективные структуры данных
Ruff использует AST (Abstract Syntax Tree) и трюки с zero-copy парсингом. Вместо того чтобы строить несколько разных представлений кода для разных правил, Ruff строит одно и прогоняет все правила по нему. Современные алгоритмы обхода дерева и кеширование поддеревьев дают дополнительный прирост.
Вот как выглядят бенчмарки на CPython (данные с официального репозитория Ruff):
| Инструмент | Время | Относительно Ruff |
|---|---|---|
| Ruff | ~0.5 с | 1x |
| flake8 | ~30 с | ~60x медленнее |
| Black | ~10 с | ~20x медленнее |
| pylint | ~120 с | ~240x медленнее |
Для кого этот курс
Этот курс подойдёт:
- Начинающим Python-разработчикам — вы узнаете современные best practices по поддержке чистоты кода с самого начала.
- Опытным разработчикам — которые устали от медленных flake8 и black и хотят перейти на Ruff.
- DevOps-инженерам — которые настраивают CI/CD и хотят добавить молниеносную проверку кода в пайплайны.
- Тимлидам — которые ищут единый стандарт форматирования и линтинга для команды.
- Мейнтейнерам open-source проектов — Ruff используется тысячами проектов, и знание его настройки критически важно.
Что вы узнаете на курсе
- Устанавливать и запускать Ruff
- Настраивать линтинг через select/ignore
- Форматировать код через ruff format
- Интегрировать Ruff в pre-commit, CI/CD и редакторы
- Мигрировать с flake8, black, isort на Ruff
- Настраивать Ruff для больших проектов и монорепозиториев
Экосистема Astral
Ruff — часть экосистемы инструментов от Astral. Помимо Ruff, компания разрабатывает:
- uv — менеджер пакетов и проектов для Python, написанный на Rust. Замена pip, pip-tools, virtualenv, poetry. В 10–100 раз быстрее pip.
- ty — инструмент для работы с типами, следующий шаг эволюции mypy и pyright.
Эти инструменты объединяет общая философия: Rust, скорость, нулевая конфигурация «из коробки» и отличная совместимость с существующей экосистемой Python.
Ruff в цифрах
Кто уже использует Ruff
Ruff принят в самых крупных и требовательных проектах Python-экосистемы:
- Apache Airflow — платформа для оркестрации рабочих процессов
- Apache Superset — BI-платформа для визуализации данных
- FastAPI — современный веб-фреймворк
- Pandas — библиотека для анализа данных
- SciPy — научные вычисления
- Hugging Face Transformers — NLP-библиотека
- Dagster — платформа для data orchestration
- Zulip — open-source чат для команд
- Bokeh — визуализация данных
- Delta Lake — storage layer для озёр данных
И тысячи других проектов. Ruff — это не экспериментальный инструмент, а проверенное решение, используемое в production буквально миллионами разработчиков.
Архитектура Ruff
Чтобы понять, почему Ruff настолько быстр, полезно разобраться в его внутренней архитектуре. В отличие от большинства Python-инструментов, которые построены как набор плагинов, загружаемых во время выполнения, Ruff использует совершенно иной подход.
Единый AST вместо цепочки плагинов
Flake8 работает по принципу загрузки плагинов: каждый плагин — это отдельный Python-модуль, который импортируется, инициализируется и запускается. Каждый плагин строит свой собственный AST (Abstract Syntax Tree) или обходит уже построенный. При 20 плагинах это 20 инициализаций и 20 обходов дерева. Ruff же строит AST один раз и прогоняет по нему все правила в одном проходе. Это даёт выигрыш в 10–50 раз только за счёт устранения дублирования.
Zero-copy парсинг
Ruff использует технику zero-copy parsin во многих местах. Вместо того чтобы копировать строки из исходного файла в отдельные строковые буферы, Ruff работает с исходным кодом через указатели и срезы. Это означает, что для анализа файла размером 1 МБ Ruff не выделяет 1 МБ дополнительной памяти — он работает напрямую с содержимым файла, отображая его в память через mmap.
Кеширование на уровне файлов
Кеш Ruff построен на основе хешей содержимого файлов (SHA-256). При первом запуске Ruff вычисляет хеш каждого файла и сохраняет результаты анализа. При повторном запуске Ruff проверяет хеш: если файл не изменился — результаты берутся из кеша. Кеш хранится в директории .ruff_cache и автоматически очищается при изменении конфигурации. Это особенно важно в CI-среде, где повторные запуски на тех же файлах — обычное дело.
Параллелизм через многопоточность
Ruff использует пул потоков (thread pool) для параллельной обработки файлов. Количество потоков по умолчанию равно количеству логических ядер процессора. Это означает, что на современном 8-ядерном процессоре Ruff проверяет 8 файлов одновременно. В отличие от многопроцессорности (multiprocessing), многопоточность в Rust не имеет проблем с GIL (Global Interpreter Lock), так как Rust не использует GIL. Это даёт практически линейное ускорение: на 8 ядрах Ruff работает примерно в 8 раз быстрее, чем на одном.
Алгоритмы и структуры данных
Ruff использует современные алгоритмы и структуры данных из экосистемы Rust. Например, для хранения множеств нарушений используется битовая маска (bitmask) вместо хеш-множества — это в десятки раз быстрее на операциях вставки и проверки. Для обхода AST используется итеративный подход с ручным управлением стеком вместо рекурсии — это устраняет риск переполнения стека на глубоко вложенных файлах и ускоряет обход за счёт локальности данных.
История Ruff и его создатели
Ruff был создан Чарли Маршем (Charlie Marsh) в 2022 году. До Ruff Чарли работал в сфере финансового ПО, но в свободное время экспериментировал с инструментарием для Python. Идея Ruff родилась из frustration: существующие инструменты были слишком медленными для больших проектов.
Первый публичный релиз Ruff состоялся 30 августа 2022 года. Уже к октябрю 2022 года проект собрал 5000 звёзд на GitHub. К концу 2022 года — 10 000 звёзд. В феврале 2023 года Чарли объявил о создании компании Astral и привлечении инвестиций в размере $4.5 млн от ведущих венчурных фондов. Основная цель компании — создание быстрых инструментов для Python на Rust.
В ноябре 2023 года Astral привлекла ещё $12 млн, а к 2024 году команда выросла до 20+ инженеров. В 2024 году Astral выпустила uv — менеджер пакетов для Python, который стал самым быстрорастущим инструментом в истории Python-экосистемы. Сам Ruff к этому моменту использовался в тысячах организаций и считался стандартом де-факто для линтинга Python.
Ключевые даты в истории Ruff:
- Август 2022 — первый публичный релиз Ruff 0.0.0
- Октябрь 2022 — 5000 звёзд на GitHub
- Февраль 2023 — основание Astral, $4.5 млн инвестиций
- Октябрь 2023 — Ruff 1.0 (стабилизация API)
- Ноябрь 2023 — $12 млн дополнительных инвестиций
- 2024 — uv, 20+ сотрудников, стандарт де-факто
- 2025 — ty (инструмент для типов), интеграции, preview-режим
Ruff vs традиционный подход
Вот как выглядит типичный процесс настройки качества кода без Ruff:
Традиционный подход (без Ruff)
- Установить flake8 + 10 плагинов (flake8-bugbear, flake8-bandit и т.д.)
- Установить black для форматирования
- Установить isort для сортировки импортов
- Установить pyupgrade для обновления синтаксиса
- Настроить каждый инструмент в отдельном конфиге (либо в .flake8, либо в black.toml, либо в setup.cfg, либо в pyproject.toml — у всех разный синтаксис!)
- Запускать их последовательно: flake8 && black --check && isort --check
- Ждать 10–30 секунд на каждый запуск
С Ruff
- pip install ruff (один пакет)
- Настроить в pyproject.toml (один раздел, единый синтаксис)
- Запустить ruff check && ruff format (одна или две команды)
- Получить результат за 0.1–0.5 секунд
Разница в процессе настройки и поддержки колоссальна. С Ruff вы тратите минуты, а не часы на конфигурацию, и секунды, а не минуты на ожидание.
| Характеристика | Без Ruff | С Ruff |
|---|---|---|
| Количество зависимостей | 15–30 | 1 (ruff) |
| Конфигурационных файлов | 2–5 | 1 (pyproject.toml) |
| Время первого запуска (100K файлов) | 30–60 с | 0.2–0.5 с |
| Время повторного запуска | 30–60 с | 0.05–0.1 с (кеш) |
| Сложность настройки | Высокая | Низкая |
| Риск конфликтов плагинов | Высокий | Минимальный |
Ruff в действии — отзывы из сообщества
Вот что говорят о Ruff создатели популярных инструментов и разработчики из ведущих компаний:
Sebastián Ramírez — создатель FastAPI
«Ruff настолько быстр, что иногда я намеренно добавляю баг в код, чтобы убедиться, что он вообще запускается и проверяет код».
Nick Schrock — сооснователь GraphQL, создатель Dagster
«Почему Ruff меняет правила игры? Потому что он почти в 1000 раз быстрее. Буквально. Не опечатка. На нашем самом большом модуле (250K строк) pylint занимает 2.5 минуты. Ruff проверяет всю кодовую базу за 0.4 секунды».
Timothy Crosley — создатель isort
«Только что переключил свой первый проект на Ruff. Единственный минус: он настолько быстр, что я не мог поверить, что он работает, пока намеренно не ввёл несколько ошибок».
Что дальше
В следующем уроке мы установим Ruff и убедимся, что он работает. А пока — вот ключевые выводы из этого урока:
📌 Что важно запомнить:
- Ruff — линтер + форматировщик в одном бинарнике на Rust
- Заменяет flake8, black, isort, pyupgrade, autoflake, bandit и 50+ плагинов
- Работает в 10–100 раз быстрее аналогов
- Используется в FastAPI, Pandas, Airflow и тысячах других проектов
- Создан и поддерживается компанией Astral
Урок 1.1: Что такое Ruff и зачем он нужен
5 вопросов