$ sudo teach|
    $ sudo teach|
    IT school
  • Telegram
  • Партнёрам
  • Все курсы
$ sudo teach IT
OOO "SALEPROFIT"Контакты и реквизитыIT-Park Logo

Школа

  • Блог
  • Проверить сертификат

Сотрудничество

  • Стать учителем
  • Партнёрская программа
  • О проекте

Право

  • Оферта
  • Политика конфиденциальности

© 2023–2026 $ sudo teach IT™. All Rights Reserved. Public user contributions licensed under CC BY-SA 4.0 license with attribution required
TelegramGitHubYouTube
ГлавнаяБлогRuff против Flake8 и Black: почему стоит перейти на один инструмент

Ruff против Flake8 и Black: почему стоит перейти на один инструмент

$ sudo teach IT
·17 июля 2026 г.·8 мин·60
Ruff против Flake8 и Black: почему стоит перейти на один инструмент

Сравниваем популярные линтеры и форматтеры Python по скорости, гибкости настройки и удобству интеграции в CI. Показываем, как за пять минут подключить Ruff к реальному проекту.

Содержание
Что умеет каждый из инструментовFlake8BlackisortpylintRuff: что это такое и почему он такой быстрыйСравнение по ключевым параметрамСкоростьКонфигурацияАвтофиксСовместимость с BlackКак подключить Ruff к реальному проекту за пять минутШаг 1. УстановкаШаг 2. Базовая конфигурацияШаг 3. Первый запуск и автофиксШаг 4. Интеграция в pre-commitШаг 5. Интеграция в GitHub ActionsТипичные подводные камни при переходеКогда Ruff не заменит pylintЭкосистема и поддержкаВывод

Если вы работаете с Python дольше нескольких месяцев, у вас наверняка сложился привычный набор инструментов для поддержания качества кода: Flake8 проверяет стиль и ловит очевидные ошибки, Black форматирует всё по единому стандарту, isort расставляет импорты по правилам, pylint добавляет более глубокий анализ. Каждый инструмент делает своё дело хорошо — но вместе они превращаются в громоздкий стек с отдельными конфигурационными файлами, разными скоростями работы и периодическими конфликтами между собой.

В 2022 году Чарли Марш выпустил Ruff — линтер и форматтер, написанный на Rust, который претендует на замену всего этого зоопарка. За два года проект набрал более 35 тысяч звёзд на GitHub и был принят в production такими командами, как Astral, Pydantic, FastAPI и Hugging Face. Разберёмся, чем Ruff заслужил такое доверие и когда его действительно стоит использовать вместо привычных инструментов.


Что умеет каждый из инструментов

Прежде чем сравнивать, стоит честно зафиксировать, что именно делает каждый участник.

Flake8

Flake8 — это обёртка над тремя инструментами: pycodestyle (бывший pep8), pyflakes и mccabe. Он проверяет соответствие кода PEP 8, ловит неиспользуемые импорты, неопределённые переменные и считает цикломатическую сложность функций. Богатая экосистема плагинов (flake8-bugbear, flake8-comprehensions, flake8-annotations и десятки других) позволяет расширять проверки практически до бесконечности.

Главный минус — скорость. Flake8 написан на чистом Python и при анализе крупного проекта работает заметно медленно. На репозитории с 50 000 строк кода он легко тратит 10–15 секунд.

Black

Black позиционирует себя как «бескомпромиссный форматтер». Он не спрашивает мнения разработчика о том, как расставлять кавычки или переносить длинные строки — просто применяет единый стиль. Это одновременно его сила и слабость: конфигурировать практически нечего, зато в команде исчезают споры о форматировании.

Black работает быстро, но только форматирует — он не ловит логические ошибки, не проверяет импорты и не занимается анализом кода.

isort

isort сортирует импорты по группам (стандартная библиотека, сторонние пакеты, локальные модули) и внутри групп — по алфавиту. Звучит просто, но конфигурация isort нередко конфликтует с Black: у них разные представления о том, как должна выглядеть строка импорта после форматирования. Решение — флаг --profile black, но об этом нужно помнить и явно прописывать.

pylint

Pylint — самый тяжёлый из перечисленных. Он делает глубокий статический анализ: проверяет типы там, где может, ловит потенциальные ошибки в логике, анализирует наследование. За это платишь скоростью: pylint на том же проекте в 50 000 строк может работать минуту и более.


Ruff: что это такое и почему он такой быстрый

