Traduce mensajes completos
con las t-strings de Python¶
gettext-tstrings conecta las t-strings de Python 3.14+ con los catálogos
gettext estándar y las herramientas de Babel. Los valores y el formato se
quedan en el código de la aplicación; los traductores trabajan con mensajes
completos y marcadores {name} sencillos:
import gettext
from gettext_tstrings import Translator
_ = Translator(gettext.translation("messages", localedir="locales"))
name = "Ada"
print(_(t"Hello {name}")) # with a Japanese catalog: こんにちは Ada
El catálogo contiene Hello {name}. Una traducción puede mover o repetir
{name}. Si lo elimina, lo renombra o le añade formato, la validación del
catálogo señala el error. Si aun así una entrada inválida llega a producción,
la biblioteca registra una advertencia y renderiza el mensaje de origen en
lugar de provocar un fallo.
Empieza el tutorial de cinco minutos Compara las alternativas
Alpha · Python 3.14+ · catálogos PO/MO estándar · sin dependencias de terceros en tiempo de ejecución
Este sitio practica lo que documenta: cada edición lingüística
—navegación, etiquetas y el informe de compilación con plurales— se renderiza
desde catálogos PO mediante
el propio gettext-tstrings.
¿Es para ti?¶
Encaja hoy si tu aplicación se ejecuta en Python 3.14 o posterior; ya utilizas gettext y Babel, o quieres adoptar su flujo de trabajo PO/MO; y quieres la sintaxis de las t-strings con marcadores con nombre que se comprueban antes de renderizarse.
Todavía no encaja si necesitas Python 3.13 o anterior; requieres una API de Python estable —esto es una versión alpha, y la especificación es la parte que ya se ha asentado—; o casi todo tu texto traducible vive en un lenguaje de plantillas y no en código Python.
¿Ya tienes catálogos? Siguen funcionando. _("Hello {name}").format(name=name)
y tr(t"Hello {name}") producen el mismo msgid, así que las traducciones
existentes sobreviven al cambio: Migración recorre el traslado
completo.
Qué puede decir el catálogo¶
Una traducción no puede cambiar la estructura del mensaje que traduce. Esa
es toda la promesa, y el resto de este sitio se deriva de ella. Una traducción
puede reordenar o repetir {name}, y puede reescribir todas las demás palabras
que lo rodean. No puede omitir el marcador, inventar uno nuevo, atravesarlo para
llegar a tus objetos ni añadir formato por su cuenta.
La biblioteca lo comprueba a la entrada —cuando se compilan los catálogos— y de nuevo al renderizar, que es la diferencia entre un error encontrado en la revisión y un error encontrado por una persona usuaria.
¿Nuevo en gettext? Todo el flujo de trabajo en cuatro frases
gettext es la forma estándar de traducir software, en Python y mucho
más allá. Tu código marca las cadenas traducibles; un extractor las
recopila en un archivo de plantilla (.pot); un traductor —normalmente no
un programador— rellena un archivo de catálogo (.po) por idioma, que se
compila a un .mo binario que tu aplicación carga en tiempo de ejecución.
El nombre convencional de la función de traducción es _, así que
_(t"Hello {name}") se lee como «traduce esta frase». El
tutorial recorre el camino completo —marcar, extraer,
traducir, compilar, ejecutar— en unos cinco minutos.
El problema que resuelve¶
Una f-string ya está interpolada cuando cualquier biblioteca la recibe:
f"Hello {name}" se ha convertido en "Hello Ada", y traducir los fragmentos
que rodean un valor rompe la gramática de la mayoría de los idiomas. Una
t-string (PEP 750) mantiene separados el texto estático, los valores
evaluados, las expresiones de origen, las conversiones y las especificaciones
de formato: exactamente la separación que necesita un catálogo de mensajes.
Consulta qué cambia respecto a %(name)s, .format() y las
cadenas $.
Sin embargo, ni gettext ni Babel definen cómo convertir una t-string en un mensaje. Esta biblioteca toma esa decisión, la documenta como una especificación versionada e incluye una suite de conformidad para comprobarla.
Las reglas de diseño¶
- Traduce mensajes completos, nunca fragmentos de frases.
- Acepta solo nombres de variable sencillos como
{name}. - Mantiene
!ry:.2fbajo el control de la aplicación, fuera del catálogo. - Permite que las traducciones reordenen y repitan marcadores conocidos, pero les impide acceder a atributos o añadir formato.
- Reutiliza los archivos POT, PO y MO habituales y las herramientas que ya los leen.
Y la lista correspondiente de lo que deja deliberadamente en paz: no localiza números, monedas ni fechas —formatéalos antes, con Babel—; no escapa la salida renderizada para HTML, un intérprete de comandos o un terminal; y no puede juzgar si una traducción es correcta, solo si sus marcadores están intactos.
Instalación¶
Requiere Python 3.14 o posterior. El renderizado no tiene dependencias:
utiliza únicamente el gettext de la biblioteca estándar.
La extracción y la validación de catálogos se ejecutan mediante Babel. Instala
el extra donde se ejecute pybabel, normalmente en desarrollo o CI y no en una
imagen de producción:
Próximos pasos¶
Empieza aquí — sin experiencia previa con gettext:
- Tutorial — de un directorio vacío a una traducción japonesa en funcionamiento en cinco pasos, con la salida de cada comando.
- Por qué usar t-strings — el mismo mensaje escrito de
cuatro formas y qué entregan al catálogo
%(name)s,.format()y las cadenas$.
Úsalo — las referencias de trabajo:
- Guía — la API de ejecución: qué punto de entrada utilizar, plurales, idiomas por petición, cadenas diferidas y qué ocurre cuando un catálogo es incorrecto.
- Extracción — la referencia de
pybabel: configuración, nombres de función propios y cómo las herramientas existentes validan estos catálogos sin coste añadido. - En producción — el ciclo tal como lo ejecuta un equipo: el ciclo de actualización, las entradas fuzzy, las puertas de CI, las plataformas de traducción y la publicación.
- Migración — adoptarlo en un proyecto que ya tiene catálogos, un punto de llamada cada vez.
- Para traductores — una única página para entregar a
quien edita los archivos
.po.
Entiéndelo — de la historia a la implementación:
- Trasfondo — por qué existe esta biblioteca: treinta años de gettext, dos PEP y la discusión sobre la biblioteca estándar que se cerró sin una respuesta.
- Escollos — qué rompió realmente traducir este sitio a treinta y cinco idiomas, y qué mitad puede detectar una herramienta.
- Cómo funciona — del objeto plantilla del PEP 750 a la cadena renderizada, y las cachés que abaratan las comprobaciones.
Referencia — los contratos:
- API — todo lo que exporta el paquete, en una sola página.
- Especificación — la convención t-string ↔ msgid como contrato estable y versionado, con una suite de conformidad legible por máquinas.
Estado¶
| Versión del paquete | 0.1.0a8 |
| Estabilidad de la API | alpha — la API de Python todavía puede cambiar |
| Especificación | v1, con una suite de conformidad |
| Python | 3.14 y posteriores; probado en 3.14, 3.14t (free-threaded) y 3.15 |
| Babel | 2.18 o posterior, y solo donde se ejecute pybabel |
| Dependencias en tiempo de ejecución | ninguna — el gettext de la biblioteca estándar |
| Formato de catálogo | POT, PO y MO corrientes |
| Cambios | CHANGELOG |
Es una versión alpha. El contrato es pequeño a propósito y la especificación es su parte estable; la API de Python todavía puede cambiar. Antes de una versión estable se necesitan fixtures en más idiomas, seguimiento continuo del rendimiento, revisión de la API por personas que utilizan gettext y Babel de forma habitual, y pruebas de compatibilidad con cada versión compatible de Python y Babel.
Se agradecen los Issues y Pull Requests: una versión alpha es precisamente el momento en el que aún merece la pena debatir la interfaz.
Únete a la comunidad¶
- Elige un good first issue para una contribución de alcance acotado.
- Haz preguntas de uso en Q&A Discussions.
- Comparte flujos de gettext en producción e ideas para la API en Ideas Discussions.
- Lee la guía de contribución antes de abrir un Pull Request.