{"id":4163,"library":"oslo-i18n","title":"Oslo Internationalization Utilities","description":"The oslo.i18n library provides utilities for internationalization (i18n) features, primarily for translating text strings within applications or libraries. It is part of the OpenStack Oslo project and is currently at version 6.7.2. New releases often align with OpenStack development cycles, indicating an active maintenance and development cadence.","status":"active","version":"6.7.2","language":"en","source_language":"en","source_url":"https://opendev.org/openstack/oslo.i18n","tags":["i18n","internationalization","localization","translation","openstack","oslo"],"install":[{"cmd":"pip install oslo-i18n","lang":"bash","label":"Install latest version"}],"dependencies":[],"imports":[{"symbol":"TranslatorFactory","correct":"from oslo_i18n import TranslatorFactory"},{"symbol":"translate","correct":"from oslo_i18n import translate"},{"note":"Marker functions like '_' should be exposed through a project's own integration module, not directly from internal oslo_i18n modules like gettextutils, which are considered private API.","wrong":"from oslo_i18n.gettextutils import _","symbol":"_ (primary translation marker)","correct":"from myapp._i18n import _"},{"note":"Similar to '_', log markers should be imported from the project's integration module.","symbol":"_LI, _LW, _LE, _LC (log translation markers)","correct":"from myapp._i18n import _LI"}],"quickstart":{"code":"import os\nfrom oslo_i18n import TranslatorFactory, enable_lazy, translate\n\n# 1. Create an integration module (conceptually, e.g., myapp._i18n.py)\n#    In a real project, this would be in a separate file and imported.\nDOMAIN = 'myproject'\n_translators = TranslatorFactory(domain=DOMAIN)\n_ = _translators.primary  # Primary translation marker\n_LW = _translators.log_warning # Log warning translation marker\n\n# 2. Enable lazy translation (optional, but common)\nenable_lazy()\n\n# 3. Mark strings for translation\nmessage = _('Hello, %(name)s!') % {'name': 'World'}\nwarning_message = _LW('Something went wrong: %s') % 'file not found'\n\n# 4. Simulate a different locale for translation at display/log time\n#    In a real app, this might come from user settings or request headers\ncurrent_locale = os.environ.get('TEST_LOCALE', 'en_US') # Example: 'es_ES'\n\n# 5. Translate and display\n#    Note: 'message' is a lazy translation object until explicitly translated or cast to string.\n#    The 'translate' function is used when the target locale is known.\n\ntranslated_message = translate(message, desired_locale=current_locale)\nprint(f\"Original (lazy) message type: {type(message)}\")\nprint(f\"Translated message for '{current_locale}': {translated_message}\")\n\n# Log messages would typically be handled by a logging configuration\n# with a TranslationHandler, but for demonstration, we can show direct translation.\nprint(f\"Translated log warning for '{current_locale}': {translate(warning_message, desired_locale=current_locale)}\")","lang":"python","description":"This quickstart demonstrates how to set up `oslo.i18n` by creating an integration module (conceptually), initializing a `TranslatorFactory`, obtaining marker functions (`_`, `_LW`), marking strings for lazy translation, and finally translating them to a specific locale using `oslo_i18n.translate()`."},"warnings":[{"fix":"Always pass string literals to `_()`, `_LI()`, etc. If a message needs dynamic parts, use string interpolation (e.g., `_('Hello, %s!') % name`).","message":"Marker functions like `_()` must receive string literals as arguments, not variables. For example, `_('My message.')` is correct, while `_(variable_containing_msg)` is wrong, as translation tools rely on static string analysis.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Review all uses of log-specific marker functions (`_LI`, `_LW`, `_LE`, `_LC`). If the message might ever be presented to a user, switch to using `_()` instead. `_()` is also appropriate if a message is used for both logging and user output.","message":"Starting with the OpenStack Pike series, log translation guidelines changed significantly. Marker functions like `_LI()`, `_LW()`, `_LE()`, and `_LC()` should ONLY be used for messages that go *directly* and *exclusively* to the log. If a message might be exposed to the user (e.g., via an exception or API response), the primary `_()` marker MUST be used.","severity":"breaking","affected_versions":"oslo.i18n versions roughly from 3.10.0 onwards (Pike series)"},{"fix":"Always use string interpolation (e.g., `_('Error: %s') % details`) or f-strings (Python 3.6+) with explicit `str()` conversion if needed (`str(_('Error')) + details`). Avoid `_('Error: ') + details`.","message":"Lazy translated message objects (returned by `_()` when lazy translation is enabled) do not support all string manipulation operations, specifically concatenation with the `+` operator. They are designed for string interpolation using the `%` operator or `.format()` (though `%` is more commonly shown in examples).","severity":"gotcha","affected_versions":"All versions with lazy translation enabled"},{"fix":"Instead of directly using `Message` objects, use `oslo_i18n.translate()` to convert a lazy translation object to a string when the locale is known. To create a new lazy message, use the marker functions (e.g., `_()`) provided by `TranslatorFactory`.","message":"The `oslo_i18n.gettextutils.Message` class was an internal implementation detail and was not part of the public API. Direct instantiation or reliance on this class is discouraged and may break in future versions.","severity":"deprecated","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-04-11T00:00:00.000Z","next_check":"2026-07-10T00:00:00.000Z"}