CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-babel

Internationalization utilities for Python providing locale data, date/time/number formatting, and message catalog management

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

message-catalogs.mddocs/

Message Catalog Management

Complete gettext-compatible message catalog system for managing translatable strings, including catalog creation, message extraction, PO/MO file handling, and translation management. Babel provides comprehensive tools for internationalization workflows.

Capabilities

Message Class

Represents individual translatable messages with metadata.

class Message:
    """
    Represents a single translatable message.
    
    Attributes:
        id (str|tuple): Message identifier (string or tuple for plurals)
        string (str|list): Translation string (string or list for plurals)
        locations (list): List of (filename, lineno) tuples where message appears
        flags (set): Set of flags (fuzzy, python-format, etc.)
        auto_comments (list): Automatic comments from extractors
        user_comments (list): User-provided comments
        previous_id (str|tuple): Previous message ID (for updates)
        lineno (int): Line number where message is defined
        context (str): Message context for disambiguation
    """
    def __init__(self, id, string='', locations=(), flags=(), auto_comments=(), 
                user_comments=(), previous_id=None, lineno=None, context=None):
        """
        Initialize a message.
        
        Args:
            id (str|tuple): Message identifier
            string (str|list): Translation string(s)
            locations (list): Source locations
            flags (set): Message flags
            auto_comments (list): Automatic comments
            user_comments (list): User comments
            previous_id (str|tuple): Previous ID for updates
            lineno (int): Line number
            context (str): Message context
        """
    
    @property
    def pluralizable(self):
        """bool: Whether this message has plural forms"""
    
    @property
    def python_format(self):
        """bool: Whether this message uses Python format strings"""

Usage example:

from babel.messages import Message

# Simple message
msg = Message('Hello, world!', 'Bonjour, le monde!', 
              locations=[('main.py', 10)], flags={'fuzzy'})

# Plural message
plural_msg = Message(
    id=('One item', '{count} items'),
    string=['Un élément', '{count} éléments'],
    locations=[('inventory.py', 25)]
)

Catalog Class

Collection of translatable messages with metadata and management functionality.

class Catalog:
    """
    Collection of translatable messages with catalog metadata.
    
    Attributes:
        locale (Locale): Target locale for translations
        domain (str): Message domain
        project (str): Project name
        version (str): Project version
        copyright_holder (str): Copyright holder
        msgid_bugs_address (str): Bug report email address
        last_translator (str): Last translator information
        language_team (str): Language team information
        charset (str): Character encoding
        creation_date (datetime): Catalog creation date
        revision_date (datetime): Last revision date
        fuzzy (bool): Whether catalog is fuzzy (incomplete)
        num_plurals (int): Number of plural forms for locale
        plural_expr (str): Plural expression for locale
        plural_forms (str): Gettext plural forms header
        mime_headers (list): List of MIME headers
    """
    def __init__(self, locale=None, domain=None, header_comment=DEFAULT_HEADER, 
                project=None, version=None, copyright_holder=None, 
                msgid_bugs_address=None, creation_date=None, revision_date=None, 
                last_translator=None, language_team=None, charset=None, 
                plurals=None, fuzzy=True):
        """
        Initialize a message catalog.
        
        Args:
            locale (Locale|str): Target locale
            domain (str): Message domain
            header_comment (str): Header comment text
            project (str): Project name
            version (str): Project version
            copyright_holder (str): Copyright holder
            msgid_bugs_address (str): Bug report address
            creation_date (datetime): Creation timestamp
            revision_date (datetime): Revision timestamp
            last_translator (str): Last translator info
            language_team (str): Language team info
            charset (str): Character encoding
            plurals (tuple): Plural forms (count, expression)
            fuzzy (bool): Whether catalog is fuzzy
        """
    
    def add(self, id, string=None, locations=(), flags=(), auto_comments=(), 
           user_comments=(), previous_id=None, lineno=None, context=None):
        """
        Add a message to the catalog.
        
        Args:
            id (str|tuple): Message identifier  
            string (str|list): Translation string(s)
            locations (list): Source locations
            flags (set): Message flags
            auto_comments (list): Automatic comments
            user_comments (list): User comments
            previous_id (str|tuple): Previous ID
            lineno (int): Line number
            context (str): Message context
            
        Returns:
            Message: The added message object
        """
    
    def get(self, id, context=None):
        """
        Get a message by ID and context.
        
        Args:
            id (str|tuple): Message identifier
            context (str, optional): Message context
            
        Returns:
            Message|None: Message object or None if not found
        """
    
    def delete(self, id, context=None):
        """
        Delete a message from the catalog.
        
        Args:
            id (str|tuple): Message identifier
            context (str, optional): Message context
        """
    
    def update(self, template, no_fuzzy_matching=False, update_header_comment=False):
        """
        Update catalog from a template catalog.
        
        Args:
            template (Catalog): Template catalog with source messages
            no_fuzzy_matching (bool): Whether to disable fuzzy matching
            update_header_comment (bool): Whether to update header comment
        """
    
    def check(self):
        """
        Run consistency checks on the catalog.
        
        Returns:
            list: List of check result tuples (message, checker_errors)
        """
    
    def __iter__(self):
        """Iterate over messages in the catalog."""
    
    def __len__(self):
        """Get number of messages in catalog."""
    
    def __contains__(self, id):
        """Check if message ID exists in catalog."""

