Время прочтения: 6 мин.

В публикации проанализирую существующие инструменты автоматического форматирования кода при написании программ на языке python. Рассмотрю особенности применения инструмента YAPF, который решает подобные задачи. Перечислю сценарии его применения, использование которых позволит улучшить читаемость кода, поможет автоматически проводить проверку на соответствие стандартам и руководствам, сократит время разработки, уменьшит вероятность появления ошибок в нём и сделает это в автоматическом режиме. 

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

В моей команде было принято проверять качество кода в отношении стиля форматирования с помощью pylint с разными конфигурационными файлами для различных заказчиков. Возможности этого инструмента в плане автоматического исправления ограничены, и для повышения производительности и удобства разработки проекта я решил проанализировать существующие инструменты автоматического форматирования кода при написании программ на языке python.

Анализ существующих инструментов автоматического форматирования кода

Существуют несколько инструментов автоматического форматирования кода для языка python: Black, Autopep8, PyFormat, PyLint, Flake8, Pepe8ify и YAPF. Сравним популярность и актуальность перечисленных инструментов на основе количества «звёзд» для репозиториев на сайте https://github.com для каждого из инструментов в зависимости от времени (см. рис. 1).

Рис.1 Популярность инструментов для python
(на основе данных с сервиса https://star-history.com/)

На сегодняшний день самым популярным и «молодым» инструментом является Black. Однако существуют причины, которые не позволяют мне его использовать. Black неразрывно связан с соглашением по оформлению кода PEP8 и поэтому имеет ограниченное количество настроек форматирования кода и не поддерживает наличие нескольких наборов пользовательских настроек форматирования.

Рассмотрю второй по популярности инструмент подробнее. YAPF (Yet Another Python Formatter). В отличие от других инструментов форматирования кода, таких как Black, он предлагает широкий спектр настроек, которые можно сохранить и использовать в виде независимых профилей. YAPF использует алгоритм стилистической унификации программного кода clang-format, который обычно применяют для таких языков программирования как С, С++, Objective-C. Алгоритм форматирования clang-format сложнее, чем алгоритмы, используемые в других инструментах, благодаря чему он учитывает не только количество отступов и пробелов, но и другие аспекты кода, такие как расположение и количество скобок, ключевых слов и т.д. Это позволяет YAPF форматировать код точно и эффективно, учитывая все детали его структуры.

На рисунке 2 представлено сравнение кода, приведённое в документации к YAPF на сайте https://github.com/google/yapf, не противоречащего PEP8, и кода, отформатированного через YAPF, и это полностью соответствует потребностям команды.

Рис.2 Сравнение кода до и после использования YAPF

Режимы работы YAPF

Часто YAPF используется в связке с текстовыми редакторами. В данный момент разработаны плагины для работы в Emacs, VIM и Sublime Text.

Его можно запустить из консоли или терминала внутри операционных систем Windows и Linux соответственно, обратившись к исполняемому файлу YAPF и указав python файлы, которые требуется проверить и отформатировать (см. Рис. 3).

Рис. 3 –  Пример выполнения команд YAPF в командной строке для автоматического форматирования кода из файла «source.py» и записи результата в «formated.py»

Существует программный интерфейс API для python, который позволяет прямо из кода в Jupiter Notebook осуществлять форматирование фрагментов кода и целых файлов с помощью абстракций FormatCode и FormatFile. Пример использования API для фрагмента кода и файла foo.py представлен на рисунках 4 и 5 соответственно.

Рис. 4 – Пример использования API для автоматического
форматирования фрагмента кода с помощью YAPF
Рис. 5 – Пример использования API для автоматического
форматирования файла «foo.py» с помощью YAPF

Отдельно стоит отметить возможность использовать YAPF в качестве pre-commit хука для системы контроля версий git, что позволит запускать автоматическое форматирование кода перед каждым коммитом. Это минимизирует «человеческий фактор», связанный с невыполнением требований обязательной проверки форматирования кода python скриптов.

Стиль форматирования

В отличии от других инструментов, YAPF дает больше возможностей для работы с кодом в плане управления стилем форматирования. Наряду с существующими четырьмя встроенными правилами форматирования, соответствующие рекомендациям PEP8, google, yapf и facebook, также доступна возможность «ручной» настройки с помощью аргумента —style. Он принимает один из четырёх стандартных стилей, путь к файлу конфигурации, который определяет желаемый стиль, или словарь пар ключ/значение.

Рассмотрю, что из себя представляет конфигурационный файл подробнее. Это не что иное, как обычный список пар ключ = значение с заголовком [style]:

[style]
based_on_style = google
split_before_dict_set_generator = true 
spaces_around_subscript_colon = true 

где параметр based_on_style соответствует стилю форматирования, который будет использоваться в качестве основы, параметр split_before_dict_set_generator управляет переносом фигурной скобки каждой строки при создании генератора словарей и множеств, а параметр spaces_around_subscript_colon управляет пробелами до и после двоеточий в срезах. Исчерпывающий перечень параметров и их описание можно найти в документации к YAPF, которая расположена на сайте https://github.com/google/yapf.

Перечисленные достоинства YAPF объясняют высокую популярность среди разработчиков этого инструмента автоматического форматирования кода.

Приведу пример кода, автоматически отформатированного YAPF со стилем форматирования, описанным выше:

example = {
	   value: 'positive'
             for value in keys if value > 0
	   samps = example_list [1 : 9 : 3]
}

Примеры пользовательского форматирования, отличающиеся в лучшую сторону по стилю в сравнении со стандартом PEP8, представлены на
рисунке 6.

Рис. 6 – Примеры пользовательского форматирования, полученные автоматическим с использованием YAPF

Заключение

Проведённый анализ существующих инструментов автоматического форматирования кода при написании программ на языке python позволил выбрать YAPF. Благодаря этому удалось улучшить читаемость кода, проводить автоматически проверку кода на соответствие стандартам и руководствам, сократить время разработки и уменьшить вероятность появления ошибок в нём.

При этом сохранилась возможность работать с несколькими разными стилями форматирования кода в скриптах python, переключая конфигурационные файлы инструмента автоматического форматирования кода YAPF.