Dev48
ЯЗЫК
  • О нас
  • Услуги
  • Индустрии
  • Технологии
  • Статьи
  • Контакты
Забронировать звонок
    Главная/Статьи/Pep 846 stroki dokumentatsii dlya psevdonimov tipov
Dev48

© 2026 · All rights reserved.

PEP 846: Строки документации для псевдонимов типов

Источник: Python Enhancement Proposals (PEPs)

PEP 846: Строки документации для псевдонимов типов

Источник: Python Enhancement Proposals (PEPs)

Данный PEP предлагает сохранять строковый литерал, следующий непосредственно за оператором type, в качестве атрибута __doc__ результирующего объекта псевдонима типа, предоставляя доступ к этой документации через a t и отображая её через pydoc и help(). Это соответствует размещению, уже поддержива…

25 сентября 2026 г.
  • Аннотация
  • Мотивация
  • Спецификация Размещение строки документации Поведение во время выполнения Оптимизация Поддержка AST Поддержка стандартной библиотеки
  • Размещение строки документации
  • Поведение во время выполнения
  • Оптимизация
  • Поддержка AST
  • Поддержка стандартной библиотеки
  • Обоснование
  • Обратная совместимость
  • Вопросы безопасности
  • Как этому обучать
  • Эталонная реализация
  • Отклоненные идеи Сохранение строкового оператора
  • Сохранение строкового оператора
  • Благодарности
  • История изменений
  • Авторские права

Аннотация

Данный PEP предлагает сохранять строковый литерал, следующий непосредственно за оператором type, в качестве атрибута __doc__ результирующего объекта псевдонима типа, предоставляя доступ к этой документации через ast и отображая её через pydoc и help(). Это соответствует размещению, уже поддерживаемому инструментами документации на основе исходного кода. Парсер сохраняет строку документации в новом необязательном поле doc в ast.TypeAlias вместо создания отдельного узла ast.Expr для неё. Функция ast.get_docstring() извлекает строки документации псевдонимов из этого поля.

Мотивация

Несколько широко используемых инструментов разработки уже распознают строки документации, следующие за объявлениями псевдонимов типов. Pyright поддерживает строки документации после операторов type (с 2023 года), директива autotype в Sphinx документирует псевдонимы и их строки документации (с 2025 года), а Pylint распознает эти строки как документацию (с 2023 года).

Например, псевдоним может пояснить, как вызывающие стороны должны интерпретировать его значения:

Вызов help(Timeout) отображает общую информацию об объекте TypeAliasType, а не строку документации псевдонима. Инструменту, которому нужна документация псевдонима, приходится находить и анализировать его исходный код, который может быть недоступен после установки или когда псевдоним передается из другого компонента.

Оператор type, представленный в PEP 695, создает выделенный объект времени выполнения. Этот объект может содержать собственную документацию, как функции и классы. Сохранение строки документации сделало бы её доступной непосредственно из импортированного псевдонима, включая случаи, когда псевдоним переэкспортируется.

Документация времени выполнения также может использоваться сторонними фреймворками. Фреймворки, которые уже распознают TypeAliasType (например, Pydantic), могут использовать __doc__ в качестве описательных метаданных. Подобные интеграции остаются на усмотрение этих проектов.

Спецификация

Размещение строки документации

PEP 257 определяет соглашение о размещении строк документации атрибутов непосредственно после присваиваний, а строки, следующие за другой строкой документации, называет «дополнительными строками документации». Данный PEP использует то же соглашение о размещении для операторов type: строковый литерал, следующий непосредственно за оператором, становится строкой документации псевдонима.

Если следующей логической строкой после оператора type в том же блоке является оператор выражения, состоящий из строкового литерала, эта строка является строкой документации псевдонима и частью оператора type. Комментарии и пустые строки могут присутствовать между оператором type и его строкой документации. Строковый литерал на той же строке, что и псевдоним, отделенный точкой с запятой, не подходит.

