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

Предыстория

Эта библиотека стоит на пересечении двух долгих историй — одной о том, как переводится программное обеспечение, и другой о том, как Python интерполирует строки, — которые наконец сошлись в 2025 году и остановились ровно в той точке, где требовалось небольшое, тщательно продуманное соглашение. Эта страница рассказывает обе истории со ссылками на источники, потому что проектные решения на этом сайте легче оценивать, когда видны вопросы, на которые они отвечают.

Экосистема gettext

GNU gettext — это то, как свободное программное обеспечение переводится с середины 1990-х: пометить строки в коде, извлечь их в шаблон, дать переводчикам по одному файлу каталога на язык, скомпилировать, загрузить во время выполнения. Вокруг этого цикла выросла целая экосистема — PO-редакторы, процессы рецензирования и платформы перевода, говорящие на одном и том же формате файлов, — а Python уже более двух десятилетий поставляет модуль gettext в стандартной библиотеке. Исполняющая половина перевода никогда не была проблемой.

Нерешённой половиной всегда оставалось то, как выглядит строка в каталоге. Сообщение %(name)s вручает переводчикам синтаксис printf, где одна удалённая буква превращается в сбой в продакшене; сообщение .format() даёт каталогу доступ к атрибутам живых объектов. (Зачем нужны t-строки разбирает оба случая, с наглядными отказами.) А f-строки — синтаксис, который теперь предпочитает большая часть кода на Python, — участвовать не могут вовсе: к моменту, когда любая библиотека видит f-строку, это уже готовая строка. Люди всё равно пытаются — достаточно часто, чтобы трекер задач Babel собирал такие попытки (#594, #715); неудача здесь структурная, а не отсутствующая функция.

Две PEP с разницей в десять лет

В 2015 году Alyssa Coghlan и Nick Humrich написали PEP 501, предложив шаблоны интерполяции, чьей первой заявленной мотивацией была i18n — «providing a cleaner syntax for i18n translation», словами самого PEP. Предложение было отложено — отчасти потому, что обсуждение показало: случай i18n несёт существенные дополнительные соображения, которых нет у более простых сценариев.

Десять лет спустя PEP 750 — за авторством Jim Baker, Guido van Rossum, Paul Everitt, Koudai Aono, Lysandros Nikolaou и Dave Peck — возродил идею в виде t-строк, был принят в апреле 2025 года и вошёл в Python 3.14 в октябре 2025 года. PEP 501 после этого был отозван в его пользу. Для этой страницы важна одна деталь: i18n не входит в заявленные мотивации PEP 750. PEP обобщил механизм — тип шаблона, который может использовать любая библиотека, — и оставил вопрос перевода ровно там, где PEP 501 припарковал его десятью годами раньше: открытым.

Так что начиная с Python 3.14 в языке была ровно та структура данных, которая нужна каталогу сообщений, — и никакого соглашения о том, как её в этом качестве использовать.

Обсуждение в stdlib

За два месяца до выхода 3.14 Adrian Mönnich (ThiefMaster, мейнтейнер проекта Indico) предложил закрыть этот пробел в самой стандартной библиотеке: тема Support t-strings in gettext на discuss.python.org, открытая в августе 2025 года, сопровождалась рабочим pull request, добавляющим поддержку t-строк и в gettext, и в pygettext.

Эту тему стоит прочитать целиком, потому что в ней всплывает каждый трудный вопрос, на который этой библиотеке позже пришлось отвечать:

  • Чем может быть интерполяция? Только простым именем — или атрибутами и вызовами с производным именем заполнителя? Каждый ответ обменивает удобство на стабильность msgid и безопасность каталога.
  • Чего требуют формы множественного числа, когда система множественного числа целевого языка отличается от исходной?
  • А правильная ли цель сам gettext? Barry Warsaw — который ещё при разработке PEP 750 утверждал, что t-строки плохо подходят для i18n, — указывал на свой flufl.i18n и его стиль $-строк как на более дружелюбный инструмент; другие предлагали вовсе оставить gettext ради более новых систем, таких как Fluent.
  • И мета-вопрос: что бы ни вошло в стандартную библиотеку, изменить это по сути уже нельзя. Соглашение с таким количеством открытых выборов — рискованная вещь, чтобы замораживать её с первой попытки.

Консенсус не сложился. Issue в CPython был закрыт как «not planned», а pull request закрыт без слияния в октябре 2025 года, через считанные дни после выхода 3.14. Возможность существовала в языке; у соглашения не было дома.

Почему сначала пакет

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

Конкретно: у каждого спорного вопроса из той темы здесь есть записанный ответ, каждый на своей странице:

  • Интерполяции — только простые имена, чтобы msgid оставались стабильными и осмысленными: руководство показывает правило, Как это работает — причины.
  • Форматирование полностью остаётся вне каталога (Зачем нужны t-строки).
  • Множественное число следует правилу объединения и пересечения, позволяющему системе множественного числа целевого языка отличаться от исходной (spec §4).
  • Повреждённый каталог откатывается вместо сбоя, сохраняя контракт самого gettext (руководство).
  • А всё соглашение целиком — это версионируемая спецификация с машиночитаемым набором тестов соответствия, написанная так, чтобы другая реализация — включая будущую реализацию в стандартной библиотеке — могла принять её без изменений и оставаться совместимой.

Обсуждение не закончилось, и этот проект — его участник, а не вердикт. Если у вас есть продакшен-опыт работы с gettext, имеющий отношение к этим выборам, та же тема и Discussions этого репозитория — те места, где обсуждение продолжается.

Хронология

Когда Что произошло
середина 1990-х GNU gettext закрепляет процесс PO/POT/MO, на котором переводчики и платформы говорят до сих пор.
2015 PEP 501 предлагает шаблоны интерполяции с i18n в качестве первой мотивации; отложен.
2016 f-строки выходят в Python 3.6 — интерполяция получает свой синтаксис, а перевод не может им пользоваться.
июль 2024 PEP 750 предлагает t-строки.
апрель 2025 PEP 750 принят; PEP 501 отозван в его пользу.
август 2025 Открывается тема Support t-strings in gettext, вместе с pull request в stdlib.
октябрь 2025 Python 3.14 выходит с t-строками; issue в stdlib закрывается как not planned.
2026 gettext-tstrings выходит как альфа, со спецификацией v1 и её набором тестов соответствия.