Zum Inhalt

Vollständige Nachrichten übersetzen
mit den t-strings von Python

gettext-tstrings verbindet die t-strings von Python 3.14+ mit gewöhnlichen gettext-Katalogen und dem Babel-Werkzeug. Werte und Formatierung bleiben im Anwendungscode; übersetzende Personen arbeiten mit vollständigen Nachrichten und einfachen {name}-Platzhaltern:

import gettext

from gettext_tstrings import Translator

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

Der Katalog enthält Hello {name}. Eine Übersetzung darf {name} umstellen oder wiederholen. Entfernt, benennt oder formatiert sie den Platzhalter um, meldet die Katalogprüfung den Fehler. Schafft es ein ungültiger Eintrag trotzdem in die Produktion, protokolliert die Bibliothek eine Warnung und rendert die Ursprungsnachricht, statt abzustürzen.

Das Fünf-Minuten-Tutorial starten Die Alternativen vergleichen

Alpha · Python 3.14+ · standardkonforme PO/MO-Kataloge · keine Laufzeitabhängigkeiten von Dritten

Diese Website praktiziert, was sie dokumentiert: Jede Sprachausgabe — Navigation, Beschriftungen und der pluralabhängige Build-Bericht — wird von gettext-tstrings selbst aus PO-Katalogen gerendert.

Ist das etwas für dich?

Heute passend, wenn deine Anwendung auf Python 3.14 oder neuer läuft, du gettext und Babel bereits nutzt oder deren PO/MO-Workflow übernehmen willst, und du t-string-Syntax mit benannten Platzhaltern möchtest, die vor dem Rendern geprüft werden.

Noch nicht passend, wenn du Python 3.13 oder älter brauchst; wenn du eine stabile Python-API benötigst — dies ist eine Alpha, und die Spezifikation ist der bereits gefestigte Teil davon; oder wenn fast dein gesamter übersetzbarer Text in einer Template-Sprache statt im Python-Quelltext steht.

Du hast bereits Kataloge? Sie funktionieren weiter. _("Hello {name}").format(name=name) und tr(t"Hello {name}") erzeugen denselben msgid, sodass vorhandene Übersetzungen den Wechsel überleben — die Migration beschreibt den ganzen Umzug.

Was der Katalog sagen darf

Eine Übersetzung kann die Struktur der Nachricht, die sie übersetzt, nicht verändern. Das ist das ganze Versprechen, und der Rest dieser Website folgt daraus. Eine Übersetzung darf {name} umstellen oder wiederholen und darf jedes andere Wort darum herum neu schreiben. Sie darf den Platzhalter nicht entfernen, keinen neuen erfinden, nicht durch ihn hindurch auf deine Objekte zugreifen und keine eigene Formatierung anhängen.

Die Bibliothek prüft das auf dem Weg hinein — wenn Kataloge kompiliert werden — und noch einmal beim Rendern, und das ist der Unterschied zwischen einem Fehler, der im Review gefunden wird, und einem, den eine nutzende Person findet.

Neu bei gettext? Der ganze Workflow in vier Sätzen

gettext ist der Standardweg, auf dem Software übersetzt wird, in Python und weit darüber hinaus. Dein Code markiert übersetzbare Strings; ein Extraktor sammelt sie in eine Vorlagendatei (.pot); eine übersetzende Person — meist keine Programmiererin — füllt pro Sprache eine Katalogdatei (.po) aus, die zu einer binären .mo kompiliert wird, die deine Anwendung zur Laufzeit lädt. Der konventionelle Name der Übersetzungsfunktion ist _, sodass sich _(t"Hello {name}") als „übersetze diesen Satz“ liest. Das Tutorial geht den gesamten Weg — markieren, extrahieren, übersetzen, kompilieren, ausführen — in etwa fünf Minuten durch.

Welches Problem wird gelöst?

Ein f-string ist bereits interpoliert, bevor ihn eine Bibliothek sieht — aus f"Hello {name}" ist "Hello Ada" geworden, und das Übersetzen der Fragmente um einen Wert herum zerstört die Grammatik der meisten Sprachen. Eine t-string (PEP 750) hält dagegen statischen Text, ausgewertete Werte, Quellausdrücke, Konvertierungen und Formatspezifikationen getrennt — genau die Trennung, die ein Nachrichtenkatalog braucht. Was sich dadurch ändert, verglichen mit %(name)s, .format() und $-Strings.

gettext und Babel definieren jedoch nicht, wie eine t-string in eine Nachricht umgewandelt wird. Diese Bibliothek trifft diese Entscheidung, schreibt sie als versionierte Spezifikation fest und liefert die Konformitätssuite mit, um sie zu prüfen.

