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

Перекладайте повні повідомлення
за допомогою t-рядків Python

gettext-tstrings з'єднує t-рядки Python 3.14+ зі стандартними каталогами gettext та інструментами Babel. Значення й форматування лишаються в коді застосунку; перекладачі працюють із повними повідомленнями та простими заповнювачами {name}:

import gettext

from gettext_tstrings import Translator

_ = Translator(gettext.translation("messages", localedir="locales"))
name = "Ada"
print(_(t"Hello {name}"))  # with a Japanese catalog: こんにちは Ada

Каталог містить Hello {name}. Переклад може переставити чи повторити {name}. Якщо він викидає, перейменовує або переформатовує заповнювач, перевірка каталогу повідомляє про помилку. Якщо хибний запис усе-таки дістався продакшну, бібліотека пише попередження й рендерить початкове повідомлення замість аварії.

Почати з п'ятихвилинного підручника Порівняти альтернативи

Альфа · Python 3.14+ · стандартні каталоги PO/MO · без сторонніх залежностей часу виконання

Цей сайт застосовує те, що документує: кожне мовне видання — навігація, підписи та звіт збірки з формами множини — рендериться з PO-каталогів самою gettext-tstrings.

Чи це для вас?

Підходить уже сьогодні, якщо ваш застосунок працює на Python 3.14 або новішому; ви вже користуєтеся gettext і Babel або хочете перейти на їхній процес PO/MO; і вам потрібен синтаксис t-рядків з іменованими заповнювачами, які перевіряються до рендерингу.

Поки що не підходить, якщо вам потрібен Python 3.13 чи старіший; вам потрібен стабільний Python API — це альфа, і специфікація є тією її частиною, що вже усталилася; або майже весь ваш перекладний текст живе у мові шаблонів, а не у вихідному коді Python.

Уже маєте каталоги? Вони й далі працюють. _("Hello {name}").format(name=name) і tr(t"Hello {name}") дають той самий msgid, тож наявні переклади переживають перехід — Міграція проводить крізь увесь переїзд.

Що каталогу дозволено казати

Переклад не може змінити структуру повідомлення, яке він перекладає. І це вся обіцянка, а решта цього сайту випливає з неї. Переклад може переставити чи повторити {name} і може переписати кожне інше слово навколо нього. Він не може викинути заповнювач, вигадати новий, дотягнутися крізь нього до ваших об'єктів або додати власне форматування.

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

Уперше бачите gettext? Увесь процес у чотирьох реченнях

gettext — стандартний спосіб перекладу програм, у Python і далеко за його межами. Ваш код позначає перекладні повідомлення; видобувач збирає їх у файл-шаблон (.pot); перекладач — зазвичай не програміст — заповнює один файл каталогу (.po) на мову, який компілюється у двійковий .mo, що його ваш застосунок завантажує під час виконання. Традиційна назва функції перекладу — _, тож _(t"Hello {name}") читається як «переклади це повідомлення». Підручник проходить увесь шлях — позначити, видобути, перекласти, скомпілювати, запустити — приблизно за п'ять хвилин.

Проблема, яку вона розв'язує

f-рядок уже інтерпольований на момент, коли його бачить будь-яка бібліотека — f"Hello {name}" встиг стати "Hello Ada", а переклад фрагментів довкола значення ламає граматику більшості мов. t-рядок (PEP 750) зберігає окремо статичний текст, обчислені значення, вихідні вирази, перетворення та специфікації формату — саме такий поділ і потрібен каталогу повідомлень. Що це змінює порівняно з %(name)s, .format() та $-рядками.

Втім, ніде в gettext чи Babel не сказано, як t-рядок стає повідомленням. Ця бібліотека робить цей вибір, записує його як версіоновану специфікацію і постачає набір тестів відповідності, щоб його перевіряти.

Правила дизайну

  • Перекладати повні повідомлення, а не уривки речень.
  • Приймати лише прості імена змінних, як-от {name}.
  • Тримати !r і :.2f під контролем застосунку, поза каталогом.
  • Дозволяти перекладам переставляти й повторювати відомі заповнювачі, водночас не даючи їм дотягнутися до атрибутів чи додати форматування.
  • Використовувати звичайні файли POT, PO і MO та інструменти, що вже їх читають.

І відповідний перелік того, чого вона свідомо не чіпає: вона не локалізує числа, валюти чи дати — форматуйте їх заздалегідь за допомогою Babel; вона не екранує відрендерений вивід для HTML, оболонки чи термінала; і вона не здатна судити, чи переклад правильний, — лише чи цілі його заповнювачі.

Встановлення

python -m pip install gettext-tstrings

Python 3.14 або новіший. Рендеринг не має залежностей — він використовує gettext зі стандартної бібліотеки й нічого більше.

Видобування та перевірка каталогів працюють через Babel, тож установіть цей extra там, де запускається pybabel — зазвичай це середовище розробки чи CI, а не продакшн-образ:

python -m pip install "gettext-tstrings[babel]"

Куди йти далі

Почніть звідси — досвід із gettext не передбачається:

  • Підручник — від порожнього каталогу до робочого японського перекладу за п'ять кроків, кожна команда показана з її виводом.
  • Навіщо t-рядки — одне повідомлення, записане чотирма способами, і що %(name)s, .format() та $-рядки віддають каталогу.

Використання — робочі довідники:

  • Посібник — API часу виконання: яку точку входу обрати, множина, мова на запит, відкладені рядки і що відбувається, коли каталог хибний.
  • Видобування — довідник із pybabel: налаштування, власні імена функцій і як наявні інструменти безплатно перевіряють ці каталоги.
  • У продакшені — цикл, як його веде команда: цикл оновлення, записи fuzzy, шлюзи CI, платформи перекладу та доставка.
  • Міграція — впровадження цього у проєкті, який уже має каталоги, по одному місцю виклику за раз.
  • Для перекладачів — одна сторінка, яку варто дати тому, хто редагує файли .po.

Як це влаштовано — від історії до реалізації:

  • Передісторія — чому ця бібліотека існує: тридцять років gettext, дві PEP і обговорення у stdlib, закрите без відповіді.
  • Пастки — що насправді зламалося під час перекладу цього сайту тридцятьма п'ятьма мовами і яку половину здатен упіймати інструмент.
  • Як це працює — від об'єкта шаблона PEP 750 до відрендереного рядка та кеші, які роблять перевірку дешевою.

Довідник — контракти:

  • API — усе, що експортує пакет, на одній сторінці.
  • Специфікація — угода t-рядок ↔ msgid як стабільний версіонований контракт із машиночитним набором тестів відповідності.

Стан

Версія пакета 0.1.0a8
Стабільність API альфа — Python API ще може змінюватися
Специфікація v1, із набором тестів відповідності
Python 3.14 і новіші; протестовано на 3.14, 3.14t (free-threaded) та 3.15
Babel 2.18 або новіша, і лише там, де запускається pybabel
Залежності під час виконання немає — gettext зі стандартної бібліотеки
Формат каталогів звичайні POT, PO та MO
Зміни CHANGELOG

Це альфа. Контракт свідомо малий, і специфікація — його стабільна частина; Python API ще може змінюватися. Перед стабільним випуском потрібні ширші мовні фікстури, постійне відстеження продуктивності, огляд API людьми, що серйозно використовують gettext і Babel, та перевірка сумісності з кожною підтримуваною версією Python і Babel.

Issues та pull requests вітаються — альфа є саме тим часом, коли про інтерфейс ще варто сперечатися.

Долучайтеся до спільноти