$ 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 как «машина компоновки» кода: как настроить правила под стиль проекта

Ruff как «машина компоновки» кода: как настроить правила под стиль проекта

$ sudo teach IT
·19 июля 2026 г.·9 мин·59
Ruff как «машина компоновки» кода: как настроить правила под стиль проекта

Покажем, как выбрать набор правил, настроить конфиги и добиться одинакового качества во всей кодовой базе. Разберём типичные кейсы конфликтов и миграции.

Содержание
Что именно делает Ruff и почему это важно для согласованностиОпределяем целевой стиль: baseline проекта и границы автоматикиКакие аспекты вы хотите доверить RuffНе смешивайте роль линтера и форматтераВыбор набора правил: от “включить всё” к осознанной стратегииПрактика: стартовый профильНастройка через pyproject.toml: минимально достаточная конфигурацияНастройки, которые почти всегда нужныУправляем импортами и автофиксом: где чаще всего возникает хаосЕсли у вас уже есть isort/BlackОсторожно с unsafe-fixesТипичные кейсы конфликтов правилКейc 1: «Почему Ruff ругается на тесты иначе, чем на боевой код?»Кейc 2: «Ruff предлагает обновления синтаксиса, но проект ещё не на новом Python»Кейc 3: «Импорт отсортирован по-разному между локально и CI»Кейc 4: «После миграции CI превращается в стену ошибок»Стратегия миграции: как перейти на Ruff без остановки разработкиШаг 1: оценить текущий ландшафтШаг 2: включить правила по сегментамШаг 3: использовать временные исключения и пер-file игнорированиеШаг 4: договоритесь о правилах автофикса в командеПортативные примеры команд: как применять Ruff локально и в CIПроверка без фиксаПроверка только по изменённым файлам (полезно в больших репозиториях)Автофиксы безопасных преобразованийЗапуск в CI (чёткий контроль)Как добиться одинакового качества: дисциплина конфигурации и тесты на стабильность1) Версионируйте конфигурацию вместе с кодом2) Введите правило: “конфиг — не предмет обсуждения в каждом PR”3) Делайте “волны” улучшений4) Следите за правдоподобностью сообщенийРекомендованный рабочий процесс для командыЗаключение: Ruff как единый стандарт — и когда лучше учиться глубже

Ruff сегодня часто воспринимают как «быструю замену линтеру». На практике же его реальная сила шире: Ruff — это единый движок для набора правил (linting) и автоматической фиксации (formatting/organizing), который может стать «машиной компоновки» кода внутри команды. Он помогает удерживать единый стиль, не превращая ревью в бесконечные споры о запятых, именах и порядке импорта.

Но чтобы Ruff реально работал как конвейер качества, а не как очередной инструмент, который «иногда ругается», нужно правильно выбрать набор правил, настроить конфигурацию и заранее продумать миграцию. В этой статье разберём, как это сделать по-взрослому: от структуры конфигурации и выбора источников правил до типичных конфликтов и стратегии перехода.


Что именно делает Ruff и почему это важно для согласованности

Ruff — это инструмент статического анализа, который по умолчанию фокусируется на PEP8/flake8-совместимом поведении, а также включает дополнительные правила (например, из экосистемы isort/pyupgrade/pyflakes и т. п.). Его ключевые функции, которые влияют на «единое качество» кодовой базы:

  1. Линтинг: находит потенциальные проблемы (unused imports/variables, неиспользуемые выражения, неправильные исключения, подозрительные конструкции и т.д.).
  2. Автофикс: часть правил умеет предлагать исправления автоматически.
  3. Конфигурация правил: можно включать/выключать категории правил, выбирать “источники” правил и настраивать исключения.
  4. Интеграция в процессы: pre-commit, CI, локальные проверки перед коммитом.

Когда Ruff настроен правильно:

  • кодовая база выглядит единообразно;
  • ревью экономит время на «стилевые» вопросы;
  • ошибки и анти-паттерны отсекаются до того, как попадут в основную ветку;
  • миграции (например, переход на новый синтаксис Python) проходят контролируемо.

Определяем целевой стиль: baseline проекта и границы автоматики

Прежде чем включать “всё подряд”, нужно сформировать baseline — минимально допустимый стандарт. В идеале вы фиксируете следующие параметры:

Какие аспекты вы хотите доверить Ruff

