Тема 04 · Аннотации типов и документация кода

Аннотации типов и документация кода · МДК.01.01 · разработка программных модулей

Глава 4.10

4.10

VS Code:
генератор и проверка

В этой главе редактор начинает помогать с докстрингами. Разобрано расширение, которое создаёт заготовку докстринга по подписи функции, настройка формата в файле проекта, свой шаблон и сниппет, а во второй половине — программная проверка: правила pydocstyle в Ruff, которые находят недокументированные функции и нарушения оформления, и включение этой проверки в запрос на слияние.

Категория
Рабочее место
Уровень
Начальный
Опирается на
Главы 4.7–4.9, тема 02
Зачем это знать
Не набирать разделы руками и не искать пропуски глазами

§1Что редактор делает без расширений

Расширение Python от Microsoft вместе с языковым сервером Pylance устанавливается в VS Code одним пакетом и выполняет две задачи из этой темы.

ВозможностьКак пользоваться
Подсказка с докстрингом при наведении на имя функцииУказатель на имя, либо CtrlCmd + K, затем CtrlCmd + I
Подсказка при наборе аргументов вызоваОткрывается сама после открывающей скобки; вызвать заново — CtrlCmd + Shift + Пробел

Заготовку докстринга по подписи функции встроенные средства не создают. Для этого ставят отдельное расширение.

§2Расширение autoDocstring

autoDocstring — расширение VS Code, которое читает подпись функции и вставляет заготовку докстринга: краткую строку, раздел с параметрами по именам аргументов, раздел результата и раздел исключений, если в теле есть raise. Текст описаний пишет человек, разметку и перечень имён — расширение.

Установка: откройте панель расширений (CtrlCmd + Shift + X), введите в поиске идентификатор и нажмите Install.

Панель расширенийидентификатор
njpwerner.autodocstring
Панель расширений VS Code: по идентификатору найдено одно расширение autoDocstring автора Nils Werner
По идентификатору находится ровно одно расширение: autoDocstring — Python Docstring Generator, автор Nils Werner. Кнопка установки появляется на карточке при наведении; на кадре расширение уже установлено, поэтому вместо неё показан значок настроек.

Расширение ищут по идентификатору: в поиске есть несколько расширений с похожими названиями, и идентификатор отличает нужное однозначно.

§3Как вызвать генератор

Разберём вставку на функции revenue_by_waiter из файла app/services/orders.py стартового архива. Порядок такой:

  1. Откройте файл и поставьте курсор на строку с def — ту, у которой нужно описание.
  2. Нажмите End (CtrlCmd + →) и затем Enter: под подписью появится пустая строка с отступом тела.
  3. Вызовите генератор любым из трёх способов: наберите три двойные кавычки и нажмите Enter; либо нажмите CtrlCmd + Shift + 2; либо откройте палитру команд (CtrlCmd + Shift + P) и выберите Generate Docstring.
  4. Заполните поля заготовки, переходя между ними клавишей Tab.
Файл orders.py из стартового архива: функция revenue_by_waiter без докстринга, курсор на строке def
Шаг первый. Курсор стоит на строке 14 — это видно в строке состояния внизу: Ln 14, Col 1. Описания у функции нет, и цифра 4 у имени файла в дереве считает замечания проверки по этому файлу.
На полях: пустая строка под подписью нужна

Генератор вставляет заготовку на место курсора. Если вызвать его, когда курсор стоит в первой колонке строки def, описание встанет выше функции и код перестанет работать. Если курсор окажется на первой строке тела, закрывающие кавычки попадут в одну строку с кодом. Поэтому сначала делают пустую строку — шаг 2 из списка.

После вызова генератора в файл вставляется такая заготовка:

Результат вставкиформат google
def revenue_by_waiter(orders: list[Order], top: int = 0) -> dict[str, int]:
    """_summary_

    Args:
        orders (list[Order]): _description_
        top (int, optional): _description_. Defaults to 0.

    Raises:
        ValueError: _description_

    Returns:
        dict[str, int]: _description_
    """
Тот же файл после вызова генератора: вставлена заготовка докстринга с разделами Args, Raises и Returns
Шаг третий выполнен. Разделы расставлены по подписи функции: в Args оба параметра, у top приписаны optional и Defaults to 0; раздел Raises добавлен из-за raise ValueError в теле; в Returns подставлен тип из аннотации. Серым выделены поля для заполнения, между ними переходят клавишей Tab.

Что сделало расширение и что осталось человеку:

