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