Обычно разделяют три зоны:

  1. Структура и порядок

    • порядок импортов;
    • выравнивания/форматирование, которое Ruff умеет фиксировать;
    • удаление неиспользуемых конструкций (в пределах автофикса).
  2. Семантика и потенциальные ошибки

    • запрет опасных шаблонов;
    • приведение к современному синтаксису;
    • правила, которые ловят реальные баги/плохие практики.
  3. Личностные предпочтения команды

    • например, строгость по длине строк, оформление сложных выражений;
    • правила, которые чаще являются “вкусовыми”.

Ruff хорош именно для (1) и (2). Для (3) следует быть осторожным: если вы включите слишком “жёсткие” вкусовые правила, то инструмент начнёт мешать и станет причиной постоянных конфликтов в PR.

Не смешивайте роль линтера и форматтера

Ruff может делать автофиксы, но полноценное форматирование в стиле Black — отдельная тема. В некоторых проектах используют связку:

  • Ruff — для линтинга + частичных фиксов (например, импортов и простых преобразований),
  • Black — для форматирования,
  • isort — если не полагаетесь на Ruff для импорта (хотя Ruff часто закрывает эту задачу).

Если ваша цель — «одинаковое качество по всей базе», сначала определите, кто отвечает за форматирование, а кто — за правила.


Выбор набора правил: от “включить всё” к осознанной стратегии

Ruff поддерживает выбор правил через select, ignore и наборы-агрегаторы вроде lint.select/lint.ignore (конфигурация зависит от версии Ruff). В целом стратегия такая:

  1. Начните с доказанного набора: например, flake8-совместимые базовые категории + полезные дополнительные правила.
  2. Добавляйте правила постепенно, особенно “строгие” или потенциально конфликтные.
  3. Выделяйте исключения точечно:
    • на уровне файла;
    • на уровне директории;
    • точечно по коду (для обоснованных случаев).

Практика: стартовый профиль

Обычно разумный старт — включить базовые ошибки и “дефекты” качества, а вкусовые вещи отложить. Например, для современных проектов на Python 3.10+ вы часто включаете:

  • правила, связанные с синтаксическими и логическими подозрениями,
  • предупреждения о неиспользуемых импортах/переменных,
  • упрощения и приведение к современному стилю.

Ниже пример конфигурации (TOML). Она не претендует на «единственно верную», но показывает подход: задаём target-Python, выбираем правила и управляем автофиксом.

code
# pyproject.toml
[tool.ruff]
target-version = "py310"

[tool.ruff.lint]
# Выбираем наборы правил. Конкретные коды зависят от версии Ruff.
select = [
  "E",   # pycodestyle: ошибки форматирования
  "F",   # pyflakes: потенциальные ошибки
  "I",   # isort-подобные правила по импорту
  "UP",  # pyupgrade: приведение к современному синтаксису
  "B",   # flake8-bugbear: потенциальные баги/подозрительные места
]

# Игнорируем то, что точно конфликтует с вашим подходом или пока “не готово”.
ignore = [
  # Например: временно отключить строгие правила по длине строк,
  # если у вас форматирование делает другой инструмент.
  "E501",
]

# Управление “важностью” правил через категорию per-file.
# Этот блок будет полезен для миграций.

Настройка через pyproject.toml: минимально достаточная конфигурация

Большая часть командных проектов держит конфигурацию Ruff в pyproject.toml. Это удобно, потому что:

  • один файл на проект;
  • можно версионировать в том же PR, что и изменения правил;
  • конфигурация легко переносится между средами.

Настройки, которые почти всегда нужны

  1. target-version — чтобы Ruff корректно рекомендовал преобразования.
  2. line-length (если релевантно вашим правилам).
  3. Параметры автокоррекции (fix, unsafe-fixes) — осторожно.
  4. Исключения по директориям (например, migrations, vendor, tests если у вас другая политика).

Пример более «прикладной» конфигурации:

code
[tool.ruff]
target-version = "py310"
line-length = 100

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

[tool.ruff.lint.per-file-ignores]
# Например, миграции в Django часто содержат специфический код.
"*/migrations/*.py" = ["UP006"]

[tool.ruff.format]
# В Ruff есть форматирование/переформатирование в рамках его компетенции.
# Если у вас есть отдельный форматтер, этот блок может быть пустым или отключённым.
quote-style = "double"

Управляем импортами и автофиксом: где чаще всего возникает хаос

Конфликтов обычно три типа:

  1. Порядок импортов спорит с другим инструментом
  2. Ruff делает автофикс там, где это конфликтует с вашими ожиданиями форматирования
  3. Правила “строгие”, но кодовая база пока не готова

Если у вас уже есть isort/Black

Сценарии:

  • Ruff может исправлять порядок импортов (включая правила I).
  • Black — форматирует строки и скобки.
  • isort (иногда) — управляет порядком импортов.