Взято из кода расширениемПишет человек
Имена параметров и их порядокЧто означает каждый параметр и какие значения допустимы
Типы из аннотаций и признак optionalСмысл значения по умолчанию
Раздел Raises: с классом исключенияУсловие, при котором исключение возбуждается
Раздел Returns: с типом результатаЧто означает результат: единицы, порядок, границы
Разметку разделов и отступыКраткую строку с действием функции
На полях: заготовку заполняют сразу

Оставленные в коде _description_ — это докстринг, который повторяет перечень имён параметров, уже известный из подписи. Проверка из §9 на незаполненные описания не жалуется: докстринг формально есть. Она заметит только _summary_ без точки на конце — правилом D415, и это видно в §11. Поэтому заготовку заполняют, пока функция в работе.

§4Настройка формата в проекте

По умолчанию расширение вставляет формат google. Формат задают явно, чтобы у всех в команде получалась одинаковая разметка. Настройка хранится в файле .vscode/settings.json внутри проекта и попадает в репозиторий вместе с кодом.

.vscode/settings.jsonнастройки проекта
{
  "autoDocstring.docstringFormat": "google",
  "autoDocstring.startOnNewLine": false,
  "autoDocstring.includeName": false,
  "autoDocstring.guessTypes": true,
  "autoDocstring.quoteStyle": "\"\"\""
}
Файл .vscode/settings.json проекта, открытый в VS Code: параметры autoDocstring и путь к интерпретатору
Тот же файл, открытый в редакторе. Формат задан значением google, три следующих параметра управляют видом заготовки, последняя строка указывает путь к интерпретатору окружения проекта.

Значение параметра docstringFormat выбирается из перечня форматов расширения:

ЗначениеЧто вставляет
googleРазделы Args:, Returns:, Raises: — формат курса
google-notypesТо же без повтора типов в скобках
numpyЗаголовки разделов с чертой из дефисов
sphinxПоля :param:, :returns:, :raises:
pep257Краткая строка и место под описание, без разделов
one-line-sphinxПоля reStructuredText в сжатой записи

Для проектов курса подходит google-notypes: типы остаются в подписи функции и в докстринге не повторяются. Начать можно с google и убирать типы вручную, пока формат не стал привычным.

§5Где лежат настройки

У VS Code два уровня настроек. Настройки проекта лежат в папке .vscode рядом с кодом и действуют на всех, кто откроет этот репозиторий. Настройки пользователя действуют на все проекты этого компьютера и в репозиторий не попадают.

УровеньФайлКогда применять
Проект.vscode/settings.json в корне репозиторияФормат докстрингов, правила проверки — общие для команды
Пользователь %APPDATA%\Code\User\settings.json ~/Library/Application Support/Code/User/settings.json ~/.config/Code/User/settings.json Личные привычки: тема, шрифт, сочетания клавиш

Оба файла открываются через палитру команд: Preferences: Open Workspace Settings (JSON) для проекта и Preferences: Open User Settings (JSON) для пользователя. Путь при этом искать не нужно.

На полях: папку .vscode держат в репозитории

В .gitignore учебных проектов .vscode/ не вносят. Файл настроек проекта — часть договорённостей команды: формат докстрингов, включённые проверки, выбранный интерпретатор. Личные настройки в этот файл не пишут, для них есть настройки пользователя.

§6Полезные параметры генератора

ПараметрЗначениеЧто меняет
autoDocstring.docstringFormatgoogleРазметка разделов
autoDocstring.startOnNewLinefalseКраткая строка начинается сразу после кавычек, как требует PEP 257
autoDocstring.includeNamefalseИмя функции в докстринг не подставляется
autoDocstring.guessTypestrueТипы берутся из аннотаций и значений по умолчанию
autoDocstring.includeExtendedSummaryfalseНе вставляет пустой блок под подробное описание
autoDocstring.generateDocstringOnEntertrueРаботает вставка по трём кавычкам и Enter
autoDocstring.customTemplatePathпуть к файлуПодключает свой шаблон вместо встроенного

§7Свой шаблон

Встроенные форматы меняются через шаблон на языке mustache: в нём подстановки вида {{name}} заменяются данными из подписи функции. Шаблон кладут в репозиторий и указывают путь в настройках проекта.

