Python And Internationalization maybe a pre-pep?

Brian Kelley bkelley at wi.mit.edu
Sun Jan 11 11:15:01 EST 2004


Martin v. Löwis wrote:
> Brian Kelley wrote:
> 
>> I don't see too much difference between using
>> _("STRING")
>>
>> to indicate a string to be internationalized and
>> i"STRING"
>>
>> Except that the later will be automatically noticed at compile time, 
>> not run-time.
> 
> 
> I'm not really sure what "compile time" is in Python. If it is the time
> when the .pyc files are generated: What happens if the user using the
> pyc files has a language different from the language of the
> administrator creating the files?
> 
> Or, what precisely does it mean that it is "noticed"?
> 
> 
>>> Using what textual domain?
>>>
>> I am using the same mechanism as gettext but tying it into the "import 
>> locale" mechanism.
> 
> 
> That does not answer my question? How precisely do you define the
> textual domain?
> 
> In gettext, I typically put a function at the beginning of each module
> 
> def _(msg):
>   return gettext.dgettext("grep", msg)
> 
> thus defining the textual domain as "grep". In your syntax, I see no
> place to define the textual domain.
> 
>> I think this happens fine in both cases.  The mechanism for 
>> internationalizing with wxPython just didn't feel, well, pythonic.  It 
>> felt kind of tacked into place.  Of course I feel the same way about 
>> most C macros :)
> 
> 
> Can you be more specific? Do you dislike function calls?
> 
>> Perhaps I am optimizing the wrong end of the stick.  
> 
> 
> Why is this an optimization in the first place? Do you make anything run
> faster? If so, what and how?
> 
>> Compile-time generation just feels safer to me.  The code-analyzer 
>> might miss special cases and what not, but if it is generated at 
>> compile time it will work all the time.
> 
> 
> Please again elaborate: What is compile-time, and what is generation,
> in this context?

I'll back away for a second to try to explain my previous rationale. 
Now that it appears to have changed that is.

By compile-time I meant essentially, not-run time.  For instance if you 
had a function

def foo(...):
     return i"Message"

You wouldn't have to execute foo directly for the parse tree to notice 
that i"Message" was a string that is supposed to be internationalized. 
This process gets this string placed in the internationalization table 
which I would then use various tools to modify and translate.

The international string class would then has an internal mechanism to 
notice what the locale is and what the value of the string should be 
when printed or used.  This is transparent to dictionaries and the like, 
so all the developer has to do is use

i"Message"

This should tranparent to Gui Widgets and the like so you can place 
i"Message" in a list box, it will automatically get internationalized 
but when you get the result of the user selected, it still can be used 
to dictionary look ups exactly the same as the original i"Message".

> The gettext module provides the GNUTranslation object. You can have
> multiple such objects, and need to explicitly use the language's
> object on gettext() invocation, e.g.
> 
>   print current_language.gettext("This is good")

This is the mechanism that I was originally using for the internation 
string class.

> If you can be certain that users will be subsequent, you can do
> 
> def _(msg):
>    return current_language.gettext(msg)
> 
> print _("This is good")

My version of this is
message = i"This is good"
print message

> There might be other ways to determine the current context, e.g.
> by looking at thread state. In that case, you still can use
> the _ function, but implement it in looking at the thread state.

I'll take a look at this.

An example of how I am currently using this is as follows:

message = i"This is good"
or
message = international("This is good")

lookup = {}
print message # -> "This is good"
lookup[message] = func

locale.set_locale("es") # spanish, this is from memory, might be wrong
print message # -> "Esto es bueno"
assert lookup[message] == func

local.set_locale("it") # italian
print message # -> "Ciò è buona"
assert lookup[message] == func

My current thinking is as follows, I could get most of this effect by 
not having a new string type (i"") and just making an 
internationalization string type.  Then I would just use code analyzer 
tools to generate the translation tables as Serge suggested, heck, they 
could even use the parse module if I was so inclined.

In either case, I far prefer using internation("This is good") over the 
_("This is good") function call.  Mainly because it is more explicit and 
using _ overrides the interpreters built in for getting last result.

 >>> 2+2
4
 >>> _
4

Thanks for your inspection of this rambling.
Brian




More information about the Python-list mailing list