Python/Django: how exactly works the ugettext_lazy function with operator %?
<p>I am using python 2.7 and had issue with lines like:
    <code>LOG.warning(_("text"))</code></p>

<p>This won't work as LOG.warning is expecting a string (str) and ugettext_lazy only knows how to render unicode.</p>

<p>Now the solution I found was to force unicode rendering before calling the logger:</p>

<pre><code>    text = 'Test trans'
    LOG.warning(u"%s" % _(text))
</code></pre>

<p>However, I was surprised to noticed that theses code also work:</p>

<pre><code>LOG.warning(_(Test trans %(test)s.') % {'test': 1})
LOG.warning(_('Test trans %s.') % 1)
</code></pre>

<p>Can somebody explain why ?
Does the "%" operator calls for unicode rendering before replacing the variable ?</p>

<p>Thanks in advance.</p>

<p>The <code>u</code> prefix in <a href="https://docs.djangoproject.com/en/1.10/ref/utils/#django.utils.translation.ugettext_lazy" rel="nofollow"><code>ugettext_lazy</code></a> means that the return value of this function is a Unicode string. The <code>_lazy</code> suffix means that the return value becomes lazy, that is, the return value only becomes a Unicode string at the absolutely last opportunity, when a string operation is done on it.</p>

<p>Try running this under <code>python2 manage.py shell</code> to see what I mean:</p>

<pre><code>&gt;&gt;&gt; from django.utils.translation import ugettext_lazy as _
&gt;&gt;&gt; _("hi")
&lt;django.utils.functional.__proxy__ object at 0x10fa23b10&gt;
&gt;&gt;&gt; _("hi") + ""
u'hi'
&gt;&gt;&gt; _("hi %s") % "hello"
u'hi hello'
</code></pre>

<p>I'm assuming that your assumption that <code>LOG.warning</code> only accepts non-Unicode strings and lazy strings is correct. In your case, maybe you have your logging configured to do nothing with warning log messages, and so the lazy strings that you are passing to <code>LOG.warning</code> are never evaluated and never converted to normal non-lazy Unicode strings.</p>

<p>Compare with <a href="https://docs.djangoproject.com/en/stable/ref/utils/#django.utils.translation.ugettext" rel="nofollow"><code>ugettext</code></a> and <a href="https://docs.djangoproject.com/en/stable/ref/utils/#django.utils.translation.gettext_lazy" rel="nofollow"><code>gettext_lazy</code></a>, and you'll see what I mean.</p>

<p>By the way, I highly recommend upgrading to Python 3, the way it deals with Unicode is much clearer and easy to follow in general than Python 2.</p>

python django python-2.7 unicode translation