Если вы включаете и Ruff (I), и isort одновременно, важно согласовать конфигурации обоих инструментов (profile, секции, force_sort_within_sections и т.п.). Иначе вы получаете бесконечные правки: один инструмент меняет — второй снова меняет.

Практическое решение:

  • либо оставить порядок импортов Ruff’у и отключить isort;
  • либо отключить импортные правила Ruff и оставить isort.

Для согласованности большинство команд выбирают один источник истины.

Осторожно с unsafe-fixes

Ruff может делать автофиксы безопасные и небезопасные (в зависимости от типа правила). Небезопасные фиксы обычно меняют структуру кода глубже, чем вы ожидаете. На этапе внедрения правил лучше начать с безопасных фиксов, а небезопасные — включать после периода стабилизации.


Типичные кейсы конфликтов правил

Кейc 1: «Почему Ruff ругается на тесты иначе, чем на боевой код?»

В тестах часто допускаются:

  • assert без дополнительных сообщений,
  • длинные строки с JSON/табличными данными,
  • специфические паттерны моков.

Решение — per-file-ignores и/или разные наборы правил. Простейший пример:

code
[tool.ruff.lint.per-file-ignores]
"tests/**/*.py" = ["B006", "E501"]

Это не «всё разрешить», а сделать различия контролируемыми.

Кейc 2: «Ruff предлагает обновления синтаксиса, но проект ещё не на новом Python»

Если вы включаете UP (pyupgrade) и не выставили target-version, Ruff может рекомендовать изменения, которые не поддерживаются вашей версией интерпретатора в проде/CI.

Решение:

  • корректно задать target-version,
  • или временно игнорировать “опасные” подклассы правил pyupgrade.

Кейc 3: «Импорт отсортирован по-разному между локально и CI»

Это почти всегда из-за несогласованности конфигураций или разной версии инструментов.

Проверьте:

  • совпадает ли pyproject.toml везде;
  • одинаковые версии Ruff (lockfile для зависимости или pinned версия в CI);
  • одинаковая ОС/файловая система (реже, но бывает влияние на некоторые сценарии).

Практика команды: фиксировать версию Ruff в зависимостях проекта или в tooling-окружении.

Кейc 4: «После миграции CI превращается в стену ошибок»

Это симптом слишком резкого включения правил.

Правильный подход:

  • включить набор правил постепенно;
  • сначала добиться нулевых ошибок в основных директориях;
  • затем расширить покрытие.

Стратегия миграции: как перейти на Ruff без остановки разработки

Самая полезная часть внедрения — не «настроить конфиг», а сделать так, чтобы команда могла продолжать работу в процессе.

Шаг 1: оценить текущий ландшафт

Запустите Ruff в “диагностическом” режиме (без фиксов) и соберите статистику по типам ошибок. Это можно сделать командой ruff check с выводом. Идея: понять, какие категории будут мешать больше всего.

Шаг 2: включить правила по сегментам

Например:

  • сначала базовые F/E (потенциальные ошибки и базовые ошибки стиля),
  • затем I (импорты),
  • затем UP/B (синтаксические обновления и потенциальные баги).

Шаг 3: использовать временные исключения и пер-file игнорирование

Если у вас большая кодовая база, “вылечить всё” в одном PR почти всегда плохо:

  • вы получаете огромный дифференс;
  • ревью становится механическим;
  • высок шанс конфликтов.

Вместо этого:

  • создайте временные per-file-ignores для веток, где проблем больше всего;
  • планируйте постепенное удаление игноров по мере рефакторинга.

Шаг 4: договоритесь о правилах автофикса в команде

Чётко решите:

  • кто запускает автопочинку (ruff check --fix или pre-commit)?
  • разрешены ли unsafe-fix?
  • нужно ли согласование через PR или фикс сразу коммитится?

Там, где это возможно, pre-commit помогает удерживать единообразие. Но важно, чтобы конфигурация pre-commit совпадала с CI.


Портативные примеры команд: как применять Ruff локально и в CI

Ниже — типовые команды, которые помогают поддерживать процесс.

Проверка без фикса

code
ruff check .

Проверка только по изменённым файлам (полезно в больших репозиториях)

В зависимости от вашей системы контроля версий можно ограничивать список. Например, для Git:

code
git diff --name-only origin/main...HEAD | xargs -r ruff check

Автофиксы безопасных преобразований

code
ruff check . --fix

Запуск в CI (чёткий контроль)

Обычно CI запускают так, чтобы не было “тихих” режимов:

code
ruff check . --output-format=github

