[openstack-dev] [oslo] i18n Message improvements

John S Warren jswarren at us.ibm.com
Thu Oct 17 16:13:16 UTC 2013


Doug Hellmann <doug.hellmann at dreamhost.com> wrote on 10/17/2013 11:01:01 
AM:

> 
> We need, at some point in the lifecycle of a Message instance, to 
> tell the message what locale to use for its translation. At that 
> point, we have code that knows the message is not a string. If we 
> already require code like that, then we can change the API of 
> Message to be explicit about producing the translated string, and 
> Message does not need to pretend to be something it isn't.
> 
> Doug

It occurred to me yesterday after my last message that I have been
delving way too much into details and it would be better to summarize
my point of view this way, using py27 parlance for the sake of clarity:

1. When we changed _() to return something other than unicode objects,
   we introduced a number of problems because of the unique manner in
   which these objects are treated, for instance in string-formatting
   operations.
2. An obvious way to fix the problems we introduced is to have _()
   once again return unicode objects.  This can be done by having
   Message extend unicode.

The implementation I am suggesting would have _() produce Message
objects that are resolved (message ID -> message string) using the
system locale, just as the gettext implementation did. Because
Message extends unicode, it can be used anywhere unicode was used.
Also, because it has already been resolved to a message string it
can be used as-is when no translation is necessary. In the cases
where translations are needed, a "translate" method would produce
a unicode or Message object that reflects the translation operation.
For instance, if an exception is thrown and the client did not
specify a locale, the Message object is used as-is to render
the exception text.  Because we are now extending unicode instead
of UserString, we avoid the string-related problems associated
with the current implementation. If the client did specify a locale,
the logic recognizes the exception message as a Message object and
that Message object's "translate" method is called and its output is
used to render the exception text.

Instead of faking unicode behavior, I'm suggesting that we use its
functionality in Message as-is, only overriding the __mod__ method
in order to support translation in downstream code. In short, the
Message class would differ from unicode in only these ways:

1. A "translate" method is introduced.
2. Attributes necessary to perform the translation operation (e.g.
   message ID) are added.
3. The __mod__ method is overridden to preserve the parameters so
   they can be used in case a translation operation is needed.

So I guess where we differ is in that I don't see the need to have
Message objects that are distinct from unicode objects. It seems
to me that having _() return objects that can be used in the same
manner as the ones returned by the original gettext implementation
avoids a lot of complications.  Because Message is extending unicode,
and it is not overriding any of the relevant behaviors, for all intents
and purposes it's not pretending to be something it isn't when an
instance of it is being used as a unicode object would be used.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.openstack.org/pipermail/openstack-dev/attachments/20131017/dbf5da42/attachment.html>


More information about the OpenStack-dev mailing list