1 | \section{\module{gettext} ---
|
---|
2 | Multilingual internationalization services}
|
---|
3 |
|
---|
4 | \declaremodule{standard}{gettext}
|
---|
5 | \modulesynopsis{Multilingual internationalization services.}
|
---|
6 | \moduleauthor{Barry A. Warsaw}{barry@zope.com}
|
---|
7 | \sectionauthor{Barry A. Warsaw}{barry@zope.com}
|
---|
8 |
|
---|
9 |
|
---|
10 | The \module{gettext} module provides internationalization (I18N) and
|
---|
11 | localization (L10N) services for your Python modules and applications.
|
---|
12 | It supports both the GNU \code{gettext} message catalog API and a
|
---|
13 | higher level, class-based API that may be more appropriate for Python
|
---|
14 | files. The interface described below allows you to write your
|
---|
15 | module and application messages in one natural language, and provide a
|
---|
16 | catalog of translated messages for running under different natural
|
---|
17 | languages.
|
---|
18 |
|
---|
19 | Some hints on localizing your Python modules and applications are also
|
---|
20 | given.
|
---|
21 |
|
---|
22 | \subsection{GNU \program{gettext} API}
|
---|
23 |
|
---|
24 | The \module{gettext} module defines the following API, which is very
|
---|
25 | similar to the GNU \program{gettext} API. If you use this API you
|
---|
26 | will affect the translation of your entire application globally. Often
|
---|
27 | this is what you want if your application is monolingual, with the choice
|
---|
28 | of language dependent on the locale of your user. If you are
|
---|
29 | localizing a Python module, or if your application needs to switch
|
---|
30 | languages on the fly, you probably want to use the class-based API
|
---|
31 | instead.
|
---|
32 |
|
---|
33 | \begin{funcdesc}{bindtextdomain}{domain\optional{, localedir}}
|
---|
34 | Bind the \var{domain} to the locale directory
|
---|
35 | \var{localedir}. More concretely, \module{gettext} will look for
|
---|
36 | binary \file{.mo} files for the given domain using the path (on \UNIX):
|
---|
37 | \file{\var{localedir}/\var{language}/LC_MESSAGES/\var{domain}.mo},
|
---|
38 | where \var{languages} is searched for in the environment variables
|
---|
39 | \envvar{LANGUAGE}, \envvar{LC_ALL}, \envvar{LC_MESSAGES}, and
|
---|
40 | \envvar{LANG} respectively.
|
---|
41 |
|
---|
42 | If \var{localedir} is omitted or \code{None}, then the current binding
|
---|
43 | for \var{domain} is returned.\footnote{
|
---|
44 | The default locale directory is system dependent; for example,
|
---|
45 | on RedHat Linux it is \file{/usr/share/locale}, but on Solaris
|
---|
46 | it is \file{/usr/lib/locale}. The \module{gettext} module
|
---|
47 | does not try to support these system dependent defaults;
|
---|
48 | instead its default is \file{\code{sys.prefix}/share/locale}.
|
---|
49 | For this reason, it is always best to call
|
---|
50 | \function{bindtextdomain()} with an explicit absolute path at
|
---|
51 | the start of your application.}
|
---|
52 | \end{funcdesc}
|
---|
53 |
|
---|
54 | \begin{funcdesc}{bind_textdomain_codeset}{domain\optional{, codeset}}
|
---|
55 | Bind the \var{domain} to \var{codeset}, changing the encoding of
|
---|
56 | strings returned by the \function{gettext()} family of functions.
|
---|
57 | If \var{codeset} is omitted, then the current binding is returned.
|
---|
58 |
|
---|
59 | \versionadded{2.4}
|
---|
60 | \end{funcdesc}
|
---|
61 |
|
---|
62 | \begin{funcdesc}{textdomain}{\optional{domain}}
|
---|
63 | Change or query the current global domain. If \var{domain} is
|
---|
64 | \code{None}, then the current global domain is returned, otherwise the
|
---|
65 | global domain is set to \var{domain}, which is returned.
|
---|
66 | \end{funcdesc}
|
---|
67 |
|
---|
68 | \begin{funcdesc}{gettext}{message}
|
---|
69 | Return the localized translation of \var{message}, based on the
|
---|
70 | current global domain, language, and locale directory. This function
|
---|
71 | is usually aliased as \function{_} in the local namespace (see
|
---|
72 | examples below).
|
---|
73 | \end{funcdesc}
|
---|
74 |
|
---|
75 | \begin{funcdesc}{lgettext}{message}
|
---|
76 | Equivalent to \function{gettext()}, but the translation is returned
|
---|
77 | in the preferred system encoding, if no other encoding was explicitly
|
---|
78 | set with \function{bind_textdomain_codeset()}.
|
---|
79 |
|
---|
80 | \versionadded{2.4}
|
---|
81 | \end{funcdesc}
|
---|
82 |
|
---|
83 | \begin{funcdesc}{dgettext}{domain, message}
|
---|
84 | Like \function{gettext()}, but look the message up in the specified
|
---|
85 | \var{domain}.
|
---|
86 | \end{funcdesc}
|
---|
87 |
|
---|
88 | \begin{funcdesc}{ldgettext}{domain, message}
|
---|
89 | Equivalent to \function{dgettext()}, but the translation is returned
|
---|
90 | in the preferred system encoding, if no other encoding was explicitly
|
---|
91 | set with \function{bind_textdomain_codeset()}.
|
---|
92 |
|
---|
93 | \versionadded{2.4}
|
---|
94 | \end{funcdesc}
|
---|
95 |
|
---|
96 | \begin{funcdesc}{ngettext}{singular, plural, n}
|
---|
97 |
|
---|
98 | Like \function{gettext()}, but consider plural forms. If a translation
|
---|
99 | is found, apply the plural formula to \var{n}, and return the
|
---|
100 | resulting message (some languages have more than two plural forms).
|
---|
101 | If no translation is found, return \var{singular} if \var{n} is 1;
|
---|
102 | return \var{plural} otherwise.
|
---|
103 |
|
---|
104 | The Plural formula is taken from the catalog header. It is a C or
|
---|
105 | Python expression that has a free variable n; the expression evaluates
|
---|
106 | to the index of the plural in the catalog. See the GNU gettext
|
---|
107 | documentation for the precise syntax to be used in .po files, and the
|
---|
108 | formulas for a variety of languages.
|
---|
109 |
|
---|
110 | \versionadded{2.3}
|
---|
111 |
|
---|
112 | \end{funcdesc}
|
---|
113 |
|
---|
114 | \begin{funcdesc}{lngettext}{singular, plural, n}
|
---|
115 | Equivalent to \function{ngettext()}, but the translation is returned
|
---|
116 | in the preferred system encoding, if no other encoding was explicitly
|
---|
117 | set with \function{bind_textdomain_codeset()}.
|
---|
118 |
|
---|
119 | \versionadded{2.4}
|
---|
120 | \end{funcdesc}
|
---|
121 |
|
---|
122 | \begin{funcdesc}{dngettext}{domain, singular, plural, n}
|
---|
123 | Like \function{ngettext()}, but look the message up in the specified
|
---|
124 | \var{domain}.
|
---|
125 |
|
---|
126 | \versionadded{2.3}
|
---|
127 | \end{funcdesc}
|
---|
128 |
|
---|
129 | \begin{funcdesc}{ldngettext}{domain, singular, plural, n}
|
---|
130 | Equivalent to \function{dngettext()}, but the translation is returned
|
---|
131 | in the preferred system encoding, if no other encoding was explicitly
|
---|
132 | set with \function{bind_textdomain_codeset()}.
|
---|
133 |
|
---|
134 | \versionadded{2.4}
|
---|
135 | \end{funcdesc}
|
---|
136 |
|
---|
137 |
|
---|
138 |
|
---|
139 | Note that GNU \program{gettext} also defines a \function{dcgettext()}
|
---|
140 | method, but this was deemed not useful and so it is currently
|
---|
141 | unimplemented.
|
---|
142 |
|
---|
143 | Here's an example of typical usage for this API:
|
---|
144 |
|
---|
145 | \begin{verbatim}
|
---|
146 | import gettext
|
---|
147 | gettext.bindtextdomain('myapplication', '/path/to/my/language/directory')
|
---|
148 | gettext.textdomain('myapplication')
|
---|
149 | _ = gettext.gettext
|
---|
150 | # ...
|
---|
151 | print _('This is a translatable string.')
|
---|
152 | \end{verbatim}
|
---|
153 |
|
---|
154 | \subsection{Class-based API}
|
---|
155 |
|
---|
156 | The class-based API of the \module{gettext} module gives you more
|
---|
157 | flexibility and greater convenience than the GNU \program{gettext}
|
---|
158 | API. It is the recommended way of localizing your Python applications and
|
---|
159 | modules. \module{gettext} defines a ``translations'' class which
|
---|
160 | implements the parsing of GNU \file{.mo} format files, and has methods
|
---|
161 | for returning either standard 8-bit strings or Unicode strings.
|
---|
162 | Instances of this ``translations'' class can also install themselves
|
---|
163 | in the built-in namespace as the function \function{_()}.
|
---|
164 |
|
---|
165 | \begin{funcdesc}{find}{domain\optional{, localedir\optional{,
|
---|
166 | languages\optional{, all}}}}
|
---|
167 | This function implements the standard \file{.mo} file search
|
---|
168 | algorithm. It takes a \var{domain}, identical to what
|
---|
169 | \function{textdomain()} takes. Optional \var{localedir} is as in
|
---|
170 | \function{bindtextdomain()} Optional \var{languages} is a list of
|
---|
171 | strings, where each string is a language code.
|
---|
172 |
|
---|
173 | If \var{localedir} is not given, then the default system locale
|
---|
174 | directory is used.\footnote{See the footnote for
|
---|
175 | \function{bindtextdomain()} above.} If \var{languages} is not given,
|
---|
176 | then the following environment variables are searched: \envvar{LANGUAGE},
|
---|
177 | \envvar{LC_ALL}, \envvar{LC_MESSAGES}, and \envvar{LANG}. The first one
|
---|
178 | returning a non-empty value is used for the \var{languages} variable.
|
---|
179 | The environment variables should contain a colon separated list of
|
---|
180 | languages, which will be split on the colon to produce the expected
|
---|
181 | list of language code strings.
|
---|
182 |
|
---|
183 | \function{find()} then expands and normalizes the languages, and then
|
---|
184 | iterates through them, searching for an existing file built of these
|
---|
185 | components:
|
---|
186 |
|
---|
187 | \file{\var{localedir}/\var{language}/LC_MESSAGES/\var{domain}.mo}
|
---|
188 |
|
---|
189 | The first such file name that exists is returned by \function{find()}.
|
---|
190 | If no such file is found, then \code{None} is returned. If \var{all}
|
---|
191 | is given, it returns a list of all file names, in the order in which
|
---|
192 | they appear in the languages list or the environment variables.
|
---|
193 | \end{funcdesc}
|
---|
194 |
|
---|
195 | \begin{funcdesc}{translation}{domain\optional{, localedir\optional{,
|
---|
196 | languages\optional{, class_\optional{,
|
---|
197 | fallback\optional{, codeset}}}}}}
|
---|
198 | Return a \class{Translations} instance based on the \var{domain},
|
---|
199 | \var{localedir}, and \var{languages}, which are first passed to
|
---|
200 | \function{find()} to get a list of the
|
---|
201 | associated \file{.mo} file paths. Instances with
|
---|
202 | identical \file{.mo} file names are cached. The actual class instantiated
|
---|
203 | is either \var{class_} if provided, otherwise
|
---|
204 | \class{GNUTranslations}. The class's constructor must take a single
|
---|
205 | file object argument. If provided, \var{codeset} will change the
|
---|
206 | charset used to encode translated strings.
|
---|
207 |
|
---|
208 | If multiple files are found, later files are used as fallbacks for
|
---|
209 | earlier ones. To allow setting the fallback, \function{copy.copy}
|
---|
210 | is used to clone each translation object from the cache; the actual
|
---|
211 | instance data is still shared with the cache.
|
---|
212 |
|
---|
213 | If no \file{.mo} file is found, this function raises
|
---|
214 | \exception{IOError} if \var{fallback} is false (which is the default),
|
---|
215 | and returns a \class{NullTranslations} instance if \var{fallback} is
|
---|
216 | true.
|
---|
217 |
|
---|
218 | \versionchanged[Added the \var{codeset} parameter]{2.4}
|
---|
219 | \end{funcdesc}
|
---|
220 |
|
---|
221 | \begin{funcdesc}{install}{domain\optional{, localedir\optional{, unicode
|
---|
222 | \optional{, codeset\optional{, names}}}}}
|
---|
223 | This installs the function \function{_} in Python's builtin namespace,
|
---|
224 | based on \var{domain}, \var{localedir}, and \var{codeset} which are
|
---|
225 | passed to the function \function{translation()}. The \var{unicode}
|
---|
226 | flag is passed to the resulting translation object's \method{install}
|
---|
227 | method.
|
---|
228 |
|
---|
229 | For the \var{names} parameter, please see the description of the
|
---|
230 | translation object's \method{install} method.
|
---|
231 |
|
---|
232 | As seen below, you usually mark the strings in your application that are
|
---|
233 | candidates for translation, by wrapping them in a call to the
|
---|
234 | \function{_()} function, like this:
|
---|
235 |
|
---|
236 | \begin{verbatim}
|
---|
237 | print _('This string will be translated.')
|
---|
238 | \end{verbatim}
|
---|
239 |
|
---|
240 | For convenience, you want the \function{_()} function to be installed in
|
---|
241 | Python's builtin namespace, so it is easily accessible in all modules
|
---|
242 | of your application.
|
---|
243 |
|
---|
244 | \versionchanged[Added the \var{codeset} parameter]{2.4}
|
---|
245 | \versionchanged[Added the \var{names} parameter]{2.5}
|
---|
246 | \end{funcdesc}
|
---|
247 |
|
---|
248 | \subsubsection{The \class{NullTranslations} class}
|
---|
249 | Translation classes are what actually implement the translation of
|
---|
250 | original source file message strings to translated message strings.
|
---|
251 | The base class used by all translation classes is
|
---|
252 | \class{NullTranslations}; this provides the basic interface you can use
|
---|
253 | to write your own specialized translation classes. Here are the
|
---|
254 | methods of \class{NullTranslations}:
|
---|
255 |
|
---|
256 | \begin{methoddesc}[NullTranslations]{__init__}{\optional{fp}}
|
---|
257 | Takes an optional file object \var{fp}, which is ignored by the base
|
---|
258 | class. Initializes ``protected'' instance variables \var{_info} and
|
---|
259 | \var{_charset} which are set by derived classes, as well as \var{_fallback},
|
---|
260 | which is set through \method{add_fallback}. It then calls
|
---|
261 | \code{self._parse(fp)} if \var{fp} is not \code{None}.
|
---|
262 | \end{methoddesc}
|
---|
263 |
|
---|
264 | \begin{methoddesc}[NullTranslations]{_parse}{fp}
|
---|
265 | No-op'd in the base class, this method takes file object \var{fp}, and
|
---|
266 | reads the data from the file, initializing its message catalog. If
|
---|
267 | you have an unsupported message catalog file format, you should
|
---|
268 | override this method to parse your format.
|
---|
269 | \end{methoddesc}
|
---|
270 |
|
---|
271 | \begin{methoddesc}[NullTranslations]{add_fallback}{fallback}
|
---|
272 | Add \var{fallback} as the fallback object for the current translation
|
---|
273 | object. A translation object should consult the fallback if it cannot
|
---|
274 | provide a translation for a given message.
|
---|
275 | \end{methoddesc}
|
---|
276 |
|
---|
277 | \begin{methoddesc}[NullTranslations]{gettext}{message}
|
---|
278 | If a fallback has been set, forward \method{gettext()} to the fallback.
|
---|
279 | Otherwise, return the translated message. Overridden in derived classes.
|
---|
280 | \end{methoddesc}
|
---|
281 |
|
---|
282 | \begin{methoddesc}[NullTranslations]{lgettext}{message}
|
---|
283 | If a fallback has been set, forward \method{lgettext()} to the fallback.
|
---|
284 | Otherwise, return the translated message. Overridden in derived classes.
|
---|
285 |
|
---|
286 | \versionadded{2.4}
|
---|
287 | \end{methoddesc}
|
---|
288 |
|
---|
289 | \begin{methoddesc}[NullTranslations]{ugettext}{message}
|
---|
290 | If a fallback has been set, forward \method{ugettext()} to the fallback.
|
---|
291 | Otherwise, return the translated message as a Unicode string.
|
---|
292 | Overridden in derived classes.
|
---|
293 | \end{methoddesc}
|
---|
294 |
|
---|
295 | \begin{methoddesc}[NullTranslations]{ngettext}{singular, plural, n}
|
---|
296 | If a fallback has been set, forward \method{ngettext()} to the fallback.
|
---|
297 | Otherwise, return the translated message. Overridden in derived classes.
|
---|
298 |
|
---|
299 | \versionadded{2.3}
|
---|
300 | \end{methoddesc}
|
---|
301 |
|
---|
302 | \begin{methoddesc}[NullTranslations]{lngettext}{singular, plural, n}
|
---|
303 | If a fallback has been set, forward \method{ngettext()} to the fallback.
|
---|
304 | Otherwise, return the translated message. Overridden in derived classes.
|
---|
305 |
|
---|
306 | \versionadded{2.4}
|
---|
307 | \end{methoddesc}
|
---|
308 |
|
---|
309 | \begin{methoddesc}[NullTranslations]{ungettext}{singular, plural, n}
|
---|
310 | If a fallback has been set, forward \method{ungettext()} to the fallback.
|
---|
311 | Otherwise, return the translated message as a Unicode string.
|
---|
312 | Overridden in derived classes.
|
---|
313 |
|
---|
314 | \versionadded{2.3}
|
---|
315 | \end{methoddesc}
|
---|
316 |
|
---|
317 | \begin{methoddesc}[NullTranslations]{info}{}
|
---|
318 | Return the ``protected'' \member{_info} variable.
|
---|
319 | \end{methoddesc}
|
---|
320 |
|
---|
321 | \begin{methoddesc}[NullTranslations]{charset}{}
|
---|
322 | Return the ``protected'' \member{_charset} variable.
|
---|
323 | \end{methoddesc}
|
---|
324 |
|
---|
325 | \begin{methoddesc}[NullTranslations]{output_charset}{}
|
---|
326 | Return the ``protected'' \member{_output_charset} variable, which
|
---|
327 | defines the encoding used to return translated messages.
|
---|
328 |
|
---|
329 | \versionadded{2.4}
|
---|
330 | \end{methoddesc}
|
---|
331 |
|
---|
332 | \begin{methoddesc}[NullTranslations]{set_output_charset}{charset}
|
---|
333 | Change the ``protected'' \member{_output_charset} variable, which
|
---|
334 | defines the encoding used to return translated messages.
|
---|
335 |
|
---|
336 | \versionadded{2.4}
|
---|
337 | \end{methoddesc}
|
---|
338 |
|
---|
339 | \begin{methoddesc}[NullTranslations]{install}{\optional{unicode
|
---|
340 | \optional{, names}}}
|
---|
341 | If the \var{unicode} flag is false, this method installs
|
---|
342 | \method{self.gettext()} into the built-in namespace, binding it to
|
---|
343 | \samp{_}. If \var{unicode} is true, it binds \method{self.ugettext()}
|
---|
344 | instead. By default, \var{unicode} is false.
|
---|
345 |
|
---|
346 | If the \var{names} parameter is given, it must be a sequence containing
|
---|
347 | the names of functions you want to install in the builtin namespace in
|
---|
348 | addition to \function{_()}. Supported names are \code{'gettext'} (bound
|
---|
349 | to \method{self.gettext()} or \method{self.ugettext()} according to the
|
---|
350 | \var{unicode} flag), \code{'ngettext'} (bound to \method{self.ngettext()}
|
---|
351 | or \method{self.ungettext()} according to the \var{unicode} flag),
|
---|
352 | \code{'lgettext'} and \code{'lngettext'}.
|
---|
353 |
|
---|
354 | Note that this is only one way, albeit the most convenient way, to
|
---|
355 | make the \function{_} function available to your application. Because it
|
---|
356 | affects the entire application globally, and specifically the built-in
|
---|
357 | namespace, localized modules should never install \function{_}.
|
---|
358 | Instead, they should use this code to make \function{_} available to
|
---|
359 | their module:
|
---|
360 |
|
---|
361 | \begin{verbatim}
|
---|
362 | import gettext
|
---|
363 | t = gettext.translation('mymodule', ...)
|
---|
364 | _ = t.gettext
|
---|
365 | \end{verbatim}
|
---|
366 |
|
---|
367 | This puts \function{_} only in the module's global namespace and so
|
---|
368 | only affects calls within this module.
|
---|
369 |
|
---|
370 | \versionchanged[Added the \var{names} parameter]{2.5}
|
---|
371 | \end{methoddesc}
|
---|
372 |
|
---|
373 | \subsubsection{The \class{GNUTranslations} class}
|
---|
374 |
|
---|
375 | The \module{gettext} module provides one additional class derived from
|
---|
376 | \class{NullTranslations}: \class{GNUTranslations}. This class
|
---|
377 | overrides \method{_parse()} to enable reading GNU \program{gettext}
|
---|
378 | format \file{.mo} files in both big-endian and little-endian format.
|
---|
379 | It also coerces both message ids and message strings to Unicode.
|
---|
380 |
|
---|
381 | \class{GNUTranslations} parses optional meta-data out of the
|
---|
382 | translation catalog. It is convention with GNU \program{gettext} to
|
---|
383 | include meta-data as the translation for the empty string. This
|
---|
384 | meta-data is in \rfc{822}-style \code{key: value} pairs, and should
|
---|
385 | contain the \code{Project-Id-Version} key. If the key
|
---|
386 | \code{Content-Type} is found, then the \code{charset} property is used
|
---|
387 | to initialize the ``protected'' \member{_charset} instance variable,
|
---|
388 | defaulting to \code{None} if not found. If the charset encoding is
|
---|
389 | specified, then all message ids and message strings read from the
|
---|
390 | catalog are converted to Unicode using this encoding. The
|
---|
391 | \method{ugettext()} method always returns a Unicode, while the
|
---|
392 | \method{gettext()} returns an encoded 8-bit string. For the message
|
---|
393 | id arguments of both methods, either Unicode strings or 8-bit strings
|
---|
394 | containing only US-ASCII characters are acceptable. Note that the
|
---|
395 | Unicode version of the methods (i.e. \method{ugettext()} and
|
---|
396 | \method{ungettext()}) are the recommended interface to use for
|
---|
397 | internationalized Python programs.
|
---|
398 |
|
---|
399 | The entire set of key/value pairs are placed into a dictionary and set
|
---|
400 | as the ``protected'' \member{_info} instance variable.
|
---|
401 |
|
---|
402 | If the \file{.mo} file's magic number is invalid, or if other problems
|
---|
403 | occur while reading the file, instantiating a \class{GNUTranslations} class
|
---|
404 | can raise \exception{IOError}.
|
---|
405 |
|
---|
406 | The following methods are overridden from the base class implementation:
|
---|
407 |
|
---|
408 | \begin{methoddesc}[GNUTranslations]{gettext}{message}
|
---|
409 | Look up the \var{message} id in the catalog and return the
|
---|
410 | corresponding message string, as an 8-bit string encoded with the
|
---|
411 | catalog's charset encoding, if known. If there is no entry in the
|
---|
412 | catalog for the \var{message} id, and a fallback has been set, the
|
---|
413 | look up is forwarded to the fallback's \method{gettext()} method.
|
---|
414 | Otherwise, the \var{message} id is returned.
|
---|
415 | \end{methoddesc}
|
---|
416 |
|
---|
417 | \begin{methoddesc}[GNUTranslations]{lgettext}{message}
|
---|
418 | Equivalent to \method{gettext()}, but the translation is returned
|
---|
419 | in the preferred system encoding, if no other encoding was explicitly
|
---|
420 | set with \method{set_output_charset()}.
|
---|
421 |
|
---|
422 | \versionadded{2.4}
|
---|
423 | \end{methoddesc}
|
---|
424 |
|
---|
425 | \begin{methoddesc}[GNUTranslations]{ugettext}{message}
|
---|
426 | Look up the \var{message} id in the catalog and return the
|
---|
427 | corresponding message string, as a Unicode string. If there is no
|
---|
428 | entry in the catalog for the \var{message} id, and a fallback has been
|
---|
429 | set, the look up is forwarded to the fallback's \method{ugettext()}
|
---|
430 | method. Otherwise, the \var{message} id is returned.
|
---|
431 | \end{methoddesc}
|
---|
432 |
|
---|
433 | \begin{methoddesc}[GNUTranslations]{ngettext}{singular, plural, n}
|
---|
434 | Do a plural-forms lookup of a message id. \var{singular} is used as
|
---|
435 | the message id for purposes of lookup in the catalog, while \var{n} is
|
---|
436 | used to determine which plural form to use. The returned message
|
---|
437 | string is an 8-bit string encoded with the catalog's charset encoding,
|
---|
438 | if known.
|
---|
439 |
|
---|
440 | If the message id is not found in the catalog, and a fallback is
|
---|
441 | specified, the request is forwarded to the fallback's
|
---|
442 | \method{ngettext()} method. Otherwise, when \var{n} is 1 \var{singular} is
|
---|
443 | returned, and \var{plural} is returned in all other cases.
|
---|
444 |
|
---|
445 | \versionadded{2.3}
|
---|
446 | \end{methoddesc}
|
---|
447 |
|
---|
448 | \begin{methoddesc}[GNUTranslations]{lngettext}{singular, plural, n}
|
---|
449 | Equivalent to \method{gettext()}, but the translation is returned
|
---|
450 | in the preferred system encoding, if no other encoding was explicitly
|
---|
451 | set with \method{set_output_charset()}.
|
---|
452 |
|
---|
453 | \versionadded{2.4}
|
---|
454 | \end{methoddesc}
|
---|
455 |
|
---|
456 | \begin{methoddesc}[GNUTranslations]{ungettext}{singular, plural, n}
|
---|
457 | Do a plural-forms lookup of a message id. \var{singular} is used as
|
---|
458 | the message id for purposes of lookup in the catalog, while \var{n} is
|
---|
459 | used to determine which plural form to use. The returned message
|
---|
460 | string is a Unicode string.
|
---|
461 |
|
---|
462 | If the message id is not found in the catalog, and a fallback is
|
---|
463 | specified, the request is forwarded to the fallback's
|
---|
464 | \method{ungettext()} method. Otherwise, when \var{n} is 1 \var{singular} is
|
---|
465 | returned, and \var{plural} is returned in all other cases.
|
---|
466 |
|
---|
467 | Here is an example:
|
---|
468 |
|
---|
469 | \begin{verbatim}
|
---|
470 | n = len(os.listdir('.'))
|
---|
471 | cat = GNUTranslations(somefile)
|
---|
472 | message = cat.ungettext(
|
---|
473 | 'There is %(num)d file in this directory',
|
---|
474 | 'There are %(num)d files in this directory',
|
---|
475 | n) % {'num': n}
|
---|
476 | \end{verbatim}
|
---|
477 |
|
---|
478 | \versionadded{2.3}
|
---|
479 | \end{methoddesc}
|
---|
480 |
|
---|
481 | \subsubsection{Solaris message catalog support}
|
---|
482 |
|
---|
483 | The Solaris operating system defines its own binary
|
---|
484 | \file{.mo} file format, but since no documentation can be found on
|
---|
485 | this format, it is not supported at this time.
|
---|
486 |
|
---|
487 | \subsubsection{The Catalog constructor}
|
---|
488 |
|
---|
489 | GNOME\index{GNOME} uses a version of the \module{gettext} module by
|
---|
490 | James Henstridge, but this version has a slightly different API. Its
|
---|
491 | documented usage was:
|
---|
492 |
|
---|
493 | \begin{verbatim}
|
---|
494 | import gettext
|
---|
495 | cat = gettext.Catalog(domain, localedir)
|
---|
496 | _ = cat.gettext
|
---|
497 | print _('hello world')
|
---|
498 | \end{verbatim}
|
---|
499 |
|
---|
500 | For compatibility with this older module, the function
|
---|
501 | \function{Catalog()} is an alias for the \function{translation()}
|
---|
502 | function described above.
|
---|
503 |
|
---|
504 | One difference between this module and Henstridge's: his catalog
|
---|
505 | objects supported access through a mapping API, but this appears to be
|
---|
506 | unused and so is not currently supported.
|
---|
507 |
|
---|
508 | \subsection{Internationalizing your programs and modules}
|
---|
509 | Internationalization (I18N) refers to the operation by which a program
|
---|
510 | is made aware of multiple languages. Localization (L10N) refers to
|
---|
511 | the adaptation of your program, once internationalized, to the local
|
---|
512 | language and cultural habits. In order to provide multilingual
|
---|
513 | messages for your Python programs, you need to take the following
|
---|
514 | steps:
|
---|
515 |
|
---|
516 | \begin{enumerate}
|
---|
517 | \item prepare your program or module by specially marking
|
---|
518 | translatable strings
|
---|
519 | \item run a suite of tools over your marked files to generate raw
|
---|
520 | messages catalogs
|
---|
521 | \item create language specific translations of the message catalogs
|
---|
522 | \item use the \module{gettext} module so that message strings are
|
---|
523 | properly translated
|
---|
524 | \end{enumerate}
|
---|
525 |
|
---|
526 | In order to prepare your code for I18N, you need to look at all the
|
---|
527 | strings in your files. Any string that needs to be translated
|
---|
528 | should be marked by wrapping it in \code{_('...')} --- that is, a call
|
---|
529 | to the function \function{_()}. For example:
|
---|
530 |
|
---|
531 | \begin{verbatim}
|
---|
532 | filename = 'mylog.txt'
|
---|
533 | message = _('writing a log message')
|
---|
534 | fp = open(filename, 'w')
|
---|
535 | fp.write(message)
|
---|
536 | fp.close()
|
---|
537 | \end{verbatim}
|
---|
538 |
|
---|
539 | In this example, the string \code{'writing a log message'} is marked as
|
---|
540 | a candidate for translation, while the strings \code{'mylog.txt'} and
|
---|
541 | \code{'w'} are not.
|
---|
542 |
|
---|
543 | The Python distribution comes with two tools which help you generate
|
---|
544 | the message catalogs once you've prepared your source code. These may
|
---|
545 | or may not be available from a binary distribution, but they can be
|
---|
546 | found in a source distribution, in the \file{Tools/i18n} directory.
|
---|
547 |
|
---|
548 | The \program{pygettext}\footnote{Fran\c cois Pinard has
|
---|
549 | written a program called
|
---|
550 | \program{xpot} which does a similar job. It is available as part of
|
---|
551 | his \program{po-utils} package at
|
---|
552 | \url{http://po-utils.progiciels-bpi.ca/}.} program
|
---|
553 | scans all your Python source code looking for the strings you
|
---|
554 | previously marked as translatable. It is similar to the GNU
|
---|
555 | \program{gettext} program except that it understands all the
|
---|
556 | intricacies of Python source code, but knows nothing about C or \Cpp
|
---|
557 | source code. You don't need GNU \code{gettext} unless you're also
|
---|
558 | going to be translating C code (such as C extension modules).
|
---|
559 |
|
---|
560 | \program{pygettext} generates textual Uniforum-style human readable
|
---|
561 | message catalog \file{.pot} files, essentially structured human
|
---|
562 | readable files which contain every marked string in the source code,
|
---|
563 | along with a placeholder for the translation strings.
|
---|
564 | \program{pygettext} is a command line script that supports a similar
|
---|
565 | command line interface as \program{xgettext}; for details on its use,
|
---|
566 | run:
|
---|
567 |
|
---|
568 | \begin{verbatim}
|
---|
569 | pygettext.py --help
|
---|
570 | \end{verbatim}
|
---|
571 |
|
---|
572 | Copies of these \file{.pot} files are then handed over to the
|
---|
573 | individual human translators who write language-specific versions for
|
---|
574 | every supported natural language. They send you back the filled in
|
---|
575 | language-specific versions as a \file{.po} file. Using the
|
---|
576 | \program{msgfmt.py}\footnote{\program{msgfmt.py} is binary
|
---|
577 | compatible with GNU \program{msgfmt} except that it provides a
|
---|
578 | simpler, all-Python implementation. With this and
|
---|
579 | \program{pygettext.py}, you generally won't need to install the GNU
|
---|
580 | \program{gettext} package to internationalize your Python
|
---|
581 | applications.} program (in the \file{Tools/i18n} directory), you take the
|
---|
582 | \file{.po} files from your translators and generate the
|
---|
583 | machine-readable \file{.mo} binary catalog files. The \file{.mo}
|
---|
584 | files are what the \module{gettext} module uses for the actual
|
---|
585 | translation processing during run-time.
|
---|
586 |
|
---|
587 | How you use the \module{gettext} module in your code depends on
|
---|
588 | whether you are internationalizing a single module or your entire application.
|
---|
589 | The next two sections will discuss each case.
|
---|
590 |
|
---|
591 | \subsubsection{Localizing your module}
|
---|
592 |
|
---|
593 | If you are localizing your module, you must take care not to make
|
---|
594 | global changes, e.g. to the built-in namespace. You should not use
|
---|
595 | the GNU \code{gettext} API but instead the class-based API.
|
---|
596 |
|
---|
597 | Let's say your module is called ``spam'' and the module's various
|
---|
598 | natural language translation \file{.mo} files reside in
|
---|
599 | \file{/usr/share/locale} in GNU \program{gettext} format. Here's what
|
---|
600 | you would put at the top of your module:
|
---|
601 |
|
---|
602 | \begin{verbatim}
|
---|
603 | import gettext
|
---|
604 | t = gettext.translation('spam', '/usr/share/locale')
|
---|
605 | _ = t.lgettext
|
---|
606 | \end{verbatim}
|
---|
607 |
|
---|
608 | If your translators were providing you with Unicode strings in their
|
---|
609 | \file{.po} files, you'd instead do:
|
---|
610 |
|
---|
611 | \begin{verbatim}
|
---|
612 | import gettext
|
---|
613 | t = gettext.translation('spam', '/usr/share/locale')
|
---|
614 | _ = t.ugettext
|
---|
615 | \end{verbatim}
|
---|
616 |
|
---|
617 | \subsubsection{Localizing your application}
|
---|
618 |
|
---|
619 | If you are localizing your application, you can install the \function{_()}
|
---|
620 | function globally into the built-in namespace, usually in the main driver file
|
---|
621 | of your application. This will let all your application-specific
|
---|
622 | files just use \code{_('...')} without having to explicitly install it in
|
---|
623 | each file.
|
---|
624 |
|
---|
625 | In the simple case then, you need only add the following bit of code
|
---|
626 | to the main driver file of your application:
|
---|
627 |
|
---|
628 | \begin{verbatim}
|
---|
629 | import gettext
|
---|
630 | gettext.install('myapplication')
|
---|
631 | \end{verbatim}
|
---|
632 |
|
---|
633 | If you need to set the locale directory or the \var{unicode} flag,
|
---|
634 | you can pass these into the \function{install()} function:
|
---|
635 |
|
---|
636 | \begin{verbatim}
|
---|
637 | import gettext
|
---|
638 | gettext.install('myapplication', '/usr/share/locale', unicode=1)
|
---|
639 | \end{verbatim}
|
---|
640 |
|
---|
641 | \subsubsection{Changing languages on the fly}
|
---|
642 |
|
---|
643 | If your program needs to support many languages at the same time, you
|
---|
644 | may want to create multiple translation instances and then switch
|
---|
645 | between them explicitly, like so:
|
---|
646 |
|
---|
647 | \begin{verbatim}
|
---|
648 | import gettext
|
---|
649 |
|
---|
650 | lang1 = gettext.translation('myapplication', languages=['en'])
|
---|
651 | lang2 = gettext.translation('myapplication', languages=['fr'])
|
---|
652 | lang3 = gettext.translation('myapplication', languages=['de'])
|
---|
653 |
|
---|
654 | # start by using language1
|
---|
655 | lang1.install()
|
---|
656 |
|
---|
657 | # ... time goes by, user selects language 2
|
---|
658 | lang2.install()
|
---|
659 |
|
---|
660 | # ... more time goes by, user selects language 3
|
---|
661 | lang3.install()
|
---|
662 | \end{verbatim}
|
---|
663 |
|
---|
664 | \subsubsection{Deferred translations}
|
---|
665 |
|
---|
666 | In most coding situations, strings are translated where they are coded.
|
---|
667 | Occasionally however, you need to mark strings for translation, but
|
---|
668 | defer actual translation until later. A classic example is:
|
---|
669 |
|
---|
670 | \begin{verbatim}
|
---|
671 | animals = ['mollusk',
|
---|
672 | 'albatross',
|
---|
673 | 'rat',
|
---|
674 | 'penguin',
|
---|
675 | 'python',
|
---|
676 | ]
|
---|
677 | # ...
|
---|
678 | for a in animals:
|
---|
679 | print a
|
---|
680 | \end{verbatim}
|
---|
681 |
|
---|
682 | Here, you want to mark the strings in the \code{animals} list as being
|
---|
683 | translatable, but you don't actually want to translate them until they
|
---|
684 | are printed.
|
---|
685 |
|
---|
686 | Here is one way you can handle this situation:
|
---|
687 |
|
---|
688 | \begin{verbatim}
|
---|
689 | def _(message): return message
|
---|
690 |
|
---|
691 | animals = [_('mollusk'),
|
---|
692 | _('albatross'),
|
---|
693 | _('rat'),
|
---|
694 | _('penguin'),
|
---|
695 | _('python'),
|
---|
696 | ]
|
---|
697 |
|
---|
698 | del _
|
---|
699 |
|
---|
700 | # ...
|
---|
701 | for a in animals:
|
---|
702 | print _(a)
|
---|
703 | \end{verbatim}
|
---|
704 |
|
---|
705 | This works because the dummy definition of \function{_()} simply returns
|
---|
706 | the string unchanged. And this dummy definition will temporarily
|
---|
707 | override any definition of \function{_()} in the built-in namespace
|
---|
708 | (until the \keyword{del} command).
|
---|
709 | Take care, though if you have a previous definition of \function{_} in
|
---|
710 | the local namespace.
|
---|
711 |
|
---|
712 | Note that the second use of \function{_()} will not identify ``a'' as
|
---|
713 | being translatable to the \program{pygettext} program, since it is not
|
---|
714 | a string.
|
---|
715 |
|
---|
716 | Another way to handle this is with the following example:
|
---|
717 |
|
---|
718 | \begin{verbatim}
|
---|
719 | def N_(message): return message
|
---|
720 |
|
---|
721 | animals = [N_('mollusk'),
|
---|
722 | N_('albatross'),
|
---|
723 | N_('rat'),
|
---|
724 | N_('penguin'),
|
---|
725 | N_('python'),
|
---|
726 | ]
|
---|
727 |
|
---|
728 | # ...
|
---|
729 | for a in animals:
|
---|
730 | print _(a)
|
---|
731 | \end{verbatim}
|
---|
732 |
|
---|
733 | In this case, you are marking translatable strings with the function
|
---|
734 | \function{N_()},\footnote{The choice of \function{N_()} here is totally
|
---|
735 | arbitrary; it could have just as easily been
|
---|
736 | \function{MarkThisStringForTranslation()}.
|
---|
737 | } which won't conflict with any definition of
|
---|
738 | \function{_()}. However, you will need to teach your message extraction
|
---|
739 | program to look for translatable strings marked with \function{N_()}.
|
---|
740 | \program{pygettext} and \program{xpot} both support this through the
|
---|
741 | use of command line switches.
|
---|
742 |
|
---|
743 | \subsubsection{\function{gettext()} vs. \function{lgettext()}}
|
---|
744 | In Python 2.4 the \function{lgettext()} family of functions were
|
---|
745 | introduced. The intention of these functions is to provide an
|
---|
746 | alternative which is more compliant with the current
|
---|
747 | implementation of GNU gettext. Unlike \function{gettext()}, which
|
---|
748 | returns strings encoded with the same codeset used in the
|
---|
749 | translation file, \function{lgettext()} will return strings
|
---|
750 | encoded with the preferred system encoding, as returned by
|
---|
751 | \function{locale.getpreferredencoding()}. Also notice that
|
---|
752 | Python 2.4 introduces new functions to explicitly choose
|
---|
753 | the codeset used in translated strings. If a codeset is explicitly
|
---|
754 | set, even \function{lgettext()} will return translated strings in
|
---|
755 | the requested codeset, as would be expected in the GNU gettext
|
---|
756 | implementation.
|
---|
757 |
|
---|
758 | \subsection{Acknowledgements}
|
---|
759 |
|
---|
760 | The following people contributed code, feedback, design suggestions,
|
---|
761 | previous implementations, and valuable experience to the creation of
|
---|
762 | this module:
|
---|
763 |
|
---|
764 | \begin{itemize}
|
---|
765 | \item Peter Funk
|
---|
766 | \item James Henstridge
|
---|
767 | \item Juan David Ib\'a\~nez Palomar
|
---|
768 | \item Marc-Andr\'e Lemburg
|
---|
769 | \item Martin von L\"owis
|
---|
770 | \item Fran\c cois Pinard
|
---|
771 | \item Barry Warsaw
|
---|
772 | \item Gustavo Niemeyer
|
---|
773 | \end{itemize}
|
---|