Contexte¶
Cette bibliothèque se situe au point de rencontre de deux longues histoires — l'une sur la façon dont les logiciels sont traduits, l'autre sur la façon dont Python interpole les chaînes — qui se sont enfin croisées en 2025, puis se sont arrêtées exactement là où une convention petite et soignée devenait nécessaire. Cette page raconte les deux histoires, avec des liens vers les sources, parce que les décisions de conception de ce site se jugent plus facilement quand on voit les questions auxquelles elles répondent.
L'écosystème gettext¶
GNU gettext est la manière dont le logiciel libre se traduit depuis le
milieu des années 1990 : marquer les chaînes dans le code, les extraire dans
un fichier modèle, donner aux traducteurs un fichier catalogue par langue,
compiler, charger à l'exécution. Autour de cette boucle a grandi tout un
écosystème — éditeurs PO, workflows de relecture et plateformes de traduction
qui parlent tous le même format de fichier — et Python embarque un
module gettext dans sa bibliothèque standard depuis plus
de deux décennies. La moitié « exécution » de la traduction n'a jamais été le
problème.
La moitié restée en suspens a toujours été l'allure de la chaîne dans le
catalogue. Un message %(name)s confie aux traducteurs une syntaxe printf
qu'une seule lettre supprimée transforme en plantage en production ; un
message .format() confie au catalogue l'accès aux attributs d'objets
vivants. (Pourquoi les t-strings parcourt les deux, avec les
défaillances à l'appui.) Et les f-strings — la syntaxe que préfère désormais
la plupart du code Python — ne peuvent pas du tout participer : lorsqu'une
bibliothèque en voit une, c'est déjà une chaîne terminée. On essaie quand
même, assez souvent pour que le gestionnaire d'issues de Babel collectionne
les tentatives (#594, #715) ; l'échec est
structurel, pas une fonctionnalité manquante.
Deux PEP, à dix ans d'écart¶
En 2015, Alyssa Coghlan et Nick Humrich écrivent la PEP 501, qui propose des modèles d'interpolation dont la première motivation déclarée était l'i18n — « providing a cleaner syntax for i18n translation », selon les propres mots de la PEP. La proposition fut différée, en partie parce que la discussion montrait que le cas de l'i18n soulevait des considérations supplémentaires importantes que des usages plus simples n'avaient pas.
Une décennie plus tard, la PEP 750 — de Jim Baker, Guido van Rossum, Paul Everitt, Koudai Aono, Lysandros Nikolaou et Dave Peck — reprend l'idée sous la forme des t-strings, est acceptée en avril 2025 et arrive dans Python 3.14 en octobre 2025. La PEP 501 est alors retirée en sa faveur. Un détail compte pour cette page : l'i18n ne figure pas parmi les motivations déclarées de la PEP 750. La PEP a généralisé le mécanisme — un type de template que n'importe quelle bibliothèque peut consommer — et a laissé la question de la traduction exactement là où la PEP 501 l'avait garée dix ans plus tôt : ouverte.
Ainsi, à partir de Python 3.14, le langage disposait précisément de la structure de données dont un catalogue de messages a besoin, et d'aucune convention pour l'utiliser comme telle.
La discussion sur la bibliothèque standard¶
Deux mois avant la sortie de 3.14, Adrian Mönnich (ThiefMaster, mainteneur du
projet Indico) propose de combler ce manque dans la bibliothèque standard
elle-même : le fil Support t-strings in gettext sur
discuss.python.org, ouvert en août 2025, s'accompagnait d'une
pull request fonctionnelle ajoutant la prise en charge des
t-strings à gettext et à pygettext.
Le fil mérite d'être lu en entier, parce qu'il fait apparaître chaque question difficile à laquelle cette bibliothèque a ensuite dû répondre :
- Que peut être une interpolation ? Un nom simple seulement, ou des attributs et des appels avec un nom de marqueur dérivé ? Chaque réponse échange de la commodité contre la stabilité des msgid et la sûreté du catalogue.
- Qu'exigent les formes plurielles, lorsque le système de pluriels de la langue cible diffère de celui de la source ?
- gettext est-il seulement la bonne cible ? Barry Warsaw — qui avait
soutenu, pendant l'élaboration de la PEP 750, que les t-strings ne
convenaient pas à l'i18n — renvoyait à son
flufl.i18net à son style de chaînes$comme outil plus accueillant ; d'autres plaidaient pour abandonner gettext au profit de systèmes plus récents tels que Fluent. - Et la méta-question : quoi que la bibliothèque standard publie, elle ne peut pour ainsi dire plus jamais le changer. Une convention comportant autant de choix ouverts est une chose risquée à figer du premier coup.
Aucun consensus ne s'est formé. L'issue CPython a été close en « not planned » et la pull request fermée sans être fusionnée en octobre 2025, quelques jours après la sortie de 3.14. La capacité existait dans le langage ; la convention n'avait pas de foyer.
Pourquoi un paquet, d'abord¶
C'est ce manque que ce projet a choisi de combler depuis l'extérieur de la bibliothèque standard, sur un pari délibéré : une convention mûrit plus vite là où elle peut évoluer librement de version en version et gagner l'adoption cas par cas, et la bibliothèque standard — qui doit être juste du premier coup — est l'endroit où une convention devrait aboutir, pas celui où elle devrait s'élaborer.
Concrètement, chaque question contestée du fil a ici une réponse écrite, chacune sur sa propre page :
- Les interpolations sont des noms simples uniquement, si bien que les msgid restent stables et parlants — le guide montre la règle, Fonctionnement en donne les raisons.
- Le formatage reste entièrement hors du catalogue (Pourquoi les t-strings).
- Les pluriels suivent une règle union/intersection qui permet au système de pluriels d'une langue cible de différer de celui de la source (spec §4).
- Un catalogue cassé retombe sur le texte source au lieu de planter, en gardant le contrat de gettext lui-même (le guide).
- Et la convention tout entière est une spécification versionnée accompagnée d'une suite de conformité lisible par machine — écrite pour qu'une autre implémentation, y compris une future implémentation dans la bibliothèque standard, puisse l'adopter telle quelle et interopérer.
La discussion n'est pas terminée, et ce projet y participe ; il n'en est pas le verdict. Si vous avez une expérience de gettext en production qui éclaire ces choix, le même fil et les Discussions de ce dépôt sont les lieux où la discussion se poursuit.
Chronologie¶
| Quand | Ce qui s'est passé |
|---|---|
| milieu des années 1990 | GNU gettext établit le workflow PO/POT/MO que traducteurs et plateformes parlent encore. |
| 2015 | La PEP 501 propose des modèles d'interpolation, avec l'i18n comme première motivation ; différée. |
| 2016 | Les f-strings arrivent dans Python 3.6 — l'interpolation obtient sa syntaxe, et la traduction ne peut pas s'en servir. |
| juil. 2024 | La PEP 750 propose les t-strings. |
| avr. 2025 | La PEP 750 est acceptée ; la PEP 501 est retirée en sa faveur. |
| août 2025 | Le fil Support t-strings in gettext s'ouvre, avec une pull request pour la bibliothèque standard. |
| oct. 2025 | Python 3.14 embarque les t-strings ; l'issue stdlib est close en « not planned ». |
| 2026 | gettext-tstrings sort en alpha, avec la spec v1 et sa suite de conformité. |