Правило применяется везде, где разрешен оператор type, включая функции, классы и блоки управления потоком. Строка должна находиться в том же блоке, что и псевдоним. Строка во вложенном или объемлющем блоке не подходит. Обобщенные псевдонимы следуют тому же правилу:

Как и в случае с модулями, функциями и классами, строка документации должна быть оператором выражения, значением которого является строковая константа. Соседние строковые литералы, объединенные парсером, подходят, как и строковый литерал в скобках. Байтовые литералы, f-строки, t-строки и выражения типа "первая" + "вторая" не подходят, даже если компиляция может свести выражение к константной строке.

Только первый следующий строковый оператор предоставляет __doc__. Дополнительные строки документации в смысле PEP 257 остаются обычными операторами выражений. Они не конкатенируются и не присваиваются псевдониму.

Поведение во время выполнения

Псевдоним хранит свою строку документации в __doc__. У недокументированного псевдонима __doc__ равен None. Доступ к этому атрибуту не вычисляет значение псевдонима.

Компиляция применяет ту же обработку пробельных символов в строках документации, что и для строк документации функций и классов. Это расширяет табуляции и очищает отступы, сохраняя при этом окружающие пустые строки. inspect.cleandoc() также удаляет окружающие пустые строки.

После создания псевдонима его атрибут __doc__ может быть переназначен. Удаление атрибута сбрасывает его в None. Конструктор TypeAliasType получает параметр doc, доступный только по ключевому слову, со значением по умолчанию None, который инициализирует __doc__ без обработки пробельных символов:

Это предложение не требует изменений в поведении статических анализаторов типов. Строка документации псевдонима не влияет на его значение для анализатора типов или на то, как его значение вычисляется во время выполнения.

Оптимизация

Уровень оптимизации 2, выбранный с помощью -OO или compile(..., optimize=2), удаляет строки документации псевдонимов так же, как он удаляет строки документации функций и классов. Результирующий псевдоним имеет __doc__, равный None. В AST предварительная обработка очищает поле doc в ast.TypeAlias. Уровни оптимизации 0 и 1 сохраняют строку документации.

Присваивания к __doc__ остаются обычными присваиваниями времени выполнения и не удаляются при -OO.

Поддержка AST

Грамматика оператора type получает необязательную завершающую строку документации, показанную схематично:

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

Этот PEP добавляет необязательное строковое поле doc в конец ast.TypeAlias (name, type_params, value, doc). Пропущенное поле doc по умолчанию равно None.

Когда строки документации сохраняются, ast.parse() заполняет это поле исходной строкой до обработки пробельных символов при компиляции. Строка документации не появляется как следующий оператор Expr(Constant(...)). Конечная позиция узла охватывает строку документации:

ast.get_docstring() принимает узлы TypeAlias. Как и для типов узлов, которые он уже поддерживает, поведение по умолчанию очищает строку документации с помощью inspect.cleandoc(). При clean=False функция возвращает исходную строку. Она возвращает None для недокументированного псевдонима.

И ast.dump(), и AST repr() отображают строку документации в поле doc. По умолчанию ast.dump() опускает поле, если его значение равно None, как и для других необязательных полей.

Генерация кода считывает поле doc и не проверяет соседние операторы. Для программно созданных узлов ast.TypeAlias поле doc предоставляет строку документации псевдонима. ast.unparse() выводит строку документации как строковый оператор на строке после псевдонима, чтобы парсинг результата снова заполнил поле.

Поддержка стандартной библиотеки

pydoc, включая help(), будет распознавать псевдонимы типов и отображать их собственную документацию. Псевдонимы также будут отличаться от других членов данных в документации модуля. Это относится как к текстовому выводу, так и к выводу в формате HTML.

Для начального примера эталонная реализация отображает:

doctest обнаруживает строки документации псевдонимов типов в модулях и классах, а также принимает объекты псевдонимов типов в словаре __test__ модуля. Как и в случае с функциями и классами, псевдонимы, импортированные из других модулей, исключаются из автоматического обнаружения. Обнаружение не вычисляет значения псевдонимов.