Die Entwurfsregeln

  • Vollständige Nachrichten statt Satzfragmenten übersetzen.
  • Nur einfache Variablennamen wie {name} zulassen.
  • !r und :.2f unter Kontrolle der Anwendung und außerhalb des Katalogs halten.
  • Bekannte Platzhalter dürfen umgestellt und wiederholt werden; Attributzugriffe und zusätzliche Formatierung sind nicht erlaubt.
  • Vorhandene POT-, PO- und MO-Dateien sowie deren Werkzeuge weiterverwenden.

Und die dazu passende Liste dessen, was sie bewusst nicht anfasst: Sie lokalisiert weder Zahlen noch Währungen oder Daten — formatiere die vorher mit Babel; sie maskiert gerenderte Ausgabe nicht für HTML, eine Shell oder ein Terminal; und sie kann nicht beurteilen, ob eine Übersetzung richtig ist, sondern nur, ob deren Platzhalter unversehrt sind.

Installation

python -m pip install gettext-tstrings

Python 3.14 oder neuer. Das Rendern hat keine Abhängigkeiten — es verwendet nur gettext aus der Standardbibliothek und sonst nichts.

Extraktion und Katalogprüfung laufen über Babel. Installiere dieses Extra überall dort, wo pybabel läuft, also üblicherweise in einer Entwicklungs- oder CI-Umgebung statt in einem Produktiv-Image:

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

Nächste Schritte

Erste Schritte — keine gettext-Erfahrung vorausgesetzt:

  • Tutorial — vom leeren Verzeichnis zu einer laufenden japanischen Übersetzung in fünf Schritten, jeder Befehl mit seiner Ausgabe.
  • Warum t-strings — dieselbe Nachricht auf vier Arten geschrieben, und was %(name)s, .format() und $-Strings dem Katalog jeweils überlassen.

Einsetzen — die Arbeitsreferenzen:

  • Anleitung — die Laufzeit-API: welcher Einstiegspunkt wofür, Pluralformen, Sprache pro Anfrage, verzögerte Strings und was geschieht, wenn ein Katalog fehlerhaft ist.
  • Extraktion — die pybabel-Referenz: Konfiguration, eigene Funktionsnamen und wie vorhandene Werkzeuge diese Kataloge ganz nebenbei validieren.
  • Im Produktivbetrieb — die Schleife, wie ein Team sie betreibt: der Update-Zyklus, fuzzy-Einträge, CI-Schranken, Übersetzungsplattformen und das Ausliefern.
  • Migration — wie du das in einem Projekt einführst, das schon Kataloge hat, eine Aufrufstelle nach der anderen.
  • Für Übersetzende — eine Seite, die du allen in die Hand geben kannst, die die .po-Dateien bearbeiten.

Hintergrundwissen — von der Geschichte zur Implementierung:

  • Hintergrund — warum diese Bibliothek existiert: dreißig Jahre gettext, zwei PEPs und die stdlib-Diskussion, die ohne Antwort geschlossen wurde.
  • Fallstricke — was beim Übersetzen dieser Website in fünfunddreißig Sprachen tatsächlich kaputtgegangen ist, und welche Hälfte davon ein Werkzeug fangen kann.
  • Funktionsweise — vom Template-Objekt aus PEP 750 zum gerenderten String, und die Caches, die das Prüfen billig machen.

Nachschlagen — die Verträge:

  • API — alles, was das Paket exportiert, auf einer Seite.
  • Spezifikation — die t-string-↔-msgid-Konvention als stabiler, versionierter Vertrag mit maschinenlesbarer Konformitätssuite.

Status

Paketversion 0.1.0a8
API-Stabilität Alpha — die Python-API kann sich noch ändern
Spezifikation v1, mit einer Konformitätssuite
Python 3.14 und neuer; getestet auf 3.14, 3.14t (free-threaded) und 3.15
Babel 2.18 oder neuer, und nur dort, wo pybabel läuft
Laufzeitabhängigkeiten keine — das gettext der Standardbibliothek
Katalogformat gewöhnliches POT, PO und MO
Änderungen CHANGELOG

Eine Alpha. Der Vertrag ist absichtlich klein, und die Spezifikation ist der stabile Teil davon; die Python-API kann sich noch bewegen. Vor einer stabilen Version braucht es breitere Sprachfixtures, kontinuierliche Performance-Messungen, eine API-Durchsicht von Leuten, die gettext und Babel ernsthaft einsetzen, und Kompatibilitätstests über jede unterstützte Python- und Babel-Version.

Issues und Pull Requests sind willkommen — eine Alpha ist genau der Zeitpunkt, zu dem über die Schnittstelle noch zu streiten lohnt.

Community