Ruff написан на Rust — это объясняет большую часть его преимуществ. Он не вызывает Python-интерпретатор для каждого файла, работает параллельно на всех ядрах процессора и использует эффективные структуры данных для хранения AST.

Но скорость — не единственное, что отличает Ruff. Ключевое архитектурное решение: авторы переписали правила из Flake8, flake8-bugbear, flake8-comprehensions, isort, pyupgrade и нескольких других инструментов прямо внутри Ruff. Это означает, что вместо пяти отдельных процессов вы запускаете один — и он делает всё то же самое.

На момент написания статьи Ruff реализует более 800 правил, охватывающих:

  • стиль PEP 8 (E, W серии)
  • pyflakes-проверки (F серия)
  • flake8-bugbear (B серия)
  • правила для аннотаций типов (ANN серия)
  • проверки безопасности из bandit (S серия)
  • правила isort (I серия)
  • и многое другое

Начиная с версии 0.1.0, Ruff также включает собственный форматтер, совместимый с Black по стилю вывода. Это означает, что теоретически можно убрать и Black из стека.


Сравнение по ключевым параметрам

Скорость

Это самый очевидный и измеримый параметр. Авторы Ruff публикуют бенчмарки на репозитории CPython (около 1 800 файлов):

ИнструментВремя (cold cache)
Flake8~16 с
pylint~60+ с
Ruff~0.3 с

Разница в 50–100 раз — не маркетинговое преувеличение. Это реально ощутимо в pre-commit хуках, когда вы хотите получить фидбек ещё до того, как успели отвлечься.

Конфигурация

Flake8 использует .flake8 или секцию [flake8] в setup.cfg. Black читает pyproject.toml. isort — отдельный [isort] блок. Ruff читает только pyproject.toml или ruff.toml, и все настройки собраны в одном месте.

Пример минимальной конфигурации в pyproject.toml:

code
[tool.ruff]
line-length = 88
target-version = "py311"

[tool.ruff.lint]
select = ["E", "F", "W", "B", "I", "UP"]
ignore = ["E501"]

[tool.ruff.lint.per-file-ignores]
"tests/**/*.py" = ["S101"]  # разрешаем assert в тестах

[tool.ruff.format]
quote-style = "double"
indent-style = "space"

Здесь select перечисляет группы правил: E/W/F — это классический Flake8, B — bugbear, I — isort, UP — pyupgrade (автоматическое обновление синтаксиса до целевой версии Python).

Автофикс

Это одна из самых практически полезных функций Ruff. Многие правила поддерживают автоматическое исправление:

code
ruff check --fix .

Ruff сам уберёт неиспользуемые импорты, отсортирует их, заменит устаревший синтаксис (например, Union[int, str] на int | str для Python 3.10+) и исправит десятки других мелочей. Flake8 такого не умеет совсем — он только сообщает о проблемах.

Совместимость с Black

Форматтер Ruff (ruff format) разработан как drop-in замена Black. На практике расхождения минимальны, но они есть — в основном в edge-случаях с магическими trailing comma. Если ваша команда строго следует Black, стоит прогнать форматтер на реальном проекте и сравнить diff перед переходом.


Как подключить Ruff к реальному проекту за пять минут

Покажем на примере типичного Django-проекта с существующим Flake8 и Black.

Шаг 1. Установка

code
pip install ruff
# или через uv, что быстрее:
uv add --dev ruff

Шаг 2. Базовая конфигурация

Добавляем в pyproject.toml:

code
[tool.ruff]
line-length = 88
target-version = "py311"
exclude = [
    "migrations",
    ".venv",
    "__pycache__",
]

[tool.ruff.lint]
select = [
    "E",   # pycodestyle errors
    "W",   # pycodestyle warnings
    "F",   # pyflakes
    "B",   # flake8-bugbear
    "I",   # isort
    "C4",  # flake8-comprehensions
    "UP",  # pyupgrade
]
ignore = [
    "E501",  # line too long — отдаём на откуп форматтеру
    "B008",  # do not perform function calls in default arguments (конфликт с FastAPI/Django)
]

[tool.ruff.format]
quote-style = "double"

Шаг 3. Первый запуск и автофикс

code
# Смотрим, что найдено
ruff check .

# Исправляем всё, что можно исправить автоматически
ruff check --fix .

# Форматируем код
ruff format .

