A lightweight, zero-dependency Python library for internationalization and translation management.
Project description
๐ TransX
English | ็ฎไฝไธญๆ
๐ A lightweight, zero-dependency Python internationalization library that supports Python 2.7 through 3.12.
The API is designed to be DCC-friendly, for example, works with Maya, 3DsMax, Houdini, etc.
โจ Features
TransX provides a comprehensive set of features for internationalization:
- ๐ Zero Dependencies: No external dependencies required
- ๐ Python Support: Full support for Python 2.7-3.12
- ๐ Context-based: Accurate translations with context support
- ๐ฆ Standard Format: Compatible with gettext .po/.mo files
- ๐ฏ Simple API: Clean and intuitive interface
- ๐ Auto Management: Automatic translation file handling
- ๐ String Extraction: Built-in source code string extraction
- ๐ Unicode: Complete Unicode support
- ๐ Parameters: Named, positional and ${var} style parameters
- ๐ซ Variable Support: Environment variable expansion support
- โก Performance: High-speed and thread-safe operations
- ๐ก๏ธ Error Handling: Comprehensive error management with fallbacks
- ๐งช Testing: 100% test coverage with extensive cases
- ๐ Auto Translation: Built-in Google Translate API support
- ๐ฅ DCC Support: Tested with Maya, 3DsMax, Houdini, etc.
- ๐ Extensible: Pluggable custom text interpreters
- ๐จ Flexible Formatting: Multiple string formatting styles
- ๐ Runtime Switching: Dynamic locale switching at runtime
- ๐ง Qt Integration: Built-in support for Qt translations
- ๐ Message Extraction: Advanced source code message extraction with context
- ๐ Multi-App Support: Multiple translation instances for different apps
GNU gettext Compatibility
TransX is fully compatible with the GNU gettext standard, providing seamless integration with existing translation workflows:
- Standard Formats: Full support for
.poand.mofile formats according to GNU gettext specifications - File Structure: Follows the standard locale directory structure (
LC_MESSAGES/domain.{po,mo}) - Header Support: Complete support for gettext headers and metadata
- Plural Forms: Compatible with gettext plural form expressions and handling
- Context Support: Full support for msgctxt (message context) using gettext standard separators
- Encoding: Proper handling of character encodings as specified in PO/MO headers
- Tools Integration: Works with standard gettext tools (msgfmt, msginit, msgmerge, etc.)
- Binary Format: Implements the official MO file format specification with both little and big endian support
This means you can:
- Use existing PO editors like Poedit, Lokalize, or GTranslator
- Integrate with established translation workflows
- Migrate existing gettext-based translations seamlessly
- Use standard gettext tools alongside TransX
- Maintain compatibility with other gettext-based systems
๐ Quick Start
๐ฅ Installation
pip install transx
๐ Basic Usage
from transx import TransX
# Initialize with locale directory
tx = TransX(locales_root="./locales")
# Basic translation
print(tx.tr("Hello")) # Output: ไฝ ๅฅฝ
# Translation with parameters
print(tx.tr("Hello {name}!", name="ๅผ ไธ")) # Output: ไฝ ๅฅฝ ๅผ ไธ๏ผ
# Context-based translation
print(tx.tr("Open", context="button")) # ๆๅผ
print(tx.tr("Open", context="menu")) # ๆๅผๆไปถ
# Switch language at runtime
tx.switch_locale("ja_JP")
print(tx.tr("Hello")) # Output: ใใใซใกใฏ
๐ Translation API
TransX provides two main methods for translation with different levels of functionality:
tr() - High-Level Translation API
The tr() method is the recommended high-level API that provides all translation features:
# Basic translation
tx.tr("Hello") # ไฝ ๅฅฝ
# Translation with parameters
tx.tr("Hello {name}!", name="ๅผ ไธ") # ไฝ ๅฅฝ ๅผ ไธ๏ผ
# Context-based translation
tx.tr("Open", context="button") # ๆๅผ
tx.tr("Open", context="menu") # ๆๅผๆไปถ
# Environment variable expansion
tx.tr("Home: $HOME") # Home: /Users/username
# Dollar sign escaping
tx.tr("Price: $$99.99") # Price: $99.99
# Complex parameter substitution
tx.tr("Welcome to ${city}, {country}!", city="ๅไบฌ", country="ไธญๅฝ")
translate() - Low-Level Translation API
The translate() method is a lower-level API that provides basic translation and parameter substitution:
# Basic translation
tx.translate("Hello") # ไฝ ๅฅฝ
# Translation with context
tx.translate("Open", context="button") # ๆๅผ
# Simple parameter substitution
tx.translate("Hello {name}!", name="ๅผ ไธ") # ไฝ ๅฅฝ ๅผ ไธ๏ผ
The main differences between tr() and translate():
| Feature | tr() | translate() |
|---|---|---|
| Basic Translation | โ | โ |
| Context Support | โ | โ |
| Parameter Substitution | โ | โ |
| Environment Variables | โ | โ |
| ${var} Style Variables | โ | โ |
| $$ Escaping | โ | โ |
| Interpreter Chain | โ | โ |
Choose tr() for full functionality or translate() for simpler use cases where you only need basic translation and parameter substitution.
๐ Advanced Parameter Substitution
# Named parameters
tx.tr("Welcome to {city}, {country}!", city="ๅไบฌ", country="ไธญๅฝ")
# Positional parameters
tx.tr("File {0} of {1}", 1, 10)
# Dollar sign variables (useful in shell-like contexts)
tx.tr("Current user: ${USER}") # Supports ${var} syntax
tx.tr("Path: $HOME/documents") # Supports $var syntax
# Escaping dollar signs
tx.tr("Price: $$99.99") # Outputs: Price: $99.99
๐ Available Locales
TransX provides a convenient way to get a list of available locales in your project:
from transx import TransX
tx = TransX(locales_root="./locales")
# Get list of available locales
print(f"Available locales: {tx.available_locales}") # e.g. ['en_US', 'zh_CN', 'ja_JP']
# Check if a locale is available before switching
if "zh_CN" in tx.available_locales:
tx.current_locale = "zh_CN"
The available_locales property returns a sorted list of locale codes that:
- Have a valid locale directory structure (
LC_MESSAGESfolder) - Contain either
.poor.motranslation files - Are ready to use for translation
This is useful for:
- Building language selection interfaces
- Validating locale switches
- Checking translation file completeness
- Displaying supported languages to users
๐ ๏ธ Command Line Interface
TransX provides a command-line interface for common translation tasks. When no arguments are provided for commands, TransX will use the ./locales directory in your current working directory as the default path.
# Extract messages from source files
# Default: Will look for source files in current directory and output to ./locales
transx extract
# Same as:
transx extract . --output ./locales/messages.pot
# Update .po files with new translations
# Default: Will update .po files in ./locales
transx update
# Same as:
transx update ./locales
# Compile .po files to .mo files
# Default: Will compile .po files from ./locales
transx compile
# Same as:
transx compile ./locales
The default working directory structure:
./
โโโ locales/ # Default translation directory
โโโ messages.pot # Extracted messages template
โโโ en/ # English translations
โ โโโ LC_MESSAGES/
โ โโโ messages.po
โ โโโ messages.mo
โโโ zh_CN/ # Chinese translations
โโโ LC_MESSAGES/
โโโ messages.po
โโโ messages.mo
Extract Messages
# Extract from a single file
transx extract app.py -o messages.pot
# Extract from a directory with project info
transx extract ./src -o messages.pot -p "MyProject" -v "1.0"
# Extract and specify languages
transx extract ./src -l "en_US,zh_CN,ja_JP"
Update PO Files
# Update or create PO files for specific languages
transx update messages.pot -l "zh_CN,ja_JP,ko_KR"
# Auto-discover and update all language files
transx update messages.pot
# Update with custom output directory
transx update messages.pot -o ./locales
Compile MO Files
# Compile a single PO file
transx compile path/to/messages.po
# Compile all PO files in a directory
transx compile -d ./locales
# Compile multiple specific files
transx compile file1.po file2.po
List Available Locales
# List all available locales in default directory
transx list
# List locales in a specific directory
transx list -d /path/to/locales
Common Options
-d, --directory: Specify working directory-o, --output: Specify output file/directory-l, --languages: Comma-separated list of language codes-p, --project: Project name (for POT generation)-v, --version: Project version (for POT generation)
For detailed help on any command:
transx <command> --help
๐ Advanced Features
๐ฅ๏ธ Qt Usage
TransX can be used with Qt applications in two ways:
Basic Integration
Use TransX directly in your Qt application:
from PySide2.QtWidgets import QMainWindow
from transx import get_transx_instance
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.tx = get_transx_instance("myapp")
# Translate window title
self.setWindowTitle(self.tx.tr("My Application"))
# Translate menu items
file_menu = self.menuBar().addMenu(self.tx.tr("&File"))
file_menu.addAction(self.tx.tr("&Open"))
file_menu.addAction(self.tx.tr("&Save"))
Qt Translator Integration
For Qt's built-in translation system, you'll need to:
- First convert your .po files to .qm format using Qt's lrelease tool
- Install the .qm files using TransX's Qt extension
from PySide2.QtWidgets import QApplication, QMainWindow
from PySide2.QtCore import QTranslator
from transx.extensions.qt import install_qt_translator
app = QApplication([])
translator = QTranslator()
# Install translator for specific locale
# Make sure qt_zh_CN.qm exists in ./translations directory
install_qt_translator(app, translator, "zh_CN", "./translations")
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
# Note: Qt's tr() will only work with .qm files
# For Python strings, use TransX's tr() function
self.setWindowTitle("My Application") # This won't be translated
Converting .po to .qm files:
# Using Qt's lrelease tool
lrelease translations/zh_CN/LC_MESSAGES/messages.po -qm translations/qt_zh_CN.qm
Note: The
lreleasetool is part of Qt's Linguist tools:
- Windows: Install with Qt installer from qt.io (Look for Qt Linguist under Tools)
- Linux: Install via package manager
# Ubuntu/Debian sudo apt-get install qttools5-dev-tools # Fedora sudo dnf install qt5-linguist # Arch Linux sudo pacman -S qt5-tools- macOS: Install via Homebrew
brew install qt5
The Qt integration supports:
- Loading .qm format translation files
- Multiple translator instances
- Note: Qt's built-in tr() function requires .qm files and won't work with .mo files
๐ Message Extraction
Extract translatable messages from your source code with powerful context support:
from transx.api.pot import PotExtractor
# Initialize extractor with output file
extractor = PotExtractor(pot_file="messages.pot")
# Add source files or directories to scan
extractor.add_source_file("app.py")
extractor.add_source_file("utils.py")
# Or scan entire directories
extractor.add_source_directory("src")
# Extract messages with project info
extractor.save_pot(
project="MyApp",
version="1.0.0",
copyright_holder="Your Name",
bugs_address="your.email@example.com"
)
๐ Multi-App Support
Manage multiple translation instances for different applications or components:
from transx import get_transx_instance
# Create instances for different apps or components
app1 = get_transx_instance("app1", default_locale="en_US")
app2 = get_transx_instance("app2", default_locale="zh_CN")
# Each instance has its own:
# - Translation catalog
# - Locale settings
# - Message domains
app1.tr("Hello") # Uses app1's translations
app2.tr("Hello") # Uses app2's translations
# Switch locales independently
app1.switch_locale("ja_JP")
app2.switch_locale("ko_KR")
Multi-app support features:
- Independent translation catalogs
- Separate locale settings per instance
- Thread-safe operation
๐ค Context-Based Translations
# UI Context
print(tx.tr("Open", context="button")) # ๆๅผ
print(tx.tr("Open", context="menu")) # ๆๅผๆไปถ
# Part of Speech
print(tx.tr("Post", context="verb")) # ๅๅธ
print(tx.tr("Post", context="noun")) # ๆ็ซ
# Scene Context
print(tx.tr("Welcome", context="login")) # ๆฌข่ฟ็ปๅฝ
print(tx.tr("Welcome", context="home")) # ๆฌข่ฟๅๆฅ
โ ๏ธ Error Handling
TransX provides comprehensive error handling with fallback mechanisms:
from transx import TransX
from transx.exceptions import LocaleNotFoundError, TranslationError
# Enable strict mode for development
tx = TransX(strict_mode=True)
try:
tx.load_catalog("invalid_locale")
except LocaleNotFoundError as e:
print(f"โ Locale error: {e.message}")
try:
result = tx.translate("Hello", target_lang="invalid")
except TranslationError as e:
print(f"โ Translation failed: {e.message}")
๐ ๏ธ Development
๐ง Environment Setup
- Clone the repository:
git clone https://github.com/loonghao/transx.git
cd transx
- Install development dependencies:
pip install -r requirements-dev.txt
๐ฆ Project Structure
TransX follows a well-organized package structure:
transx/
โโโ transx/ # Main package directory
โ โโโ __init__.py # Package initialization
โ โโโ __version__.py # Version information
โ โโโ api/ # Public API modules
โ โ โโโ __init__.py
โ โ โโโ mo.py # MO file operations
โ โ โโโ po.py # PO file operations
โ โ โโโ pot.py # POT file operations
โ โโโ app.py # Application management
โ โโโ cli.py # Command-line interface
โ โโโ constants.py # Constants and configurations
โ โโโ context/ # Translation context management
โ โ โโโ __init__.py
โ โ โโโ manager.py # Context manager implementation
โ โโโ core.py # Core functionality
โ โโโ exceptions.py # Custom exceptions
โ โโโ extensions/ # Framework integrations
โ โ โโโ __init__.py
โ โ โโโ qt.py # Qt support
โ โโโ internal/ # Internal implementation details
โ โโโ __init__.py
โ โโโ compat.py # Python 2/3 compatibility
โ โโโ filesystem.py # File system operations
โ โโโ logging.py # Logging utilities
โโโ examples/ # Example code
โโโ locales/ # Translation files
โโโ tests/ # Test suite
โโโ nox_actions/ # Nox automation scripts
โโโ CHANGELOG.md # Version history
โโโ LICENSE # MIT License
โโโ README.md # English documentation
โโโ README_zh.md # Chinese documentation
โโโ noxfile.py # Test automation config
โโโ pyproject.toml # Project configuration
โโโ requirements.txt # Production dependencies
โโโ requirements-dev.txt # Development dependencies
๐ Development Workflow
We use Nox to automate development tasks. Here are the main commands:
# Run linting
nox -s lint
# Fix linting issues automatically
nox -s lint-fix
# Run tests
nox -s pytest
๐งช Running Tests
Tests are written using pytest and can be run using nox:
nox -s pytest
For running specific tests:
# Run a specific test file
nox -s pytest -- tests/test_core.py
# Run tests with specific markers
nox -s pytest -- -m "not integration"
๐ Code Quality
We maintain high code quality standards using various tools:
- Linting: We use ruff and isort for code linting and formatting
- Type Checking: Static type checking with mypy
- Testing: Comprehensive test suite with pytest
- Coverage: Code coverage tracking with coverage.py
- CI/CD: Automated testing and deployment with GitHub Actions
๐ Documentation
Documentation is written in Markdown and is available in:
- README.md: Main documentation
- examples/: Example code and usage
- API documentation in source code
๐ค Contributing Guidelines
- Fork the repository
- Create a new branch for your feature
- Make your changes
- Run tests and linting
- Submit a pull request
Please ensure your PR:
- Passes all tests
- Includes appropriate documentation
- Follows our code style
- Includes test coverage for new features
๐ License
This project is licensed under the MIT License - see the LICENSE file for details.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file transx-0.6.0.tar.gz.
File metadata
- Download URL: transx-0.6.0.tar.gz
- Upload date:
- Size: 54.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/5.1.1 CPython/3.12.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3abb4982903a7e5d4848151809d216d057e898f2437215fb5eed186a34a57cce
|
|
| MD5 |
53cec4822fa2d921af9a5414153d9bb6
|
|
| BLAKE2b-256 |
faa671e4aba5884e1da62bc14072ea787131c4d927beb43b68150f190031cf67
|
Provenance
The following attestation bundles were made for transx-0.6.0.tar.gz:
Publisher:
python-publish.yml on loonghao/transx
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
transx-0.6.0.tar.gz -
Subject digest:
3abb4982903a7e5d4848151809d216d057e898f2437215fb5eed186a34a57cce - Sigstore transparency entry: 154177682
- Sigstore integration time:
-
Permalink:
loonghao/transx@777462c94727cf4518b2103cfefc96b20fb9c754 -
Branch / Tag:
refs/tags/v0.6.0 - Owner: https://github.com/loonghao
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@777462c94727cf4518b2103cfefc96b20fb9c754 -
Trigger Event:
push
-
Statement type:
File details
Details for the file transx-0.6.0-py2.py3-none-any.whl.
File metadata
- Download URL: transx-0.6.0-py2.py3-none-any.whl
- Upload date:
- Size: 58.5 kB
- Tags: Python 2, Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/5.1.1 CPython/3.12.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
dff8517bb545064ac1ea5c459147d344c4bbb023c316b79f995af1a668539d46
|
|
| MD5 |
54e842d6bd2bfca5cf72d2f26749cdf2
|
|
| BLAKE2b-256 |
10552f4bf270d184196614378df319fe7b54b4ba260b1c10245b8160d40da413
|
Provenance
The following attestation bundles were made for transx-0.6.0-py2.py3-none-any.whl:
Publisher:
python-publish.yml on loonghao/transx
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
transx-0.6.0-py2.py3-none-any.whl -
Subject digest:
dff8517bb545064ac1ea5c459147d344c4bbb023c316b79f995af1a668539d46 - Sigstore transparency entry: 154177683
- Sigstore integration time:
-
Permalink:
loonghao/transx@777462c94727cf4518b2103cfefc96b20fb9c754 -
Branch / Tag:
refs/tags/v0.6.0 - Owner: https://github.com/loonghao
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@777462c94727cf4518b2103cfefc96b20fb9c754 -
Trigger Event:
push
-
Statement type: