1. David Jean Louis
  2. polib


Clone wiki

polib / Tutorial

polib tutorial

Some basics about gettext catalogs

A gettext catalog is made up of many entries, each entry holding the relation between an original untranslated string and its corresponding translation. All entries in a given catalog usually pertain to a single project, and all translations are expressed in a single target language. One PO file entry has the following schematic structure:

#  translator-comments
#. extracted-comments
#: reference...
#, flag...
msgid untranslated-string
msgstr translated-string

A simple entry can look like this:

#: lib/error.c:116
msgid "Unknown system error"
msgstr "Error desconegut del sistema"

polib has two main entry points for working with gettext catalogs:

  • the _pofile_ and _mofile_ functions to *load* existing po or mo files,
  • the _POFile_ and _MOFile_ classes to *create* new po or mo files.

loading existing catalogs

Loading a catalog and detecting its encoding

Here the encoding of the po file is auto-detected by polib (polib detects it by parsing the charset in the header of the pofile):

import polib
po = polib.pofile('path/to/catalog.po')

Loading a catalog and specifying explicitly the encoding

For some reason you may want to specify the file encoding explicitely (because the charset is not specified in the po file header for example), to do so:

import polib
po = polib.pofile('path/to/catalog.po', autodetect_encoding=False, encoding='iso-8859-15')

You can also pass other options to pofile():

  • wrapwidth: integer, the wrap width (optional, default to 78)
  • check_for_duplicates: whether to check for duplicate entries when adding entries to the file, default: False.

Loading an mo catalog

In some cases you can be forced to load an mo file (because the po file is not available for example), polib handles this case:

import polib
mo = polib.mofile('path/to/catalog.mo')
print mo

As for po files, mofile also allows to specify the encoding explicitely.

Creating a po catalog from scratch

polib allows you to create catalog from scratch, this can be done with the POFile class, for exemple to create a simple catalog you could do:

import polib

po = polib.POFile()
po.metadata = {
    'Project-Id-Version': '1.0',
    'Report-Msgid-Bugs-To': 'you@example.com',
    'POT-Creation-Date': '2007-10-18 14:00+0100',
    'PO-Revision-Date': '2007-10-18 14:00+0100',
    'Last-Translator': 'you <you@example.com>',
    'Language-Team': 'English <yourteam@example.com>',
    'MIME-Version': '1.0',
    'Content-Type': 'text/plain; charset=utf-8',
    'Content-Transfer-Encoding': '8bit',

print po

POFile and MOFile objects

POFile and MOFile objects have the following properties/method in common


  • header: a string containing the po file header
  • metadata: a dict containing the po file metadata
  • wrapwidth: an integer, the width at which lines should be wrapped


  • to_binary() -> string: return the binary (mo format) representation of the file,
  • save([fpath]): save the string representation to file _fpath_. If fpath is ommited and the object points to an existing file, the existing file is updated,
  • ordered_metadata() -> list: convenience method that return the metadata ordered. The return value is list of tuples (metadata name, metadata_value)
  • percent_translated() -> integer: convenience method that return an integer that correspond to the percentage of translated messages (in mo files this always return 100),
  • translated_entries() -> list: convenience method that return the list of translated entries (entries that have a non empty msgstr and that are not obsolete or fuzzy),
  • untranslated_entries() -> list: convenience method that return the list of untranslated entries (in mo files this always return an empty list),
  • fuzzy_entries() -> list: convenience method that return the list of fuzzy entries (in mo files this always return an empty list),
  • obsolete_entries() -> list: convenience method that return the list of obsolete (in mo files this always return an empty list) entries.

POFile specific method

  • save_as_mofile(fpath): save the binary representation of the file (mo format) to file _fpath_

MOFile specific method

  • save_as_pofile(fpath): save the string representation of the mo file (the po format) to file _fpath_

POEntry and MOEntry objects

POEntry and MOEntry objects have the following properties in common

  • msgid: string containing the msgid to translate,
  • msgid_plural: string containing the plural msgid,
  • msgstr: string containing the msgid translation,
  • msgstr_plural: dictionary containing the translations for 0,1,...,n occurrences (eg. msgstr[0], msgstr[1], etc...).

Additionally, POEntry objects have the following properties and method


  • occurrences: list containing tuples of file name, line number representing occurrences of the msgid in the source code,
  • comment: string containing a generated comment (eg. #. some text),
  • tcomment: string containing a translator comment (eg. # some text),
  • flags: list of strings reprensenting the entry flags (eg: fuzzy, c-format...).


  • translated() -> boolean: return True if the entry has been translated or False otherwise.


Iterating over entries

POFile and MOFile inherit from python builtin lists, so to iterate over entries it's quite simple, here are some examples:

Iterating over all entries (by default POFiles contains all catalog entries, even obsolete and fuzzy entries):

import polib

po = polib.pofile('path/to/catalog.po')
for entry in po:
    print entry.msgid, entry.msgstr

Iterating over all entries except obsolete entries:

import polib

po = polib.pofile('path/to/catalog.po')
valid_entries = [e for e in po if not e.obsolete]
for entry in valid_entries:
    print entry.msgid, entry.msgstr

Iterating over translated entries:

import polib

po = polib.pofile('path/to/catalog.po')
for entry in po.translated_entries():
    print entry.msgid, entry.msgstr

And so on... you could also iterate over the list of POEntry objects returned by the following POFile methods:

  • untranslated_entries(),
  • fuzzy_entries()

Getting the percent of translated entries

import polib

po = polib.pofile('path/to/catalog.po')
print po.percent_translated()

Compiling po to mo files and reversing mo files to po files

Compiling a po file

import polib

po = polib.pofile('path/to/catalog.po')
# to get the binary representation in a variable:
modata = po.to_binary()
# or to save the po file as an mo file

Reverse a mo file to a po file

import polib

mo = polib.mofile('path/to/catalog.mo')
# to get the string representation in a variable:
podata = str(mo)
# or to save the mo file as an po file