После первого запуска на старом проекте вы, скорее всего, увидите несколько сотен предупреждений. Не пугайтесь — большинство из них исправятся автоматически. Остальные стоит просмотреть вручную.

Шаг 4. Интеграция в pre-commit

code
# .pre-commit-config.yaml
repos:
  - repo: https://github.com/astral-sh/ruff-pre-commit
    rev: v0.4.4
    hooks:
      - id: ruff
        args: [--fix]
      - id: ruff-format

Шаг 5. Интеграция в GitHub Actions

code
# .github/workflows/lint.yml
name: Lint

on: [push, pull_request]

jobs:
  ruff:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: astral-sh/ruff-action@v1
        with:
          args: "check ."
      - uses: astral-sh/ruff-action@v1
        with:
          args: "format --check ."

Официальный экшен astral-sh/ruff-action не требует установки Python и работает значительно быстрее, чем аналогичный шаг с Flake8 + Black.


Типичные подводные камни при переходе

Конфликт с существующим Black. Если вы используете Black параллельно с ruff format, они могут конфликтовать в edge-случаях. Решение простое: выберите одно или другое. Ruff format достаточно зрелый, чтобы его использовать как основной форматтер.

Правила, которых нет в Ruff. Некоторые специализированные плагины Flake8 ещё не реализованы в Ruff. Например, flake8-django или flake8-pytest-style покрыты частично. Проверяйте актуальный список поддерживаемых правил в документации — он обновляется с каждым релизом.

Слишком строгий select = ["ALL"]. Соблазн включить все 800+ правил велик, но это плохая идея для существующего проекта. Часть правил противоречит друг другу (например, правила про кавычки из разных наборов), часть — слишком педантична для реального кода. Начинайте с базового набора E/F/W/B/I и добавляйте группы осознанно.

Версионирование конфигурации. Ruff активно развивается, и между версиями могут появляться новые правила или меняться поведение существующих. Фиксируйте версию в requirements-dev.txt или pyproject.toml и обновляйте осознанно, просматривая changelog.


Когда Ruff не заменит pylint

Честный ответ: Ruff не является полноценной заменой pylint для глубокого статического анализа. Pylint умеет отслеживать типы через несколько файлов, анализировать цепочки наследования, предупреждать о потенциально некорректных операциях с типами без явных аннотаций. Если вам нужен именно такой уровень анализа — смотрите в сторону mypy или pyright в связке с Ruff, а не вместо них.

Ruff заменяет Flake8 + isort + pyupgrade + flake8-bugbear и берёт на себя форматирование вместо Black. Это уже очень много, и для большинства проектов этого достаточно.


Экосистема и поддержка

За Ruff стоит компания Astral — та же команда, что разрабатывает менеджер пакетов uv. Проект финансируется венчурными инвесторами и имеет полноценную команду разработчиков. Это важно для оценки долгосрочных рисков: инструмент не заброшен одним энтузиастом, а активно развивается.

Поддержка в редакторах также на высоком уровне: официальные расширения для VS Code и Neovim, интеграция в PyCharm через плагин, поддержка в Zed из коробки.

Для тех, кто только начинает разбираться с инструментарием Python и хочет понять Ruff не только на уровне «скопировал конфиг», но и осознать логику правил и настроек, есть бесплатный вводный курс «ruff – для начинающих!» — там разбирается именно практическая сторона: как читать вывод линтера, как выбирать правила под свой проект и как не сломать команду резким переходом.


Вывод

Ruff — это не хайп и не очередной инструмент ради инструмента. Это прагматичное решение реальной проблемы: разработчики Python тратили время на поддержку пяти разных конфигурационных файлов, ждали медленных проверок в CI и разбирались в конфликтах между isort и Black.

Переход на Ruff оправдан, если:

  • вы устали от зоопарка инструментов и хотите один конфиг
  • скорость CI для вас имеет значение
  • вы хотите автофикс, а не только отчёты об ошибках

Оставить старый стек имеет смысл, если вы завязаны на специфические плагины Flake8, которые Ruff ещё не реализовал, или если вам критичен глубокий анализ типов — тогда pylint или mypy всё равно останутся в стеке.

Для большинства проектов пяти минут на подключение и один коммит с новым pyproject.toml — вполне разумная инвестиция. Если хочется разобраться в теме системнее, прежде чем менять конфигурацию в production, курс «ruff – для начинающих!» даст нужный контекст без лишней воды.

Войдите, чтобы поставить лайк и оставить комментарий.