Если вы используете форматтеры/линтеры в связке, поддерживайте одинаковые параметры в локальной среде и в CI.


Как добиться одинакового качества: дисциплина конфигурации и тесты на стабильность

Ruff — статический инструмент, и качество его работы зависит от дисциплины:

1) Версионируйте конфигурацию вместе с кодом

Изменения в pyproject.toml должны идти в PR вместе с логикой и рефакторингом. Иначе вы получите ситуацию: CI ловит новое правило, но разработчик не увидит изменения в конфигурации локально.

2) Введите правило: “конфиг — не предмет обсуждения в каждом PR”

Не нужно спорить каждый раз: почему включили/не включили конкретный код. Пусть решение принято один раз и оформлено в конфиг.

3) Делайте “волны” улучшений

Вместо того чтобы каждый месяц расширять набор правил и ловить накопленный долг, удобно:

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

4) Следите за правдоподобностью сообщений

У Ruff сообщения обычно конкретные. Но если вы отключаете правило “везде” или игнорируете “на всё”, потеряете пользу. Лучше точечные пер-file игноры и понятные причины.


Рекомендованный рабочий процесс для команды

Чтобы Ruff стал «машиной компоновки», команда должна договориться о рутинной схеме:

  1. Локально разработчик запускает ruff check перед коммитом (лучше pre-commit).
  2. PR содержит либо нулевые lint-ошибки, либо логически объяснимое временное исключение.
  3. CI проверяет всё репозиторий, не скрывая ошибки.
  4. Правила добавляются итеративно, с планом по устранению “хвоста”.
  5. Автофиксы применяются единообразно (и фиксируются в диффе, чтобы ревью видело изменения).

Заключение: Ruff как единый стандарт — и когда лучше учиться глубже

Ruff выгоден тем, что позволяет командам держать единый стиль и качество кода в одном движке: выбрали набор правил, настроили target-version, аккуратно применили автофиксы, разрулили импортные вопросы и спланировали миграции без “стены ошибок”. Главное — не пытаться включить максимальную строгость сразу, а выстроить устойчивый процесс: от baseline до постепенного расширения правил.

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

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

Автор

$ sudo teach IT

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

Курс по теме

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

16 сентября 2026 г.
1050
Как настроить локальную среду для Python-проекта: venv, pyproject.toml и воспроизводимые зависимости
настроить

Как настроить локальную среду для Python-проекта: venv, pyproject.toml и воспроизводимые зависимости

Разберём, как правильно собрать окружение для разработки и CI: структуры проекта, pyproject.toml, lock-файлы и типовые сценарии воспроизведения зависимостей на другой машине. Параллельно покажем, как избежать “работает у меня”.

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

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

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

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

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

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

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

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

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

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

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

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

Комментарии

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

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

Содержание

Что именно делает Ruff и почему это важно для согласованностиОпределяем целевой стиль: baseline проекта и границы автоматикиКакие аспекты вы хотите доверить RuffНе смешивайте роль линтера и форматтераВыбор набора правил: от “включить всё” к осознанной стратегииПрактика: стартовый профильНастройка через pyproject.toml: минимально достаточная конфигурацияНастройки, которые почти всегда нужныУправляем импортами и автофиксом: где чаще всего возникает хаосЕсли у вас уже есть isort/BlackОсторожно с unsafe-fixesТипичные кейсы конфликтов правилКейc 1: «Почему Ruff ругается на тесты иначе, чем на боевой код?»Кейc 2: «Ruff предлагает обновления синтаксиса, но проект ещё не на новом Python»Кейc 3: «Импорт отсортирован по-разному между локально и CI»Кейc 4: «После миграции CI превращается в стену ошибок»Стратегия миграции: как перейти на Ruff без остановки разработкиШаг 1: оценить текущий ландшафтШаг 2: включить правила по сегментамШаг 3: использовать временные исключения и пер-file игнорированиеШаг 4: договоритесь о правилах автофикса в командеПортативные примеры команд: как применять Ruff локально и в CIПроверка без фиксаПроверка только по изменённым файлам (полезно в больших репозиториях)Автофиксы безопасных преобразованийЗапуск в CI (чёткий контроль)Как добиться одинакового качества: дисциплина конфигурации и тесты на стабильность1) Версионируйте конфигурацию вместе с кодом2) Введите правило: “конфиг — не предмет обсуждения в каждом PR”3) Делайте “волны” улучшений4) Следите за правдоподобностью сообщенийРекомендованный рабочий процесс для командыЗаключение: Ruff как единый стандарт — и когда лучше учиться глубже