Добавить в корзинуПозвонить
Найти в Дзене

Ruff: Сверхбыстрый линтер и форматтер для Python с примерами

В мире Python-разработки поддержка чистоты кода критически важна. Традиционно для этого используются: - Линтеры (flake8, pylint) — анализ ошибок и стиля - Форматтеры (black, autopep8) — автоматическое форматирование - Инструменты сортировки импортов (isort) Проблема: Множество инструментов = сложная настройка + медленная работа. Решение: Ruff — инструмент на Rust, объединяющий функциональность линтера, форматтера и сортировщика импортов с фокусом на скорости и удобстве. 1. Невероятная скорость (в 10-100 раз быстрее аналогов) 2. 700+ встроенных правил (совместимость с flake8, isort, pyupgrade) 3. Автофикс для 50%+ правил 4. Форматирование кода (альтернатива black) 5. Простая установка — один бинарный файл 6. Современный стандарт — поддержка Python 3.12, Jupyter Notebooks pip install ruff # Или для изолированного окружения: pipx install ruff Проверка установки: ruff --version # ruff 0.3.4 ruff check . Пример вывода: main.py:5:17: E225 [*] Missing whitespace around operator utils.py:1:8:
Оглавление

В мире Python-разработки поддержка чистоты кода критически важна. Традиционно для этого используются:

- Линтеры (flake8, pylint) — анализ ошибок и стиля

- Форматтеры (black, autopep8) — автоматическое форматирование

- Инструменты сортировки импортов (isort)

Проблема: Множество инструментов = сложная настройка + медленная работа.

Решение: Ruff — инструмент на Rust, объединяющий функциональность линтера, форматтера и сортировщика импортов с фокусом на скорости и удобстве.

Ключевые особенности

1. Невероятная скорость (в 10-100 раз быстрее аналогов)

2. 700+ встроенных правил (совместимость с flake8, isort, pyupgrade)

3. Автофикс для 50%+ правил

4. Форматирование кода (альтернатива black)

5. Простая установка — один бинарный файл

6. Современный стандарт — поддержка Python 3.12, Jupyter Notebooks

Установка

pip install ruff
# Или для изолированного окружения:
pipx install ruff

Проверка установки:

ruff --version
# ruff 0.3.4

Базовое использование

Линтинг всех файлов в проекте

ruff check .

Пример вывода:

main.py:5:17: E225 [*] Missing whitespace around operator
utils.py:1:8: F401 [*] `os` imported but unused
Found 12 errors.
[*] 8 fixable with the `--fix` option.

Автоматическое исправление ошибок

ruff check --fix .

Форматирование кода

ruff format .

Примеры правил с объяснением

1. Логические ошибки (F-правила)

F601: Повторяющийся ключ в словаре

# До
config = {"port": 8080, "host": "localhost", "port": 8000}
# После автофикса
config = {"host": "localhost", "port": 8000}

F841: Неиспользуемая переменная

# До
def calculate():
....result = 42 # Переменная не используется
....return 100
# После автофикса
def calculate():
....return 100

2. Стиль кода (E, W-правила)

E711: Сравнение с `None` через `is`

# До
if value == None:
....pass
# После
if value is None:
....pass

W292: Отсутствие пустой строки в конце файла

# До
print("Hello")
# Файл заканчивается без \n
# После
print("Hello")
# Добавляется \n в конце

3. Сортировка импортов (I-правила)

I001: Несортированные импорты

# До
import sys
import os
from django.conf import settings
# После
import os
import sys
from django.conf import settings

4. Форматирование (RUF-правила)

RUF100: Ненужные `noqa`

# До
import os # noqa: F401
# После (комментарий удаляется)
import os

Конфигурация через pyproject.toml

Пример настройки:

[tool.ruff]
line-length = 100
select = [
"E", # pycodestyle errors
"F", # Pyflakes
"I", # isort
"UP", # pyupgrade
"RUF", # ruff-specific
]
ignore = ["E501"] # Игнорировать длинные строки
# Настройка форматирования
[tool.ruff.format]
quote-style = "single" # Использовать одинарные кавычки
indent-width = 4
# Настройка isort
[tool.ruff.isort]
known-first-party = ["myapp"]

Интеграция в IDE (VS Code)

1. Установите расширение Ruff

2. Добавьте в settings.json:

{
"python.linting.enabled": true,
"python.linting.ruffEnabled": true,
"editor.codeActionsOnSave": {
"source.fixAll.ruff": true
},
"python.formatting.provider": "ruff"
}