.vscode/docstring.mustacheсвой шаблон
{{summaryPlaceholder}}
{{#parametersExist}}

Args:
{{#args}}
    {{var}}: {{descriptionPlaceholder}}
{{/args}}
{{/parametersExist}}
{{#exceptionsExist}}

Raises:
{{#exceptions}}
    {{type}}: {{descriptionPlaceholder}}
{{/exceptions}}
{{/exceptionsExist}}
{{#returnsExist}}

Returns:
    {{descriptionPlaceholder}}
{{/returnsExist}}
.vscode/settings.jsonподключение шаблона
{
  "autoDocstring.customTemplatePath": ".vscode/docstring.mustache"
}

Этот шаблон отличается от встроенного google одним: типы в разделе Args: не подставляются, потому что они уже есть в подписи. Разделы Args:, Raises: и Returns: вставляются только тогда, когда у функции есть параметры, raise в теле и возвращаемое значение.

§8Сниппет вместо расширения

Заготовку можно вставлять и средствами самого редактора, без расширения. Сниппет — шаблон текста, который вставляется по короткому слову и клавише Tab. Сниппеты проекта лежат в файле с расширением .code-snippets в папке .vscode.

.vscode/python.code-snippetsсниппет по слову dsg
{
  "Докстринг в формате Google": {
    "scope": "python",
    "prefix": "dsg",
    "body": [
      "\"\"\"${1:Действие функции одним предложением.}",
      "",
      "Args:",
      "    ${2:параметр}: ${3:ограничения и смысл}",
      "",
      "Returns:",
      "    ${4:что означает результат}",
      "\"\"\""
    ],
    "description": "Заготовка докстринга с разделами Args и Returns"
  }
}

Наберите dsg и нажмите Tab — вставится этот текст, курсор встанет в первое поле, переход между полями по Tab. Имена параметров сниппет не подставляет: он вставляет заранее записанный текст, одинаковый для любой функции. Зато установки он не требует и работает в любой сборке редактора.

§9Проверка докстрингов программой

Генератор вставляет разметку, но не показывает места, где описания нет. Их находит проверка кода. В курсе используется Ruff — программа проверки кода на Python, в которую входят правила pydocstyle: они отвечают за докстринги и обозначаются кодами с буквой D.

Правила включаются в файле pyproject.toml в корне проекта:

pyproject.tomlвключение правил о докстрингах
[tool.ruff.lint]
select = ["E", "F", "D"]

[tool.ruff.lint.pydocstyle]
convention = "google"

[tool.ruff.lint.per-file-ignores]
"tests/*" = ["D"]

Три части этого файла означают следующее. Набор "D" включает правила о докстрингах вместе с обычными проверками кода. Строка convention = "google" согласует правила с выбранным форматом: часть правил, относящихся к другим форматам, отключается, чтобы требования не противоречили друг другу. Последний раздел снимает требование докстрингов с папки тестов: имя тестовой функции там само описывает проверяемый случай.

Терминалзапуск проверки
$ ruff check app --output-format=concise
Встроенный терминал VS Code с выводом ruff check: десять замечаний с кодами D100, D103 и D104
Вывод в терминале, встроенном в редактор, на стартовом архиве темы. В каждой строке файл, номер строки и колонки, код правила и его название. Последняя строка — Found 33 errors.: столько мест в проекте пока без описаний. Без ключа --output-format=concise Ruff печатает то же самое подробнее, с фрагментом кода под каждым замечанием.

По коду правила его находят в документации Ruff, где описано, что оно проверяет и как исправить.

§10Правила, которые чаще срабатывают

КодЧто проверяетКак исправить
D100Нет докстринга у модуляДобавить описание первой строкой файла
D101Нет докстринга у классаОписать, что представляет объект
D102Нет докстринга у публичного методаОписать действие метода
D103Нет докстринга у публичной функцииДобавить описание после def
D104Нет докстринга у пакетаДобавить описание в __init__.py
D200Описание из одной строки записано в триСвести к """Текст."""
D205Нет пустой строки между краткой строкой и подробностямиВставить пустую строку
D209Закрывающие кавычки не на своей строкеПеренести кавычки вниз
D210Лишние пробелы вокруг текста в кавычкахУбрать пробелы
D415Первая строка не заканчивается знаком препинанияПоставить точку
D417В разделе Args: описаны не все параметрыДописать пропущенные или убрать лишние

Как это выглядит на коде проекта — четыре случая с настоящим выводом проверки:

Какое правило сработаетчетыре случая из проекта

app/utils/formatter.pyкак написано
def format_title(text: str, width: int = 40) -> str:
    return text.center(width, "=")
вывод ruff check
Терминал--output-format=concise
formatter.py:1:1: D100 Missing docstring in public module
formatter.py:1:5: D103 Missing docstring in public function

ИсправлениеДобавить докстринг модуля первой строкой файла и докстринг функции сразу после def.

app/utils/formatter.pyкак написано
    """Центрирует заголовок отчёта
    Достраивает строку знаками «=» до нужной ширины.
    """
вывод ruff check
Терминал--output-format=concise
formatter.py:5:5: D205 1 blank line required between summary
line and description

ИсправлениеПоставить точку в конце краткой строки и отделить её от пояснения пустой строкой.

app/services/orders.pyу функции два параметра
    """Считает выручку по официантам.

    Args:
        orders: Заказы за смену.

    Returns:
        Выручка по именам.
    """
вывод ruff check
Терминал--output-format=concise
orders.py:4:5: D417 Missing argument description in the
docstring for `revenue_by_waiter`: `top`

ИсправлениеДописать в раздел Args: строку про top. Это правило сравнивает докстринг с подписью функции, поэтому находит расхождение после правки кода.

app/utils/clock.pyкак написано
    """
    Возвращает дату для шапки отчёта
    """
вывод ruff check
Терминал--output-format=concise
clock.py:5:5: D200 One-line docstring should fit on one line
clock.py:5:5: D212 Multi-line docstring summary should start
at the first line
clock.py:5:5: D415 First line should end with a period,
question mark, or exclamation point

ИсправлениеСвести к одной строке и поставить точку: """Возвращает дату для шапки отчёта.""". У D212 есть готовое исправление в меню быстрых действий.

Правило D417 отличается от остальных тем, что сравнивает докстринг с кодом: перечень параметров в разделе Args: с подписью функции. Добавленный аргумент, для которого забыли строку описания, находится сразу. Остальные правила проверяют наличие описания и его оформление.

У части замечаний есть готовое исправление. Пример: заготовка генератора оставляет краткую строку _summary_ без точки на конце, и правило D415 предлагает её поставить.

Меню Quick Fix в VS Code на строке докстринга: первый пункт — Ruff (D415): Add closing punctuation
Курсор стоит на краткой строке докстринга, открыто меню быстрых исправлений. Первый пункт — Ruff (D415): Add closing punctuation: он допишет точку. Второй отключает правило для этой строки; им пользуются, когда правило мешает по делу, и вместе с ним в код попадает комментарий noqa. Вызывается меню сочетанием CtrlCmd + . или из палитры командой Quick Fix.
На полях: правило про повелительную форму

Среди правил pydocstyle есть D401: первая строка докстринга записывается повелительной формой английского глагола. Конвенция google это правило не включает, и для русских описаний в форме «Считает…», «Возвращает…» замечаний не будет. Текущий перечень правил, входящих в конвенцию, приведён в документации Ruff по ссылке в конце главы.

§11Проверка в редакторе и в запросе на слияние

Чтобы замечания появлялись во время набора кода, ставят расширение Ruff, его идентификатор — charliermarsh.ruff. После установки нарушения подчёркиваются в файле и перечисляются в панели Problems (CtrlCmd + Shift + M), а часть из них исправляется действием Quick Fix по сочетанию CtrlCmd + ..

Панель Problems в VS Code: три замечания Ruff с кодами D100 и D103 для файла formatter.py
Панель Problems для открытого файла formatter.py. Замечания подписаны источником: Ruff(D100) — нет докстринга у модуля, Ruff(D103) — у двух функций. Справа в скобках строка и колонка; щелчок по строке открывает это место в файле. Цифра 3 рядом с именем файла в проводнике — то же число замечаний.

Путь пропущенного описания

1 · Код Функция дописана, докстринг забыт. программа работает
2 · Редактор Расширение Ruff подчёркивает строку def и пишет замечание в панель Problems. видно сразу
3 · Терминал ruff check app печатает файл, строку и код правила. перед коммитом
4 · Запрос на слияние Та же команда выполняется на стороне репозитория и отмечает проверку непройденной. до разбора работы

Шаги 2 и 3 зависят от одного файла настроек — pyproject.toml, поэтому редактор и терминал показывают одинаковые замечания.

Та же команда запускается в проверках запроса на слияние. Шаг Ruff стоит там следом за шагом mypy, который проверяет типы:

.github/workflows/checks.ymlшаги проверки
      - name: Проверка типов
        run: mypy app
      - name: Проверка кода и докстрингов
        run: ruff check app
      - name: Тесты
        run: python -m pytest -q

После этого отсутствие докстринга у публичной функции попадает в замечания к запросу на слияние так же, как функция без аннотаций или лишний импорт. Подробно устройство таких проверок разбирается в разделе про CI; здесь важен состав: один запуск ruff check покрывает и оформление кода, и наличие описаний, а типы проверяет mypy.

§12Мини-практика: десять минут

  1. Установите расширение njpwerner.autodocstring через панель расширений.
  2. Создайте в проекте файл .vscode/settings.json с параметрами из §4.
  3. Откройте функцию без докстринга, поставьте курсор под подписью, наберите три кавычки и нажмите Enter. Заполните вставленные поля, переходя по Tab.
  4. Добавьте в pyproject.toml разделы из §9 и выполните ruff check app. Разберите каждое замечание по таблице §10.
  5. Исправьте замечания и добейтесь вывода All checks passed!.
  6. Добавьте в функцию новый параметр, не дописывая раздел Args:, и запустите проверку снова: появится D417. Верните докстринг в соответствие с подписью.

§13Частые вопросы

Обычно думаютРасширение создаёт документацию за разработчика.
На самом делеРасширение вставляет разметку и имена параметров из подписи. Описания остаются полями _description_, и текст в них пишет человек.
Обычно думаютПроверка Ruff показывает, что докстринг правильный.
На самом делеПроверка находит отсутствие докстринга, нарушения оформления и расхождение списка параметров с подписью. Верность описания по смыслу она не проверяет: докстринг с текстом _description_ для неё в порядке.
Обычно думаютНастройки редактора у каждого свои, в репозиторий их класть не нужно.
На самом делеФормат докстрингов и набор правил проверки — договорённость команды, и хранится она в .vscode/settings.json и pyproject.toml внутри репозитория. Личные настройки остаются в настройках пользователя.
Обычно думаютРаз есть генератор, докстринги можно расставить в конце разработки одним проходом.
На самом делеГенератор подставляет имена и разметку, а смысл описания восстанавливается чтением собственного кода. Пока функция в работе, эти сведения есть; через месяц их приходится выяснять заново.

§14Проверьте себя

Что вставляет autoDocstring и что остаётся человеку?

Расширение вставляет разметку выбранного формата, имена параметров из подписи, признак необязательности со значением по умолчанию, раздел Raises: при наличии raise в теле и раздел результата. Человек пишет краткую строку и описания на месте полей _description_.

Чем настройки проекта отличаются от настроек пользователя?

Настройки проекта лежат в .vscode/settings.json внутри репозитория и действуют у всех, кто его откроет: туда пишут формат докстрингов и общие правила. Настройки пользователя лежат в папке профиля VS Code, действуют на все проекты этого компьютера и в репозиторий не попадают.

Зачем в pyproject.toml строка convention = "google"?

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

Что находит правило D417 и чем оно отличается от остальных?

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

Почему с папки тестов снимают требование докстрингов?

Имя тестовой функции описывает проверяемый случай: test_average_empty_list_raises. Отдельное описание повторяло бы имя. Поэтому в настройках проверки для папки тестов правила D отключают.

Проверка ruff check прошла без замечаний. Означает ли это, что документация в порядке?

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

§15Шпаргалка по главе

Расширения njpwerner.autodocstring charliermarsh.ruff
Вставить заготовку """ и Enter Cmd/Ctrl+Shift+2 палитра: Generate Docstring
Настройки проекта .vscode/settings.json autoDocstring.docstringFormat значение google
Правила проверки pyproject.toml select = ["D"] convention = "google"
Запуск ruff check app панель Problems Quick Fix: Cmd/Ctrl+.
Частые коды D100, D103 — нет описания D205 — нет пустой строки D417 — параметр без описания

Итог главы

Редактор с расширением Python показывает докстринг в подсказке, но заготовку по подписи не создаёт: для этого ставят расширение njpwerner.autodocstring. Оно вставляет разметку выбранного формата, имена параметров, признак необязательности и раздел исключений; описания пишет человек. Формат задают в .vscode/settings.json внутри репозитория, потому что это договорённость команды. Свой шаблон подключают файлом mustache, а простую заготовку можно получить сниппетом редактора без установки расширений. Пропущенные и неверно оформленные докстринги находит проверка: правила pydocstyle включаются в pyproject.toml набором "D" с конвенцией google и запускаются командой ruff check в редакторе и в проверках запроса на слияние. Правило D417 сравнивает перечень параметров в докстринге с подписью функции. Верность описания по смыслу проверяет человек. В следующей главе всё это применяется к своему проекту: практика на паре и домашнее задание.

Откуда взяты факты
  1. Параметры, сочетания клавиш и перечень форматов расширения — страница autoDocstring в каталоге расширений VS Code.
  2. Уровни настроек и расположение файла настроек пользователя — документация VS Code, раздел Settings.
  3. Правила pydocstyle, их коды и конвенции — документация Ruff, перечень правил pydocstyle.
  4. Синтаксис сниппетов — документация VS Code, Snippets.
Глава 4.10 · VS Code: генератор и проверка · МДК.01.01 Автор: Макаров Максим Николаевич