We introduced contextual/plural translation in version 2.1.0, so declare this in documentation to avoid AttributeError. Change-Id: Iadc24d19e2a2b799a5009a806ee7c64867b1d554 Related-Bug: #1525992
5.9 KiB
How to Use oslo.i18n in Your Application or Library
Installing
At the command line:
$ pip install oslo.i18n
Creating an Integration Module
To use oslo.i18n in a project (e.g. myapp), you will need to create a
small integration module to hold an instance of ~oslo_i18n.TranslatorFactory
and references to the
marker functions the factory creates.
Note
Libraries probably do not want to expose the new integration module
as part of their public API, so rather than naming it
myapp.i18n
it should be called myapp._i18n
to
indicate that it is a private implementation detail, and not meant to be
used outside of the library's own code.
# myapp/_i18n.py
import oslo_i18n
= "myapp"
DOMAIN
= oslo_i18n.TranslatorFactory(domain=DOMAIN)
_translators
# The primary translation function using the well-known name "_"
= _translators.primary
_
# The contextual translation function using the name "_C"
# requires oslo.i18n >=2.1.0
= _translators.contextual_form
_C
# The plural translation function using the name "_P"
# requires oslo.i18n >=2.1.0
= _translators.plural_form
_P
# Translators for log levels.
#
# The abbreviated names are meant to reflect the usual use of a short
# name like '_'. The "L" is for "log" and the other letter comes from
# the level.
= _translators.log_info
_LI = _translators.log_warning
_LW = _translators.log_error
_LE = _translators.log_critical
_LC
def get_available_languages():
return oslo_i18n.get_available_languages(DOMAIN)
Then, in the rest of your code, use the appropriate marker function for each message:
from myapp._i18n import _, _LW, _LE
# ...
= "openstack"
variable 'warning message: %s'), variable)
LOG.warning(_LW(
# ...
try:
# ...
except AnException1:
# Log only
'exception message'))
LOG.exception(_LE(
except AnException2:
# Raise only
raise RuntimeError(_('exception message'))
else:
# Log and Raise
= _('Unexpected error message')
msg
LOG.exception(msg)raise RuntimeError(msg)
Note
The import of multiple modules from _i18n on a single line is a valid exception to OpenStack Style Guidelines for import statements.
It is important to use the marker functions (e.g. _LI), rather than the longer form of the name, because the tool that scans the source code for translatable strings looks for the marker function names.
Warning
The old method of installing a version of _()
in the
builtins namespace is deprecated. Modifying the global namespace affects
libraries as well as the application, so it may interfere with proper
message catalog lookups. Calls to gettextutils.install
should be replaced with the
application or library integration module described here.
Handling hacking Objections to Imports
The OpenStack Style Guidelines prefer importing modules and accessing names from those modules after import, rather than importing the names directly. For example:
# WRONG
from foo import bar
bar()
# RIGHT
import foo
foo.bar()
The linting tool hacking will typically
complain about importing names from within modules. It is acceptable to
bypass this for the translation marker functions, because they must have
specific names and their use pattern is dictated by the message catalog
extraction tools rather than our style guidelines. To bypass the hacking
check for imports from this integration module, add an import exception
to tox.ini
.
For example:
# tox.ini
[hacking]
import_exceptions = myapp._i18n
Lazy Translation
Lazy translation delays converting a message string to the translated form as long as possible, including possibly never if the message is not logged or delivered to the user in some other way. It also supports logging translated messages in multiple languages, by configuring separate log handlers.
Lazy translation is implemented by returning a special object from the translation function, instead of a unicode string. That special message object supports some, but not all, string manipulation APIs. For example, concatenation with addition is not supported, but interpolation of variables is supported. Depending on how translated strings are used in an application, these restrictions may mean that lazy translation cannot be used, and so it is not enabled by default.
To enable lazy translation, call enable_lazy
.
import oslo_i18n
oslo_i18n.enable_lazy()
Translating Messages
Use ~oslo_i18n.translate
to translate strings to a
specific locale. translate
handles delayed translation and strings
that have already been translated immediately. It should be used at the
point where the locale to be used is known, which is often just prior to
the message being returned or a log message being emitted.
import oslo_i18n
trans_msg = oslo_i18n.translate(msg, my_locale)
If a locale is not specified the default locale is used.
Available Languages
Only the languages that have translations provided are available for
translation. To determine which languages are available the ~oslo_i18n.get_available_languages
is provided. The
integration module provides a domain defined specific function.
import myapp._i18n
= myapp._i18n.get_available_languages() languages
guidelines