Результат: автоматический линтинг и форматирование при сохранении файла.

Работа с Jupyter Notebooks

ruff check --format jupyter notebook.ipynb
ruff format notebook.ipynb

Продвинутые сценарии

1. Локальное подавление правил

def deprecated_function():
....# ruff: noqa: F401, W292
....return 42 # Игнорирует 2 правила

2. Per-file игнорирование

В pyproject.toml:

[tool.ruff.per-file-ignores]
"__init__.py" = ["F401"] # Разрешить неиспользуемые импорты в __init__.py
"tests/*.py" = ["S101"] # Разрешить assert в тестах

3. Пользовательские правила

Через плагины (требуется сборка из исходников):

// ruff/src/rules/plugin_example.rs
fn rule_impl(context: &mut Context) -> Option<Diagnostic> {
// Кастомная логика
}

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

.pre-commit-config.yaml:

repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.3.4
hooks:
- id: ruff
args: [--fix, --show-fixes]
- id: ruff-format

Бенчмарки производительности

Тест на кодовой базе Django (20k+ LOC):

Tool Time Rules

flake8 + isort 8.2s 65

Ruff 0.4s 188

Причины скорости:

1. Компиляция в нативный код (Rust)

2. Параллельная обработка файлов

3. Оптимизированные алгоритмы

Экосистема Ruff

1. ruff-lsp — Language Server Protocol

2. ruff-pre-commit — интеграция с Git hooks

3. Ruff VS Code Extension — расширение для редактора

4. Red Hat OpenShift — встроенная поддержка в платформе

Ограничения

1. Форматирование пока в бета-версии (не 100% совместимость с black)

2. Меньше кастомизации стиля, чем у pylint

3. Нет поддержки плагинов из коробки (только через сборку)

Миграция с других инструментов

Пошаговая миграция:

1. Заменить isort: `ruff check --select I --fix`

2. Заменить flake8: `ruff check --select E,F,W --fix`

3. Заменить black: `ruff format`

4. Настроить конфиг через `pyproject.toml`

Сравнение команд:

Legacy Ruff Equivalent

isort . ruff check --select I --fix

flake8 . ruff check --select E,F,W

black . ruff format

pylint --disable=C ruff check --ignore PLC

Пример полного рабочего процесса

1. Инициализация проекта:

mkdir myproject && cd myproject
python -m venv .venv
source .venv/bin/activate

2. Настройка:

echo "[tool.ruff]" > pyproject.toml
echo "line-length = 88" >> pyproject.toml

3. Пример кода (`main.py`):

import sys, os # Ошибки: I001, F401
def calculate():
....x=2+3 # Ошибка: E225
....return {'a':1,'a':2} # Ошибка: F601

4. Запуск проверки:

ruff check .
# main.py:1:8: F401 [*] `os` imported but unused
# main.py:1:1: I001 [*] Import block is un-sorted or un-formatted
# main.py:3:16: E225 [*] Missing whitespace around operator
# main.py:4:18: F601 [*] Duplicate key `'a'` in dictionary

5. Автоматическое исправление:

ruff check --fix .

Исправленный код:

import sys
def calculate():
....x = 2 + 3
....return {"a": 2}

Заключение

Ruff — не просто ещё один инструмент, а качественный скачок в инструментарии Python:

- ⚡ Экономия времени — проверка 10k строк за 0.1 сек

- � Упрощение стека — один инструмент вместо 5-7

- 🔧 Легкая миграция — совместимость с существующими конфигами

- 🌱 Активное развитие — 20k+ звёзд на GitHub, поддержка PSF

Когда использовать:

- Новые проекты — сразу начать с Ruff

- Существующие проекты — постепенная миграция

- CI/CD пайплайны — ускорение сборок

- Образовательные проекты — минимум настройки

Рекомендации:

1. Начните с `ruff check --fix`

2. Постепенно настраивайте правила через `select/ignore`

3. Включите форматирование в pre-commit

4. Используйте `ruff format` вместо black

# Оптимальная стартовая команда
ruff check --fix --show-source --ignore=E501 .

Ruff задаёт новый стандарт инструментов Python, делая поддержку кода не обязанностью, а удовольствием.

Подписывайтесь:

Телеграм https://t.me/lets_go_code
Блог "Просто о программировании"
http://lets-go-code.ru/blog/