Обоснование

Размещение строки после объявления соответствует соглашению, уже используемому инструментами для псевдонимов типов и описанному для строк документации атрибутов в PEP 257. Существующие задокументированные псевдонимы получат документацию во время выполнения без необходимости их переписывания авторами.

Хранение строки документации в поле doc узла псевдонима позволяет ast.get_docstring() извлекать её без поиска по окружающим операторам. Инструменты, которые проверяют или изменяют строки документации псевдонимов, могут напрямую считывать или обновлять это поле. Цена этого — изменение AST, описанное в разделе «Обратная совместимость».

Обратная совместимость

Ранее строковый литерал, следующий непосредственно за оператором type, не оказывал никакого влияния во время выполнения. Согласно этому предложению, подходящая строка становится __doc__ псевдонима и удаляется из AST как отдельный оператор ast.Expr. Строка сохраняется в поле doc узла псевдонима, а конечная позиция узла расширяется, чтобы охватить её.

Инструментам, которые находят строки документации псевдонимов, просматривая следующий оператор, или которые полагаются на конечную позицию узла псевдонима, потребуется корректировка при парсинге с помощью Python 3.16. ast.TypeAlias получает четвертое, необязательное поле. Создание узла с тремя позиционными аргументами продолжит работать.

Последствия для безопасности

Данный PEP не имеет известных последствий для безопасности.

Как обучать этому

Справочная документация по оператору type должна демонстрировать строку документации сразу после объявления, отмечать, что принятые формы соответствуют строкам документации функций и классов, а затем показывать Alias.__doc__ и help(Alias). Документация typing.TypeAliasType должна описывать новый атрибут и способы его назначения для псевдонимов, созданных с помощью конструктора.

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

Документация для ast.TypeAlias и ast.get_docstring() должна объяснять, как читать и изменять поле doc и как обрабатываются пробельные символы. Также следует отметить, что строка документации больше не имеет отдельного узла ast.Expr.

Эталонная реализация

Прототип CPython доступен в следующих ревизиях:

  • Поддержка компилятора, среды выполнения и AST.
  • Поддержка pydoc.
  • Обнаружение doctest.

Правило грамматики для оператора type получает необязательную группу, которая парсит оператор выражения на следующей логической строке. Правило type_alias_docstring[expr_ty] использует вспомогательное действие, которое возвращает узел выражения, если это строковая константа. В противном случае вспомогательная функция возвращает NULL без установки ошибки. Это приводит к сбою необязательной группы, поэтому парсер делает откат до символа новой строки. Пустые строки и строки, содержащие только комментарии, не мешают парсеру распознать строку документации. Строка должна находиться в том же блоке, что и оператор type. Действие псевдонима типа извлекает строковое значение константы и сохраняет его в поле doc.

Реализация pydoc запрашивает выражение псевдонима в строковом формате. Это вычисление может инициировать отложенный импорт. Если вычисление вызывает исключение, pydoc пытается восстановить исходное выражение псевдонима из исходного кода без его вычисления. Если восстановление из исходного кода также не удается, объявление содержит заполнитель с repr() исходного исключения, и рендеринг продолжается со строкой документации. Полная трассировка не включается. Сбои при рендеринге границ, ограничений или значений по умолчанию параметров типа приводят к пропуску этой части объявления.

Отклоненные идеи

Сохранение строкового оператора

Альтернативный дизайн мог бы заключаться в том, чтобы предварительная обработка AST заполняла doc, сохраняя при этом строку как отдельный оператор ast.Expr, следующий за псевдонимом. Существующие инструменты могли бы продолжать проверять этот оператор, но AST содержал бы одну и ту же документацию и в поле, и в операторе. После преобразования AST они могли бы содержать разные строки. Компилятору тогда потребовалось бы правило для выбора того, какую строку использовать. ast.unparse() и compile() также могли бы создавать разные строки документации из одного и того же дерева, если бы использовали разные копии.