Автор

$ sudo teach IT

ruff – для начинающих!

Курс по теме

ruff – для начинающих!

С нуля до уверенной работы с линтингом и форматированием Python-кода. Подходит для начинающих и тех, кто уже пишет на Python. Разберитесь с Ruff раз и навсегда — и перестаньте гадать, какой инструмент запускать.

Бесплатно
Открыть курс

Продолжите обучение

Все курсы
Python – для начинающих!

Python – для начинающих!

С нуля до профессионального уровня. Подходит для всех. Учитесь каждый день и овладейте самым популярным языком программирования.

Перейти к курсу
Простыми словами о защищенном соединении

Простыми словами о защищенном соединении

Базовый курс для обычных людей: что такое защищённое соединение, как оно устроено, что оно умеет и чего не умеет, как выбрать сервис и настроить его на своих устройствах.

Перейти к курсу
Ботостроение Telegram

Ботостроение Telegram

Лёгкий, быстрый и доступный способ познакомиться с миром ботостроения в Telegram. Видео, конспекты, практика и помощь – всё у нас на курсе.

Перейти к курсу
Сервис, который не падает - как построить безопасную зашифрованную сеть

Сервис, который не падает - как построить безопасную зашифрованную сеть

Практический курс по безопасности сети: как собрать собственный сервис защищённого доступа - от пустого сервера до подписки с автовыбором - и, что важнее, как потом не уронить его своими руками.

Перейти к курсу

Другие статьи

Запуск и поддержка проекта на Ruff в команде: формат “как в CI”, а не “как договорились”
запуск

Запуск и поддержка проекта на Ruff в команде: формат “как в CI”, а не “как договорились”

Как правильно выстроить конфигурацию Ruff (линтинг, форматирование, автозамены) и сделать так, чтобы одинаковые правила гарантировались в локальной сборке и на CI без ручного шаманства.

16 сентября 2026 г.
1050
GIL в CPython: почему многопоточность не всегда ускоряет ваш Python-код
cpython

GIL в CPython: почему многопоточность не всегда ускоряет ваш Python-код

Разбираем, как устроен Global Interpreter Lock, почему потоки в Python не работают параллельно на CPU-задачах и когда стоит переключиться на multiprocessing или asyncio.

16 июля 2026 г.
710
Создание Telegram бота в 2026 легко и просто! Полный курсы!
создание

Создание Telegram бота в 2026 легко и просто! Полный курсы!

19 июня 2026 г.
1431
Как выбрать, куда идти в IT: веб, боты, данные — без хаоса
выбрать

Как выбрать, куда идти в IT: веб, боты, данные — без хаоса

Разберём самые понятные направления для новичка (веб, боты, аналитика/данные) и чем они отличаются по шагам обучения. В конце вы получите простой план, как проверить, что вам подходит, и какой стартовый путь выбрать.

5 октября 2026 г.
580
Путь от README до демо: как собрать портфолио разработчика, чтобы его хотели смотреть
путь

Путь от README до демо: как собрать портфолио разработчика, чтобы его хотели смотреть

Разберём структуру репозитория, как упаковать проект в понятную историю (проблема → решение → запуск → метрики качества) и какие артефакты повышают доверие: скринкасты, архитектурная схема, чек-лист продакшн-готовности.

17 сентября 2026 г.
1070
Как понять, какой язык программирования учить первым: простой тест и выбор
понять

Как понять, какой язык программирования учить первым: простой тест и выбор

Помогу новичку выбрать первый язык без стресса: объясню варианты по целям (веб, боты, анализ данных), что учить в первую очередь и как не потратить месяцы впустую. В конце — краткий план старта на ближайшие недели.

2 октября 2026 г.
630

Комментарии

Станьте первым в обсуждении

Поделитесь мнением о статье или задайте вопрос автору

Содержание

Что умеет каждый из инструментовFlake8BlackisortpylintRuff: что это такое и почему он такой быстрыйСравнение по ключевым параметрамСкоростьКонфигурацияАвтофиксСовместимость с BlackКак подключить Ruff к реальному проекту за пять минутШаг 1. УстановкаШаг 2. Базовая конфигурацияШаг 3. Первый запуск и автофиксШаг 4. Интеграция в pre-commitШаг 5. Интеграция в GitHub ActionsТипичные подводные камни при переходеКогда Ruff не заменит pylintЭкосистема и поддержкаВывод