Перейти до змісту

Передісторія

Ця бібліотека стоїть на перетині двох довгих історій — однієї про те, як перекладають програми, і другої про те, як Python інтерполює рядки, — які нарешті перетнулися 2025 року й зупинилися рівно там, де була потрібна маленька, ретельна угода. Ця сторінка розповідає обидві історії з посиланнями на джерела, бо дизайнерські рішення цього сайту легше оцінювати, коли видно питання, на які вони відповідають.

Екосистема gettext

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

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

Дві PEP, десять років між ними

2015 року Алісса Коґлан і Нік Гамрич написали PEP 501, запропонувавши шаблони інтерполяції, першою заявленою мотивацією яких була i18n — «чистіший синтаксис для перекладу i18n», словами самої PEP. Пропозицію відклали, зокрема тому, що обговорення показало: випадок i18n несе суттєві додаткові міркування, яких простіші сценарії не мали.

Десятиліттям пізніше PEP 750 — авторства Джима Бейкера, Ґвідо ван Россума, Пола Еверітта, Кодая Аоно, Лісандроса Ніколау та Дейва Пека — відродила ідею як t-рядки, була ухвалена у квітні 2025 і вийшла у Python 3.14 у жовтні 2025. PEP 501 тоді відкликали на її користь. Одна деталь важлива для цієї сторінки: i18n не входить до заявлених мотивацій PEP 750. PEP узагальнила механізм — тип шаблона, який може споживати будь-яка бібліотека, — і залишила питання перекладу рівно там, де PEP 501 припаркувала його десятьма роками раніше: відкритим.

Тож станом на Python 3.14 мова мала рівно ту структуру даних, яка потрібна каталогу повідомлень, — і жодної угоди про те, як нею користуватися.

Обговорення у stdlib

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

Гілку варто прочитати цілком, бо вона виносить на поверхню кожне складне питання, на яке цій бібліотеці згодом довелося відповісти:

  • Чим може бути інтерполяція? Лише простим іменем — чи атрибутами й викликами з похідним ім'ям заповнювача? Кожна відповідь розмінює зручність на стабільність msgid і безпеку каталогу.
  • Чого вимагають форми множини, коли система множини цільової мови відрізняється від вихідної?
  • Чи gettext узагалі правильна ціль? Баррі Варшава — який ще під час розробки PEP 750 доводив, що t-рядки погано пасують до i18n, — вказував на свій flufl.i18n та його стиль $-рядків як дружніший інструмент; інші пропонували взагалі залишити gettext позаду на користь новіших систем на кшталт Fluent.
  • І метапитання: хай там що вийде у стандартній бібліотеці, змінити його буде по суті неможливо. Угоду з такою кількістю відкритих виборів ризиковано заморожувати з першої спроби.

Консенсус не склався. Задачу в 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 зі stdlib pull request.
жовт. 2025 Python 3.14 постачає t-рядки; задачу у stdlib закривають як not planned.
2026 gettext-tstrings виходить як альфа зі spec v1 та її набором тестів відповідності.