При удалении строки документации в режиме -OO предварительная обработка AST также должна была бы предотвращать появление дополнительной строки документации, если дерево будет скомпилировано снова. При распознавании на уровне парсера AST содержит строку документации только в поле doc, поэтому эти правила излишни.

В одном варианте doc ссылался бы на исходный узел Constant. Правки на месте были бы видны через обе ссылки, но посетители (visitors) достигали бы одного и того же узла дважды. Замена узла через одну ссылку оставила бы другую ссылку указывающей на старый узел.

В другом варианте закрытый атрибут содержал бы строку документации, доступную только через ast.get_docstring(). Этот дизайн позволил бы избежать публичного поля, но предварительная обработка AST все равно нуждалась бы в правилах для аннулирования сохраненной документации при изменении окружающих операторов.

Благодарности

Спасибо Jelle Zijlstra за рецензирование предложения и согласие стать спонсором PEP, Guido van Rossum за предложение о том, чтобы парсер распознавал строку документации, а также участникам первоначального обсуждения на Discourse.

Спасибо Peter Bierma и Jakub Romańczuk за то, что убедили меня развивать эту идею.

История изменений

  • 06-сен-2026: Первоначальное предложение и первый черновик PEP.
  • 15-сен-2026: Парсер распознает строку документации как часть оператора type вместо того, чтобы предварительная обработка AST связывала следующий оператор с псевдонимом. AST больше не сохраняет строку как отдельный оператор.

Авторское право

Этот документ передан в общественное достояние или доступен по лицензии CC0-1.0-Universal, в зависимости от того, что является более разрешительным.

← Все статьи

Ещё в разделе «Разработка ПО»

Все →
Новый навык обнаруживает риски ИИ-агентов, устраняет их и доказывает эффективность исправлений
Microsoft

Новый навык обнаруживает риски ИИ-агентов, устраняет их и доказывает эффективность исправлений

Некоторые клиенты Supabase открывают в публичном доступе огромные массивы личных данных пользователейПресса
Supabase

Некоторые клиенты Supabase открывают в публичном доступе огромные массивы личных данных пользователей

Основы Blazor: SEO для веб-приложений на Blazor
Telerik

Основы Blazor: SEO для веб-приложений на Blazor

Вас затронули сокращения? Не упустите возможность приобрести пропуск Expo+ на TechCrunch Disrupt 2026 всего за 75 долларовПресса
Expo

Вас затронули сокращения? Не упустите возможность приобрести пропуск Expo+ на TechCrunch Disrupt 2026 всего за 75 долларов

Последние 24 часа, чтобы сэкономить до 200 долларов на TechCrunch Disrupt 2026. Причина 5 из 5 для участия: ИмпульсПресса
Momentum

Последние 24 часа, чтобы сэкономить до 200 долларов на TechCrunch Disrupt 2026. Причина 5 из 5 для участия: Импульс

Мы создаем Copilot как новую операционную систему для работы, охватывающую любую модель, любой форм-фактор и любую задачу. Сегодня мы объявляем о самом масштабном обновлении Copilot на сегодняшний день, объединяющем четыре компонента [Читать далее]
Microsoft

Мы создаем Copilot как новую операционную систему для работы, охватывающую любую модель, любой форм-фактор и любую задачу. Сегодня мы объявляем о самом масштабном обновлении Copilot на сегодняшний день, объединяющем четыре компонента [Читать далее]

Ещё от Python

PEP 823: Операторы доступа с учетом None
Python

PEP 823: Операторы доступа с учетом None

PEP 824: Операторы объединения с None
Python

PEP 824: Операторы объединения с None

PEP 849: Более выразительные выражения типов
Python

PEP 849: Более выразительные выражения типов

PEP 848: Поколенческая инкрементальная сборка мусора
Python

PEP 848: Поколенческая инкрементальная сборка мусора