[I18n-sig] Re: pygettext dilemma

François Pinard pinard@iro.umontreal.ca
13 Aug 2001 08:10:56 -0400

[Barry A. Warsaw]

> Indeed!  BTW, I18N Mailman is coming along very nicely now.  I hope
> the 2.1 release will happen within the next few months.

I have a few friends who are impatiently waiting for this release! :-)

> What I do in this situation is to temporarily bind _() to a no-op
> function so that the string is marked for extraction, but not
> translated in place.  E.g.

>     import gettext

>     def _(s):
>         return s

>     foo = _('extract this string but do not translate it yet')

>     _ = gettext.gettext

No hurt intended of course, you should know be better :-).  Let me friendly
stress that constructs like above are ugly.  We should set up examples,
that people could follow, in which we rely on a single, common, widespread,
unvarying interpretation of _(TEXT), without having to look around each
time to see what it means, or set and reset its meaning.  The above is a
kludge that does not fit well with what I think is good Python style.

> This works perfectly because Python doesn't suffer from the same
> deficiencies as C (i.e. the C pre-processor :).

I quite understand that "it works", but yet, it much suffers, both on the
side of legibility and simplicity.

>     |    ''"""TEXT"""    8-quoted     marked

> This has been brought up before, and I know that some people really
> like this approach.  I don't though, because 1) it is too magical; 2)
> the rules are arbitrary and hard to remember; 3) explicit is better
> than implicit.

As long `pygettext.py' (or `xgettext' or `xpot') is involved, there is
some unavoidable magic somewhere.  Even _(TEXT) does not give much clue
to a newcomer about the mandatory extraction process.

About the idiom of prefixing a string with two quotes of the other kind,
I find it quite easy to explain and remember.

> Seeing something like an unadorned ""'Traditional Chinese' really
> gives no clue as to the purpose of this strange markup,

In my opinion, this is equally opaque to use _(TEXT) after having temporarily
redefined _() as the identify function.  It only acquire meaning to a
user after s/he learns about the extraction process, you just cannot make
it evident.  The explanation is unavoidable, anyway.  Redefining _() is a
formidable stunt.  Concatenating an empty string is much simpler and cleaner.

> Or, you can sometimes do something ugly like use explicit

>     __doc__ = _('Here is a module docstring')

> Not pretty, but also not common I think, so it doesn't concern me much.

Let's avoid being ugly, as far as we can.  Keep in mind that you are
opening a way, here, and setting up examples and methods that will stick,
and have incidence.  (One never knows.  When I started to use `_' instead
of explicit `gettext' calls, most people were reluctant, and told me
that it was to break with so many C compilers that I should give up now;
Richard Stallman just refused to see GNU standards suggesting it; but I
used it nevertheless and for many packages, to the point it stuck somewhat;
nowadays, many languages spontaneously use conventions similar to it.)

My point is that you should look forward and a little beyond the immediate
needs.  Even if does not concern you much, let's try to do well.

> I appreciate the suggestions Francois!  I think what we've got gives us
> the best approach for Python programs.

I would not want to crusade inordinately over this, and I'm not really trying
to punch _my_ own suggestions through.  Really not!  On the other hand,
I would like to convince you that temporarily overriding _(), or assigning
the __doc__ attribute directly, just _cannot_ be "the best approach".
We should do better than that.  My suggestion does better already, but
I see we do not agree on this, a bit sadly...  I surely do not mind if
someone comes with something even better that what we both suggest, and do
hope it happens!  But we should at least come with something as good.

                                        Keep happy!

François Pinard   http://www.iro.umontreal.ca/~pinard