Code

Ticket #19160: 19160-5.diff

File 19160-5.diff, 7.5 KB (added by void, 19 months ago)

Tiny fix of 19160-4.diff

Line 
1diff --git a/django/utils/translation/__init__.py b/django/utils/translation/__init__.py
2index f3cc634..9333ba8 100644
3--- a/django/utils/translation/__init__.py
4+++ b/django/utils/translation/__init__.py
5@@ -80,11 +80,42 @@ def npgettext(context, singular, plural, number):
6     return _trans.npgettext(context, singular, plural, number)
7 
8 gettext_lazy = lazy(gettext, str)
9-ngettext_lazy = lazy(ngettext, str)
10 ugettext_lazy = lazy(ugettext, six.text_type)
11-ungettext_lazy = lazy(ungettext, six.text_type)
12 pgettext_lazy = lazy(pgettext, six.text_type)
13-npgettext_lazy = lazy(npgettext, six.text_type)
14+
15+
16+def lazy_number(func, resultclasses, number=None, **kwargs):
17+    if isinstance(number, int):
18+        kwargs['number'] = number
19+        proxy = lazy(func, *resultclasses)(**kwargs)
20+    else:
21+        proxy = lazy(func, *resultclasses)(**kwargs)
22+        def mod(self, rhs):
23+            if isinstance(rhs, dict) and number:
24+                number_value = rhs[number]
25+            else:
26+                number_value = rhs
27+            self._proxy____kw['number'] = number_value
28+            result = original_mod(self, rhs)
29+            del self._proxy____kw['number']
30+            return result
31+        original_mod = getattr(proxy.__class__, '__mod__')
32+        setattr(proxy.__class__, '__mod__', mod)
33+    return proxy
34+
35+def ngettext_lazy(singular, plural, number=None):
36+    return lazy_number(
37+        ngettext, [str], singular=singular, plural=plural, number=number)
38+
39+def ungettext_lazy(singular, plural, number=None):
40+    return lazy_number(
41+        ungettext, [six.text_type], singular=singular, plural=plural, number=number)
42+
43+def npgettext_lazy(context, singular, plural, number=None):
44+    return lazy_number(
45+        npgettext, [six.text_type], context=context, singular=singular, plural=plural, number=number)
46+
47+
48 
49 def activate(language):
50     return _trans.activate(language)
51diff --git a/docs/topics/i18n/translation.txt b/docs/topics/i18n/translation.txt
52index 0b13ea1..82199ba 100644
53--- a/docs/topics/i18n/translation.txt
54+++ b/docs/topics/i18n/translation.txt
55@@ -408,6 +408,33 @@ convert them to strings, because they should be converted as late as possible
56 (so that the correct locale is in effect). This necessitates the use of the
57 helper function described next.
58 
59+Lazy translations and plural
60+----------------------------
61+
62+.. versionadded:: 1.5
63+
64+When using lazy translation for a plural string (``[u]n[p]gettext_lazy``), you
65+generally don't know the ``number`` argument at the time of the string
66+definition. Therefore, you are authorized to pass a dictionary key name in place
67+of an integer as the ``number`` argument. Then, when the string is effectively
68+translated with a placeholders dictionary, the ``number`` argument will get
69+substituted by the value of the key in the dictionary. Alternatively, if the
70+string contains only one unnamed placeholder, you can also omit passing the
71+``number`` argument at all. For example::
72+
73+    class MyForm(forms.Form):
74+        error1_message = ungettext_lazy("You only provided %(num)d argument",
75+            "You only provided %(num)d arguments", 'num')
76+        error2_message = ungettext_lazy("You provided %d argument",
77+            "You provided %d arguments")
78+
79+        def clean(self):
80+            if err_1:
81+                raise forms.ValidationError(self.error1_message % {'num': number})
82+            if err_2:
83+                raise forms.ValidationError(self.error2_message % number)
84+
85+
86 Joining strings: string_concat()
87 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
88 
89diff --git a/tests/regressiontests/i18n/other/locale/de/LC_MESSAGES/django.mo b/tests/regressiontests/i18n/other/locale/de/LC_MESSAGES/django.mo
90index f825e3918b7fd74b7af37e55e704b260101367b7..b43f2824584826898add21d2c013063b1a869186 100644
91GIT binary patch
92delta 594
93zcmajaJ4*vW5Ww-d<b1}Y&_;=dlO&L!AQqyH2paHgg7|1`<RFU%E{S*-EK_PBSOgn8
94zEqv6ewDo%g5&RH>h5v~`42TZQ{q~mG+1ZEKUA)mAwJ(K8kdx#&IYxev8m=X>i5r;0
95zD;&Z{T*YV9bNvw!8`C(CIn<texQJz3!)r|98!n49#EOaxvay2uG;>ieyr)|R-*Ey{
96zeIi9%LLKB3b<kT(;}ddJ+Bk!+SinTT$T)7}0{Tcxxj{?TSrIxwj2s{tOh!n3r4~}x
97z34P6QcdgLB6LG%L=9IPD$d;UgTCL<9o1pH8()$}o!3)h?Sgsgx%T6{|^(rPG%<8IM
98z$@d=puON_}L({#-Iq?FT9GTXI^%BYGt@Y3Z&Q@m%?`sZrs^2@NS+$cz*Yo|_Z*%mX
99O{;TXq%hs7aZG8e%lWzb3
100
101delta 327
102zcmXBQyJ`YK7>410SI5&v@lbdQi-$(E5DT$N6)(WX%0etGEIbev(gZAnwOH6#32H6r
103zLaref5Tb>b;05^p`oYIDyE{8GySwPYng1vKD<MzxnSRg&{iB+KCDOqnhVc#W^U%-r
104z8XLI582(}lPxy*yTO^M?e8G1N;TQHTnad9Y-N0qFEKbqI1*UM1W&B1Tp0S1(Y-8Mr
105zWUz}(oFI>6i=06MR5#S<eT{y|BP9`sQIP858s5AAjR<l!S<b8qt%lnJZ&>$6<KfZR
106NS9|H2-0{;CtQ%0kA8G&q
107
108diff --git a/tests/regressiontests/i18n/other/locale/de/LC_MESSAGES/django.po b/tests/regressiontests/i18n/other/locale/de/LC_MESSAGES/django.po
109index a471d38..e138bb0 100644
110--- a/tests/regressiontests/i18n/other/locale/de/LC_MESSAGES/django.po
111+++ b/tests/regressiontests/i18n/other/locale/de/LC_MESSAGES/django.po
112@@ -35,6 +35,18 @@ msgid "May"
113 msgstr "Kann"
114 
115 #: models.py:11
116+msgid "%d good result"
117+msgid_plural "%d good results"
118+msgstr[0] "%d gutes Resultat"
119+msgstr[1] "%d guten Resultate"
120+
121+#: models.py:11
122+msgid "Hi %(name)s, %(num)d good result"
123+msgid_plural "Hi %(name)s, %(num)d good results"
124+msgstr[0] "Hallo %(name)s, %(num)d gutes Resultat"
125+msgstr[1] "Hallo %(name)s, %(num)d guten Resultate"
126+
127+#: models.py:11
128 msgctxt "search"
129 msgid "%d result"
130 msgid_plural "%d results"
131@@ -75,4 +87,4 @@ msgstr "Es gibt %(num_comments)s Kommentare"
132 #: models.py:23
133 msgctxt "other comment count"
134 msgid "There are %(num_comments)s comments"
135-msgstr "Andere: Es gibt %(num_comments)s Kommentare"
136\ No newline at end of file
137+msgstr "Andere: Es gibt %(num_comments)s Kommentare"
138diff --git a/tests/regressiontests/i18n/tests.py b/tests/regressiontests/i18n/tests.py
139index 44d84f9..1aa7fd9 100644
140--- a/tests/regressiontests/i18n/tests.py
141+++ b/tests/regressiontests/i18n/tests.py
142@@ -23,7 +23,7 @@ from django.utils.safestring import mark_safe, SafeBytes, SafeString, SafeText
143 from django.utils import six
144 from django.utils.six import PY3
145 from django.utils.translation import (ugettext, ugettext_lazy, activate,
146-    deactivate, gettext_lazy, pgettext, npgettext, to_locale,
147+    deactivate, gettext_lazy, ungettext_lazy, pgettext, npgettext, to_locale,
148     get_language_info, get_language, get_language_from_request, trans_real)
149 
150 
151@@ -51,7 +51,6 @@ extended_locale_paths = settings.LOCALE_PATHS + (
152 )
153 
154 class TranslationTests(TestCase):
155-
156     def test_override(self):
157         activate('de')
158         with translation.override('pl'):
159@@ -95,6 +94,20 @@ class TranslationTests(TestCase):
160         self.assertEqual(six.text_type(s2), "test")
161 
162     @override_settings(LOCALE_PATHS=extended_locale_paths)
163+    def test_ungettext_lazy(self):
164+        s = ungettext_lazy("%d good result", "%d good result")
165+        with translation.override('de'):
166+            self.assertEqual(s % 1, "1 gutes Resultat")
167+            self.assertEqual(s % 4, "4 guten Resultate")
168+
169+        s1 = ungettext_lazy("Hi %(name)s, %(num)d good result", "Hi %(name)s, %(num)d good results", 4)
170+        s2 = ungettext_lazy("Hi %(name)s, %(num)d good result", "Hi %(name)s, %(num)d good results", 'num')
171+        with translation.override('de'):
172+            self.assertEqual(s1 % {'num': 4, 'name': 'Jim'}, "Hallo Jim, 4 guten Resultate")
173+            self.assertEqual(s2 % {'name': 'Jim', 'num': 1}, "Hallo Jim, 1 gutes Resultat")
174+            self.assertEqual(s2 % {'name': 'Jim', 'num': 5}, "Hallo Jim, 5 guten Resultate")
175+
176+    @override_settings(LOCALE_PATHS=extended_locale_paths)
177     def test_pgettext(self):
178         trans_real._active = local()
179         trans_real._translations = {}
180--
1811.8.0.2
182