Usage example:

from babel.messages import Catalog, Message
from babel import Locale
import datetime

# Create a catalog
catalog = Catalog(
    locale=Locale('fr_FR'),
    project='My Project',
    version='1.0',
    creation_date=datetime.datetime.now()
)

# Add messages
catalog.add('Hello', 'Bonjour', locations=[('main.py', 10)])
catalog.add('Goodbye', 'Au revoir', locations=[('main.py', 20)])

# Plural message
catalog.add(
    ('One file', '{count} files'),
    ['Un fichier', '{count} fichiers'],
    locations=[('files.py', 15)]
)

# Check catalog
issues = catalog.check()
print(f"Catalog has {len(catalog)} messages")

PO File Handling

Read and write PO (Portable Object) files for translation management.

def read_po(fileobj, locale=None, domain=None, ignore_obsolete=True, 
           charset=None, abort_invalid=False):
    """
    Read a PO file and return a Catalog.
    
    Args:
        fileobj (file-like): File object to read from
        locale (Locale|str, optional): Target locale
        domain (str, optional): Message domain
        ignore_obsolete (bool): Whether to ignore obsolete entries
        charset (str, optional): Character encoding
        abort_invalid (bool): Whether to abort on invalid entries
        
    Returns:
        Catalog: Parsed message catalog
        
    Raises:
        PoFileError: If PO file parsing fails
    """

def write_po(fileobj, catalog, width=76, no_location=False, omit_header=False, 
            sort_output=False, sort_by_file=False, ignore_obsolete=True, 
            include_previous=False, include_lineno=True):
    """
    Write a Catalog to a PO file.
    
    Args:
        fileobj (file-like): File object to write to
        catalog (Catalog): Message catalog to write
        width (int): Maximum line width
        no_location (bool): Whether to omit location comments
        omit_header (bool): Whether to omit the header
        sort_output (bool): Whether to sort messages by ID
        sort_by_file (bool): Whether to sort by filename
        ignore_obsolete (bool): Whether to ignore obsolete entries
        include_previous (bool): Whether to include previous msgid
        include_lineno (bool): Whether to include line numbers
    """

Usage example:

from babel.messages.pofile import read_po, write_po
from babel.messages import Catalog

# Read a PO file
with open('messages.po', 'rb') as f:
    catalog = read_po(f, locale='fr_FR')

# Write a PO file
with open('output.po', 'wb') as f:
    write_po(f, catalog, width=80)

MO File Handling

Read and write MO (Machine Object) files for runtime translation use.

def read_mo(fileobj):
    """
    Read a binary MO file and return a Catalog.
    
    Args:
        fileobj (file-like): File object to read from
        
    Returns:
        Catalog: Parsed message catalog
    """

def write_mo(fileobj, catalog, use_fuzzy=False):
    """
    Write a Catalog to a binary MO file.
    
    Args:
        fileobj (file-like): File object to write to
        catalog (Catalog): Message catalog to write
        use_fuzzy (bool): Whether to include fuzzy translations
    """

Usage example:

from babel.messages.mofile import read_mo, write_mo

# Read MO file
with open('messages.mo', 'rb') as f:
    catalog = read_mo(f)

# Write MO file
with open('output.mo', 'wb') as f:
    write_mo(f, catalog, use_fuzzy=False)

Message Extraction

Extract translatable strings from source code files.

def extract_from_dir(dirname, method_map=None, options_map=None, keywords=None, 
                    comment_tags=None, callback=None, strip_comment_tags=False):
    """
    Extract messages from a directory tree.
    
    Args:
        dirname (str): Directory to extract from
        method_map (dict): File extension to extraction method mapping
        options_map (dict): Method-specific options
        keywords (dict): Keyword function specifications
        comment_tags (list): Comment tags to extract
        callback (callable): Progress callback function
        strip_comment_tags (bool): Whether to strip comment tags
        
    Returns:
        Generator: Iterator of (filename, lineno, message, comments, context) tuples
    """

def extract_from_file(method, filename, keywords=None, comment_tags=None, 
                     options=None, strip_comment_tags=False):
    """
    Extract messages from a single file.
    
    Args:
        method (str|callable): Extraction method
        filename (str): File to extract from
        keywords (dict): Keyword specifications
        comment_tags (list): Comment tags to extract
        options (dict): Method-specific options
        strip_comment_tags (bool): Whether to strip comment tags
        
    Returns:
        Generator: Iterator of (lineno, message, comments, context) tuples
    """

