I18n questions · Localization files
Use msgunfmt, the counterpart of msgfmt in GNU gettext:
msgunfmt messages.mo -o messages.po
Without -o the PO text goes to standard output. The tool ships with the gettext package of Linux distributions and Homebrew. The manual page also lists --java, --csharp and --tcl modes for the other catalog formats msgfmt can produce.
The result is a valid, editable .po file, but not the file the translation was made from. A .mo contains a header (the entry with the empty msgid) and two parallel tables, one of original strings and one of translations, plus an optional hash table. Nothing else is stored, so these parts of the original file are gone:
# ...), extracted comments (#.) and source references (#:), which is why the recovered file has no file names or line numbers.#, fuzzy and #, c-format. Entries marked fuzzy are not compiled by default, so they are missing entirely rather than recovered as fuzzy.msgstr and nothing to compile, and obsolete #~ entries.What does survive: contexts and plurals. The MO format encodes msgctxt in front of the original string and stores plural forms as NUL-separated variants, so msgunfmt writes proper msgctxt, msgid_plural and msgstr[n] entries again. Since gettext 0.22 msgfmt writes the strings as UTF-8 unless --no-convert is given, and msgunfmt keeps the charset declared in the header.
If you still have the program sources, get the references back by merging the recovered file with a fresh template; msgmerge takes the #: lines from the template and marks changed strings fuzzy:
xgettext --from-code=UTF-8 -o messages.pot src/*.py
msgmerge recovered.po messages.pot -o de.po
The same conversion from Python uses polib:
import polib
mo = polib.mofile("messages.mo")
mo.save_as_pofile("messages.po")
Treat the decompiled file as a recovery, not as the source of truth. If the original .po exists in version control or in a translation tool, use that one; the .mo is only the compiled output. The PO entry types mentioned above are described at PO file.
Published Oct 9, 2026 · Markdown version