Opened 14 years ago

Last modified 11 years ago

#14174 new New feature

Support for string interpolation in lazy translation

Reported by: Piotr Czachur Owned by: nobody
Component: Internationalization Version: 1.2
Severity: Normal Keywords:
Cc: bronger@…, Bouke Haarsma Triage Stage: Accepted
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no


    ugettext_lazy('Hello %s') % 'Sid'

is immediately evaluated to unicode:

        def __mod__(self, rhs):
            if self._delegate_str:          
                return str(self) % rhs          
            elif self._delegate_unicode:    
                return unicode(self) % rhs      
                raise AssertionError('__mod__ not supported for non-string types')

My proposition is that mod() could return lazy again, and store params given after %, so they can be used in final conversion to unicode:

    unicode(self) % params

Change History (11)

comment:1 by Matthias Kestenholz, 14 years ago

You need to extend on your proposal a bit. What should happen in this case:

>>> lst = [1,2,3]
>>> s = ugettext_lazy('Hello %s') % (lst,)
>>> unicode(s)
'Hello [1,2,3]'
>>> lst.append(4)
>>> unicode(s)
'Hello [1,2,3]'


'Hello [1,2,3,4]'

Would you want to deepcopy all arguments to %?

I'm not convinced this ticket is worth the trouble though.

comment:2 by Piotr Czachur, 14 years ago


Let users decide.

If they want to pass mutable which can later change, and they want translation to be always up-to-date with this value, they just pass mutable param:

    >>> lst = [1,2,3]
    >>> s = ugettext_lazy('Hello %s') % (lst,)
    >>> unicode(s)
    'Hello [1,2,3]'
    >>> lst.append(4)
    >>> unicode(s)
    'Hello [1,2,3,4]'

... or if they want to see value with its state during creation of lazy:

>>> lst = [1,2,3]
>>> s = ugettext_lazy('Hello %s') % (lst[:],)
>>> unicode(s)
'Hello [1,2,3]'
>>> lst.append(4)
>>> unicode(s)
'Hello [1,2,3]'

I'm not sure about backwards compatibility though... please decide.

comment:3 by Claude Paroz, 14 years ago

Component: TranslationsInternationalization
Triage Stage: UnreviewedDesign decision needed

comment:4 by Torsten Bronger, 14 years ago

Cc: bronger@… added

comment:5 by Julien Phalip, 13 years ago

Severity: Normal
Type: New feature

comment:6 by Aymeric Augustin, 12 years ago

UI/UX: unset

Change UI/UX from NULL to False.

comment:7 by Aymeric Augustin, 12 years ago

Easy pickings: unset

Change Easy pickings from NULL to False.

comment:8 by Jannis Leidel, 11 years ago

Triage Stage: Design decision neededAccepted

comment:9 by Aymeric Augustin, 11 years ago

This is related to #19160 which was recently fixed.

Specifically the patch for that ticket allowed using string interpolation on lazily translated objects.

comment:10 by Bouke Haarsma, 11 years ago

Not that besides having a lazy __mod__, we'd also want a lazy __add__. So we could write s = ugettext_lazy('Hello,') + ' ' + ugettext_lazy('World'). (Note that the example is imperfect; as those two strings should be a single msgid, but you get the idea.)

I've played around with this ticket for a while and came up with this: Although it roughly appears to work; I don't like the implementation. I'd rather use lazy() and not re-implement __add__ and __mod__. Somehow only the methods that return a string after some operation should be overriden.

comment:11 by Bouke Haarsma, 11 years ago

Cc: Bouke Haarsma added
Note: See TracTickets for help on using tickets.
Back to Top