def extract_python(fileobj, keywords, comment_tags, options):
    """
    Extract messages from Python source code.
    
    Args:
        fileobj (file-like): File object to read from
        keywords (dict): Keyword specifications
        comment_tags (list): Comment tags to extract
        options (dict): Extraction options
        
    Returns:
        Generator: Iterator of extraction results
    """

def extract_javascript(fileobj, keywords, comment_tags, options):
    """
    Extract messages from JavaScript source code.
    
    Args:
        fileobj (file-like): File object to read from
        keywords (dict): Keyword specifications
        comment_tags (list): Comment tags to extract
        options (dict): Extraction options
        
    Returns:
        Generator: Iterator of extraction results
    """

Usage example:

from babel.messages.extract import extract_from_dir, extract_python

# Extract from directory
method_map = {
    '*.py': 'python',
    '*.js': 'javascript'
}

keywords = {
    '_': None,
    'gettext': None,
    'ngettext': (1, 2),
}

for filename, lineno, message, comments, context in extract_from_dir('.', method_map, keywords=keywords):
    print(f"{filename}:{lineno}: {message}")

Command Line Tools

Classes for setuptools integration and command-line message management.

class ExtractMessages:
    """Command to extract messages from source code."""
    
    def run(self):
        """Execute message extraction."""

class InitCatalog:
    """Command to initialize a new message catalog."""
    
    def run(self):
        """Execute catalog initialization."""

class UpdateCatalog:
    """Command to update an existing catalog from template."""
    
    def run(self):
        """Execute catalog update."""

class CompileCatalog:
    """Command to compile PO files to MO files."""
    
    def run(self):
        """Execute catalog compilation."""

Translation Support Classes

Extended translation classes with Babel-specific functionality.

class Translations:
    """
    Extended translation catalog with Babel features.
    
    Inherits from gettext.GNUTranslations with additional methods.
    """
    @classmethod
    def load(cls, dirname=None, locales=None, domain=None):
        """
        Load translations from directory.
        
        Args:
            dirname (str): Directory containing translation files
            locales (list): List of locale identifiers
            domain (str): Message domain
            
        Returns:
            Translations: Translation object
        """
    
    def add(self, translations, merge=True):
        """
        Add translations from another catalog.
        
        Args:
            translations (Translations): Translations to add
            merge (bool): Whether to merge duplicates
        """
    
    def merge(self, translations):
        """
        Merge translations from another catalog.
        
        Args:
            translations (Translations): Translations to merge
        """

String Utilities

Utilities for PO file string handling.

def escape(string):
    """
    Escape string for PO file format.
    
    Args:
        string (str): String to escape
        
    Returns:
        str: Escaped string
    """

def unescape(string):
    """
    Unescape PO file string.
    
    Args:
        string (str): String to unescape
        
    Returns:
        str: Unescaped string
    """

def normalize(string, prefix='', width=76):
    """
    Normalize multiline strings for PO format.
    
    Args:
        string (str): String to normalize
        prefix (str): Line prefix
        width (int): Maximum line width
        
    Returns:
        str: Normalized string
    """

def denormalize(string):
    """
    Reverse normalization of PO strings.
    
    Args:
        string (str): String to denormalize
        
    Returns:
        str: Denormalized string
    """

Plural Forms

Get plural form information for locales.

def get_plural(locale):
    """
    Get plural rule for locale.
    
    Args:
        locale (Locale|str): Target locale
        
    Returns:
        _PluralTuple: Tuple containing (count, expression)
    """

Message Checkers

Functions to validate message catalog consistency.

def num_plurals(catalog, message):
    """
    Check that number of plural forms matches locale.
    
    Args:
        catalog (Catalog): Message catalog
        message (Message): Message to check
        
    Returns:
        list: List of error messages
    """

def python_format(catalog, message):
    """
    Check Python format string consistency.
    
    Args:
        catalog (Catalog): Message catalog  
        message (Message): Message to check
        
    Returns:
        list: List of error messages
    """

Exception Classes

class TranslationError(Exception):
    """Base exception for translation-related errors."""

class PoFileError(Exception):
    """Exception raised for PO file parsing errors."""

Constants

DEFAULT_HEADER: str
    """Default catalog header comment template."""

PYTHON_FORMAT: re.Pattern
    """Regex pattern for Python format strings."""

Install with Tessl CLI

npx tessl i tessl/pypi-babel

docs

core-locales.md

date-time-formatting.md

index.md

message-catalogs.md

number-currency-formatting.md

plural-language-data.md

units-utilities.md

tile.json