Перекладайте повні повідомлення
за допомогою 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 3.14 або новіший. Рендеринг не має залежностей — він використовує
gettext зі стандартної бібліотеки й нічого більше.
Видобування та перевірка каталогів працюють через Babel, тож установіть цей
extra там, де запускається pybabel — зазвичай це середовище розробки чи CI,
а не продакшн-образ:
Куди йти далі¶
Почніть звідси — досвід із 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 вітаються — альфа є саме тим часом, коли про інтерфейс ще варто сперечатися.
Долучайтеся до спільноти¶
- Оберіть good first issue для обмеженого за обсягом внеску.
- Ставте запитання щодо використання у Q&A Discussions.
- Приносьте продакшн-досвід із gettext та ідеї щодо API в Ideas Discussions.
- Перед відкриттям pull request прочитайте посібник для учасників.