Saltar a contenido

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 !r y :.2f bajo 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

python -m pip install gettext-tstrings

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:

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

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