Registry / serialization / polib
library1.2.0pypypi✓ verified 26d ago

polib is a pure Python library designed to manipulate gettext files, specifically .po (Portable Object) and .mo (Machine Object) files. It enables loading, creating, modifying, and saving these translation files. The library is stable, widely used, and supports Python versions from 2.7 to the latest 3.x. Its release cadence is irregular but indicates active maintenance, with version 1.2.0 released in February 2023.

pip install polib
INSTALL
IMPORT
SIG · POLIB
P
polib
serializationpythonv1.2.0
Install
1.7s avg
Import
10ms
Disk
16MB
Pass rate
10/ 10
Env Coverage10 / 10
glibc
3.93.13
musl
3.93.13
Install & Compatibility
Where this runs
tested against v1.2.0 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
musl
py 3.103.95 runs
installs and imports cleanly · install 0.0s · import 0.006s · 17.9MB
glibc
py 3.103.95 runs
installs and imports cleanly · install 1.7s · import 0.006s · 18MB
16MB installed
● package 16MB
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

polib
import polib
pofile
po = polib.pofile('path/to/catalog.po')
Used to load an existing .po file or string.
mofile
mo = polib.mofile('path/to/catalog.mo')
Used to load an existing .mo file.
POFile
new_po = polib.POFile()
Class for creating a new .po file object.
POEntry
entry = polib.POEntry(msgid='Hello', msgstr='Hola')
Class for creating a new PO file entry.

This quickstart demonstrates how to load a PO file (from a string for simplicity), iterate through its entries, add a new entry, modify an existing entry, and save the changes. For real-world use, replace `polib.pofile(dummy_po_content)` with `polib.pofile('/path/to/your/file.po')` to load from a file.

import polib import os # Create a dummy .po file for demonstration dummy_po_content = '''\ msgid "" msgstr "" "Project-Id-Version: test\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "MIME-Version: 1.0\n" "X-Generator: Python-polib\n" #: main.py:10 msgid "Hello, world!" msgstr "" #: another.py:5 msgid "Another message" msgstr "Other message" ''' # Load an existing PO file (or from a string) # For a real file, use: pofile = polib.pofile('/path/to/your/file.po') pofile = polib.pofile(dummy_po_content) print("\n--- Iterating through entries ---") for entry in pofile: print(f"Msgid: {entry.msgid}, Msgstr: {entry.msgstr}") # Add a new entry new_entry = polib.POEntry( msgid='New string', msgstr='Nueva cadena', comment='A new comment for this string', occurrences=[('app.py', '20')] ) pofile.append(new_entry) print("\n--- After adding a new entry ---") for entry in pofile: print(f"Msgid: {entry.msgid}, Msgstr: {entry.msgstr}") # Modify an entry if pofile.find('Hello, world!'): entry_to_modify = pofile.find('Hello, world!') entry_to_modify.msgstr = '¡Hola, mundo!' entry_to_modify.comment = 'Translated by quickstart' print("\n--- After modifying an entry ---") for entry in pofile: print(f"Msgid: {entry.msgid}, Msgstr: {entry.msgstr}") # Save the modified PO file (to a dummy path for demonstration) dummy_output_path = 'temp_output.po' pofile.save(dummy_output_path) print(f"\nSaved modified PO file to {dummy_output_path}") # Clean up the dummy file os.remove(dummy_output_path) print(f"Cleaned up {dummy_output_path}")
Debug
Known issues
breakingSupport for Python versions older than 2.7 was dropped in version 1.1.1.
fix
Ensure your project runs on Python 2.7 or a Python 3.x version. Upgrade your Python environment if necessary.
affects: < 1.1.1
gotchaEnabling `check_for_duplicates=True` when adding entries to a POFile can significantly slow down performance, especially with large files.
fix
Use `check_for_duplicates=False` if performance is critical and you are confident in your entry uniqueness, or implement custom batching/deduplication logic before adding entries.
affects: All versions
gotchaRefactoring of `POEntry.__cmp__` method in version 1.1.0 might affect custom sorting logic or assumptions about entry comparison.
fix
Review any code that relies on implicit or explicit comparison of `POEntry` objects after upgrading to version 1.1.0 or later.
affects: < 1.1.0
gotchaPrior to version 1.1.1, `polib` might not correctly handle Message Context (`msgctxt`) in MO files. Additionally, older versions (<=1.0.3) could raise exceptions during `POFile.append()` with `check_for_duplicates=True` if `msgid` was the same but `msgctxt` differed.
fix
Upgrade to polib 1.1.1 or later for robust `msgctxt` support. If using `check_for_duplicates=True`, be aware of the older behavior and either upgrade or handle potential exceptions.
affects: < 1.1.1 and <= 1.0.3
gotchaHow `polib` wraps 'occurrences' (the `#: reference...` lines) might differ from `xgettext --no-wrap` output, potentially leading to inconsistencies if strict byte-for-byte matching is expected.
fix
If exact `xgettext` output formatting is required for occurrence lines, manual post-processing or specific `wrapwidth` configuration might be necessary. This is an ongoing discussion in the community.
affects: All versions
Errors
Common errors & fixes
ModuleNotFoundError: No module named 'polib'
The 'polib' library is not installed in your current Python environment.
fix
Install the library using pip: `pip install polib`
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x... in position ...: invalid start byte
The PO/MO file you are trying to read or write is not encoded in UTF-8, or has an encoding mismatch, causing Python to fail decoding specific byte sequences.
fix
Explicitly specify the correct encoding when loading or saving the file, often after detecting it with `polib.detect_encoding()`. Example: `po = polib.pofile('path/to/file.po', encoding='latin-1')`
TypeError: list indices must be integers or slices, not str
This error often occurs when incorrectly trying to assign an empty string directly to `POEntry.msgstr_plural` or attempting to access plural forms with string indices, while it expects a dictionary or a list of strings.
fix
Assign `msgstr_plural` an empty dictionary `{}` or a list of empty strings `['', '']` (depending on plural forms) when initializing or clearing plural translations. Example: `entry.msgstr_plural = {'0': ''}` or `entry.msgstr_plural = ['', '']`.
Upgrade
Version history
1.2.0latest on PyPI · released Feb 23, 2023
Audit
Dependencies

No dependency data recorded yet.

Agent activity
13 hits · last 30 days
node
10
Amazon
1
Resources
polib — pip install polib · libregistry