[Merge] lp:~songofacandy/bzr/i18n into lp:bzr

Stephen J. Turnbull stephen at xemacs.org
Wed May 11 14:51:20 UTC 2011


Alexander Belchenko writes:

 > I can add even more reasons against using _() in first place.
 > 
 > Function _() is just alias to some gettext method which is bound to 
 > specific language at installing time.

That's false.  You can change languages at invocation time, and add
new languages after installation.  You can even change languages on
the fly (but this requires some extra effort from the application
programmer, and I'm not sure whether it's possible with Python's
gettext wrapper, I've only worked with previously I18N-ed programs in
Python, not actually done the I18N myself -- all my experience with
writing gettext code is in C).

 > So the usual practice for GUI applications

GUI apps like to treat the user as a single-celled organism, incapable
of walking and chewing gum at the same time.  What else is new?  We
can do better, past practice does not limit us.

 > is to install _() into global namespace leaving gettext to
 > determine what language user wants to see and don't care about
 > translations anymore.

gettext uses the POSIX locale API, which certainly sucks for many
purposes, but for this application it ain't no biggee:

    setlocale(LC_MESSAGES, locale_of_choice)

It's just not that hard.  Note that without a setlocale call, you
won't get any translations anyway.  So you just add logic to pick up
the user's preferred locale from a config file or query for it
interactively or whatever, rather than delegating it to the
environment with "setlocale(LC_ALL)".

 > 1) Function _() translates the strings to some language immediately. 
[...]
 > But  this is simply the wrong way for CLI like bzr, who wants to achieve 
 > speed. Bzr wants to be lazy and don't do extra work until it's really 
 > needed.

I don't understand what you mean by "immediately".  Of course the call
to _() looks up and returns a string "immediately".  But gettext()
doesn't do any work until called, which should be done at display
time, and only for the strings to be displayed.  Where's the
efficiency problem?

Ie, in

    if need_m17n:
        print _("Boy, do POSIX locale APIs suck!")
    else
        print _("POSIX locale APIs will do for most I18N usage.")

only one of the two strings will be looked up and translated on each
pass through the block.  Or consider:

    # Dummy "marker" function for convenience of xgettext y amigos.
    def N_(x): return x

    # No strings are translated, at nominal expense.
    # It's probably possible to avoid the cost of the dummy function call.
    look_ma_jit_translation = [ N_("one"),
                                N_("two"),
                                N_("three"),
                                N_("four"),
                                N_("five"),
                                N_("six") ]

    die = random.Random()

    # Two strings are translated.
    print _("Result of die roll: "), 
    print _(look_ma_jit_translation[die.randrange(0,6)])

 > 2) Function _() translate the strings to some language immediately.
 > That will be VERY bad for tests which check output of bzr commands. 
 > Output never will match until you have forced C locale before running tetst.

You should be doing that anyway, unless you're testing I18N features.
Cf. the infamous non-bugs where en_US collates a-z as "aBbCc...Zz"
... screwing up all your regexps unless you use "[[:ugly:]]", er,
"[[:lower:]]".

 > 3) For QBzr/Explorer I've implemented support for user-defined language 
 > of the UI, it's stored as language option in bazaar.conf.

It's easy to do that if you use gettext, simply by adjusting your
setlocale() call.

 > I can be wrong of course, and will be happy to hear the contra
 > arguments.

I don't have time to dig into qbzr, but before you argue *against* a
particular *implementation* you should find out what its capabilities
are.  Everything you've mentioned so far is certainly possible with
gettext().  *I've done it.*

"Standards" == requirements are another matter:

 > So maybe my own standards a bit higher than in the other
 > projects.

Your standards are higher, and that's why your projects do more than
others do.  Not because they use gettext().

If your classes do a good job of I18N, and are compatible with tools
that make it easy for translators to do their work (in practice, AFAIK
this means generating .pot files for them), feel free to advocate
them, of course.  I have no complaint against them, but they need to
be at least as good as gettext.




More information about the bazaar mailing list