[Python-Dev] Re: PEP 292, Simpler String Substitutions

Barry A. Warsaw barry@zope.com
Sun, 23 Jun 2002 11:33:18 -0400

>>>>> "NH" == Neil Hodgson <nhodgson@bigpond.net.au> writes:

    >> The feature would be useless to me if I had to
    >> pass some explicit dictionary into the _() method.  It makes
    >> writing i18n code extremely tedious.

    NH>    I think you are overstating the problem here.

Trust me, I'm not.  Then again, maybe it's just me, or my limited
experience w/ i18n'd source code, but being forced to pass in the
explicit bindings is a big burden in terms of maintainability and
    NH> The explicit bindings are a small increase over your current
    NH> code as you are already creating an extra variable just to use
    NH> the automatic binding. With explicit bindings:

    NH> def whereBorn(name):
    |    return _('$name was born in $country',
    |         name=name, country=countryOfOrigin(name))

More often then not, you already have the values you want to
interpolate sitting in local variables for other uses inside the
function.  Notice how you've written `name' 5 times there?  Try that
with every other line of code and see if it doesn't get tedious. ;)

    NH>    The protection provided is not just against untrustworthy
    NH> translaters but also allows checking the initial language
    NH> code. You can ensure all the interpolations are provided with
    NH> values and all the provided values are used.

Yes, you could do that.  Note that the actual interpolation function
/does/ have access to a dictionary, it might have more stuff than you
want (making the second check impossible), but the first check could
be done.
    NH> It avoids exposing implementation details such as the names of
    NH> local variables

This isn't an issue from a security concern, if the code is open
source.  And you should be picking meaningful local variable names
anyway!  Mine tend to be stuff like `subject', `listname',
`realname'.  I've yet to get a question about the meaning of an
interpolation variable.

Actually, translators really need access to the source code anyway,
and .po files usually contain references to the file and line number
of the source string, and po-mode makes it easy for translators to
locate the context and the purpose of the translation.

    NH> and can ensure that a more meaningful identifier in the local
    NH> context of the string is available to the translator. For
    NH> example, I may have some code that processes a command line
    NH> argument which has multiple uses on different execution paths:
    NH> _('$moduleName already exists', moduleName = arg)
    NH> _('$searchString can not be found', searchString = arg)

+1 on using explicit bindings or a dictionary when it improves

    NH>    Not making bindings explicit may mean that translators use
    NH> other variables available at the translation point leading to
    NH> unexpected failures when internal details are changed.

I18n'ing a program means you have to worry about a lot more things.
If some local variable changed, I'd consider using an explicit binding
to preserve the original source string, a change to which would force
updated translations.  Then again, you tend to get paranoid about
changing /any/ source string, say to remove a comma, adjust
whitespace, or fix a preposition.  Any change means a dozen language
teams have a new message they must translate (unless you can
mechanically fix them for them).

Another i18n approach altogether uses explicit message ids instead of
using the source string as the implicit message id, but that has a
whole 'nuther set of issues.

multi-lingual-ly y'rs,