<tt><font size=2>Doug Hellmann <doug.hellmann@dreamhost.com> wrote
on 10/17/2013 11:01:01 AM:<br>
<br>
> <br>
> We need, at some point in the lifecycle of a Message instance, to
<br>
> tell the message what locale to use for its translation. At that <br>
> point, we have code that knows the message is not a string. If we
<br>
> already require code like that, then we can change the API of <br>
> Message to be explicit about producing the translated string, and
<br>
> Message does not need to pretend to be something it isn't.</font></tt>
<br><tt><font size=2>> <br>
> Doug</font></tt>
<br>
<br><tt><font size=2>It occurred to me yesterday after my last message
that I have been</font></tt>
<br><tt><font size=2>delving way too much into details and it would be
better to summarize</font></tt>
<br><tt><font size=2>my point of view this way, using py27 parlance for
the sake of clarity:</font></tt>
<br>
<br><tt><font size=2>1. When we changed _() to return something other than
unicode objects,</font></tt>
<br><tt><font size=2>   we introduced a number of problems because
of the unique manner in</font></tt>
<br><tt><font size=2>   which these objects are treated, for
instance in string-formatting</font></tt>
<br><tt><font size=2>   operations.</font></tt>
<br><tt><font size=2>2. An obvious way to fix the problems we introduced
is to have _()</font></tt>
<br><tt><font size=2>   once again return unicode objects.  This
can be done by having</font></tt>
<br><tt><font size=2>   Message extend unicode.</font></tt>
<br>
<br><tt><font size=2>The implementation I am suggesting would have _()
produce Message</font></tt>
<br><tt><font size=2>objects that are resolved (message ID -> message
string) using the</font></tt>
<br><tt><font size=2>system locale, just as the gettext implementation
did. Because</font></tt>
<br><tt><font size=2>Message extends unicode, it can be used anywhere unicode
was used.</font></tt>
<br><tt><font size=2>Also, because it has already been resolved to a message
string it</font></tt>
<br><tt><font size=2>can be used as-is when no translation is necessary.
In the cases</font></tt>
<br><tt><font size=2>where translations are needed, a "translate"
method would produce</font></tt>
<br><tt><font size=2>a unicode or Message object that reflects the translation
operation.</font></tt>
<br><tt><font size=2>For instance, if an exception is thrown and the client
did not</font></tt>
<br><tt><font size=2>specify a locale, the Message object is used as-is
to render</font></tt>
<br><tt><font size=2>the exception text.  Because we are now extending
unicode instead</font></tt>
<br><tt><font size=2>of UserString, we avoid the string-related problems
associated</font></tt>
<br><tt><font size=2>with the current implementation. If the client did
specify a locale,</font></tt>
<br><tt><font size=2>the logic recognizes the exception message as a Message
object and</font></tt>
<br><tt><font size=2>that Message object's "translate" method
is called and its output is</font></tt>
<br><tt><font size=2>used to render the exception text.</font></tt>
<br>
<br><tt><font size=2>Instead of faking unicode behavior, I'm suggesting
that we use its</font></tt>
<br><tt><font size=2>functionality in Message as-is, only overriding the
__mod__ method</font></tt>
<br><tt><font size=2>in order to support translation in downstream code.
In short, the</font></tt>
<br><tt><font size=2>Message class would differ from unicode in only these
ways:</font></tt>
<br>
<br><tt><font size=2>1. A "translate" method is introduced.</font></tt>
<br><tt><font size=2>2. Attributes necessary to perform the translation
operation (e.g.</font></tt>
<br><tt><font size=2>   message ID) are added.</font></tt>
<br><tt><font size=2>3. The __mod__ method is overridden to preserve the
parameters so</font></tt>
<br><tt><font size=2>   they can be used in case a translation
operation is needed.</font></tt>
<br>
<br><tt><font size=2>So I guess where we differ is in that I don't see
the need to have</font></tt>
<br><tt><font size=2>Message objects that are distinct from unicode objects.
It seems</font></tt>
<br><tt><font size=2>to me that having _() return objects that can be used
in the same</font></tt>
<br><tt><font size=2>manner as the ones returned by the original gettext
implementation</font></tt>
<br><tt><font size=2>avoids a lot of complications.  Because Message
is extending unicode,</font></tt>
<br><tt><font size=2>and it is not overriding any of the relevant behaviors,
for all intents</font></tt>
<br><tt><font size=2>and purposes it's not pretending to be something it
isn't when an</font></tt>
<br><tt><font size=2>instance of it is being used as a unicode object would
be used.</font></tt>