Сегодня немного о линтерах и стандартах оформления кода. Кратко рассмотрим flake8, а затем в качестве бонуса напишем небольшой pre-commit hook для git.
Что такое стандарт оформления кода и зачем его соблюдать?
Через некоторое время работы осознаешь, что читаешь код гораздо чаще чем пишешь. Если команда большая, то кодовая база в принципе расширяется стремительнее, чем ты успеваешь её отслеживать. Потом оказывается, что Петя перешел на Python после C++, Жанна после 1С а Иван просто очень любит использовать именованные лямбды и сокращения. Чтобы привести этот зоопарк к одному виду и новые люди могли въехать в проект без геноцида девственниц и дьявольских ритуалов нужны стандарты. В них описывается количество пробелов в отступах, правила оформления докстрингов, расположения аргументов, импортов и т.д. Мысль вроде очевидная, но если их соблюдать, действительно становится легче.
В Python есть базовый стандарт, который многими берут за основу - PEP8[1].
Крупные компании, куда все хотят попасть, могут создать свой гайд. Например так сделал Google[2].
Немного о flake8
Программисты не были бы собой, если бы не свесили проверку стандартов на машину. Программы решающие эту задачу называются линтеры и могут указывать на допущенные ошибки или просто править их. Вдогонку они часто проверяют код на базовые синтаксические ошибки.
Как говорит документация, flake8 - обертка сразу над несколькими проектами (PyFlakes, pycodestyle, Ned Batchelder’s McCabe script). Кроме этого есть достаточно большое количество плагинов, расширяющих подмечаемые линтером детали.
Немного посмотрим, что он умеет. Установка:
$ pip install flake8
Ради примера сгенерируем совсем небольшой кусочек кода.
Чтобы проверить файл или директории с проектом просто указываем к ним путь:
$ flake8 example.py
нажимаем на кнопку и получаем результат:
В ответе название файла, строка ошибки, её код и текстовая расшифровка. Помните я говорил про плагины? В базовом варианте flake8 игнорирует докстринги. Если доставить еще flake8-docstrings, flake8-builtins, то вы получите даже больше информации.
Часто код даже не нужно проверять на соответствие всем правилам. Для таких случаев есть параметры --select / --ignore, после которых можно указать коды отслеживаемых / игнорируемых правил.
Чтобы не забивать себе голову и не городить ужасающие конструкции в командной строке, лучше собрать настройки в конфигурационном файле .flake8 и положить его в корневую директорию проверяемого проекта.
Думаю основная идея понятна, чтобы разобраться глубже - лучше смотреть документацию [3], а с меня еще парочка особенностей и советов:
Творим добро на уже существующем проекте
Как мы уже убедились, flake8 может выдавать огромные простыни поправок даже на маленьких проектах. Иногда хорошим решением может быть не проверять весь проект сразу, а проверять только новый код. Например, у вас слишком большой проект и сейчас нет ресурсов на косметическую корректировку кода (а на такое их обычно нет).
На помощь приходит параметр --diff.
Получаем дифф гита и отправляем его в линтер:
$ git diff | flake8 --diff
Всегда есть надежда, что постепенно работая над проектом вы сможете переписать его и привести к идеальному виду. (Ну или по-крайней мере правильно оформить докстринги)
Немного автоматизации
Как быть уверенным, что не забыл проверить свой код перед коммитом и отправкой в репозиторий? В git есть замечательный инструмент pre-commit hook, который выполняет ваш скрипт перед фиксацией коммита.
Чтобы его установить, нужно найти в вашем проекте директорию .git/hooks и в ней файл pre-commit.
Поскольку наши корпоративные правила немного отличаются от PEP8 мы с коллегой решили не проверять всё сразу, а собрать самые распространенные ошибки. Какую-то часть с чистой совестью отдали на автоисправление.
Итог - небольшой bash-скрипт:
Это самая верхушка айсберга, но даже она помогает экономить время и нервы на ревью. Что он делает:
- Проверяет установку необходимых библиотек. (сам flake8, 2 плагина к нему и 2 автоматических линтера, которые исправляют мелкие косяки)
- Запускает автоматические линтеры, которые корректируют код.
- Проверяет новый код на ошибки.
Код скрипта и пример конфигурационного .flake8 выложу в репозиторий[4]. Так же под заметкой ссылка на более подробную статью о git hooks[5].
_______________________________________________________________________________________
+1 в копилку полезных инструментов и еще на один шаг ближе к прекрасному. До новых встреч)
[1] Style Guide for Python Code
[4] примеры кода