Advice - just use .po files?
For the project I'm working on - a simple Litestar-implemented API - we are using Babel to manage translation responses.
For us, .pot, .po and .mo files are overkill. We commit .po files to source control, but then on build/push of our code we generate .mo files so they're available to the application on install. We have commands to create .pot files, apply them as a diff to our .po files, and then instantly delete the .pot files.
Is there a way of working that just involves using .po files? I'd love to be able to commit .po files to my repo, have them included in the build, and then be read and cached on startup. It would also make running tests and other scenarios much simpler to just have one file type.
Has anyone done this? Could I just do read_po() into Catalog files that I cache and read from?
I actually bit the bullet and had a go at this myself.
class TranslatorFunction(Protocol):
def __call__(self, message_id: str, locale: str) -> str:
...
def create_t(translations_path: Path) -> TranslatorFunction:
"""Returns a t function populated with all of the translations detected in the file system."""
translations = {}
for po_file_path in translations_path.glob("**/LC_MESSAGES/*.po"):
po_file_relative_path = po_file_path.relative_to(translations_path)
locale = po_file_relative_path.parts[0]
domain = po_file_relative_path.parts[2].removesuffix(".po")
po_file_contents = StringIO(Path(po_file_path).read_text())
catalogue: Catalog = read_po(po_file_contents)
catalogue.locale = locale
catalogue.domain = domain
translations[locale] = catalogue
supported_locales = set(translations.keys())
def gettext(message_id: str, locale: str) -> str:
if locale not in supported_locales:
raise ValueError(
f'Unavailable locale "{locale}" requested. Available: {supported_locales}.'
)
return translations[locale].get(message_id).string
return gettext
t = create_t(TRANSLATIONS_DIRECTORY)
Nice! The only issue I see is the gettext implementation. It is possible that the message you are looking for is pluralized in which case you have to look at the plurals as well:
https://github.com/python/cpython/blob/342e654b8eda24c68da64cc21bc9583e480d9e8e/Lib/gettext.py#L438-L447
The problem is that the plural method is part of the GNUTranslations class which you want to avoid. You could probably do somehing like this instead:
from gettext import c2py
plural_fn = c2py(catalog._plural_expr)
Can we close this? It was answered and there has been no activity for a few months, mixing questions and bugs is not the best. At least add the question label?
cc @akx (Apologies for the pings but I don't see any other people triaging)