Ticket #19160: 19160.resolvable-ungettext.diff

File 19160.resolvable-ungettext.diff, 6.7 KB (added by void, 3 years ago)

Another implementation

  • django/utils/functional.py

    diff --git a/django/utils/functional.py b/django/utils/functional.py
    index 085a8fc..4fff693 100644
    a b class Promise(object): 
    5151    """
    5252    pass
    5353
    54 def lazy(func, *resultclasses):
     54def lazy(func, *resultclasses, **kwargs):
    5555    """
    5656    Turns any callable into a lazy evaluated callable. You need to give result
    5757    classes or types -- at least one is needed so that the automatic forcing of
    def lazy(func, *resultclasses): 
    5959    function is evaluated on every access.
    6060    """
    6161
     62    mixin = kwargs.get('mixin', object)
    6263    @total_ordering
    63     class __proxy__(Promise):
     64    class __proxy__(Promise, mixin):
    6465        """
    6566        Encapsulate a function call and act as a proxy for methods that are
    6667        called on the result of that function. The function is not evaluated
    def lazy(func, *resultclasses): 
    8081                (func, self.__args, self.__kw) + resultclasses
    8182            )
    8283
     84        @classmethod
    8385        def __prepare_class__(cls):
    8486            cls.__dispatch = {}
    8587            for resultclass in resultclasses:
    def lazy(func, *resultclasses): 
    106108                    cls.__bytes__ = cls.__bytes_cast
    107109                else:
    108110                    cls.__str__ = cls.__bytes_cast
    109         __prepare_class__ = classmethod(__prepare_class__)
    110111
     112        @classmethod
    111113        def __promise__(cls, klass, funcname, method):
    112114            # Builds a wrapper around some magic method and registers that magic
    113115            # method for the given type and method name.
    def lazy(func, *resultclasses): 
    124126                cls.__dispatch[klass] = {}
    125127            cls.__dispatch[klass][funcname] = method
    126128            return __wrapper__
    127         __promise__ = classmethod(__promise__)
    128129
    129130        def __text_cast(self):
    130131            return func(*self.__args, **self.__kw)
  • django/utils/translation/__init__.py

    diff --git a/django/utils/translation/__init__.py b/django/utils/translation/__init__.py
    index f3cc634..8e87e93 100644
    a b def npgettext(context, singular, plural, number): 
    8080    return _trans.npgettext(context, singular, plural, number)
    8181
    8282gettext_lazy = lazy(gettext, str)
    83 ngettext_lazy = lazy(ngettext, str)
    8483ugettext_lazy = lazy(ugettext, six.text_type)
    85 ungettext_lazy = lazy(ungettext, six.text_type)
    8684pgettext_lazy = lazy(pgettext, six.text_type)
    87 npgettext_lazy = lazy(npgettext, six.text_type)
     85
     86
     87def lazy_number(func, resultclasses, number=None, **kwargs):
     88    class LazyNumberMixin(object):
     89        def __mod__(self, rhs):
     90            assert self._proxy____kw['number'], 'This object is not resolved yet'
     91            return super(LazyNumberMixin, self).__mod__(rhs)
     92
     93        def resolve(self, number):
     94            self._proxy____kw['number'] = number
     95            return self
     96
     97    if number is not None:
     98        kwargs['number'] = number
     99        proxy = lazy(func, *resultclasses)(**kwargs)
     100    else:
     101        proxy = lazy(func, *resultclasses, mixin=LazyNumberMixin)(**kwargs)
     102    return proxy
     103
     104def ngettext_lazy(singular, plural, number=None):
     105    return lazy_number(
     106        ngettext, [str], singular=singular, plural=plural, number=number)
     107
     108def ungettext_lazy(singular, plural, number=None):
     109    return lazy_number(
     110        ungettext, [six.text_type], singular=singular, plural=plural, number=number)
     111
     112def npgettext_lazy(context, singular, plural, number=None):
     113    return lazy_number(
     114        npgettext, [six.text_type], context=context, singular=singular, plural=plural, number=number)
     115
     116
    88117
    89118def activate(language):
    90119    return _trans.activate(language)
  • tests/regressiontests/i18n/other/locale/de/LC_MESSAGES/django.po

    diff --git a/tests/regressiontests/i18n/other/locale/de/LC_MESSAGES/django.po b/tests/regressiontests/i18n/other/locale/de/LC_MESSAGES/django.po
    index a471d38..63b5339 100644
    a b msgid "May" 
    3535msgstr "Kann"
    3636
    3737#: models.py:11
     38msgid "%d good result"
     39msgid_plural "%d good results"
     40msgstr[0] "%d gutes Resultat"
     41msgstr[1] "%d guten Resultate"
     42
     43#: models.py:11
     44msgid "%(num)d good result"
     45msgid_plural "%(num)d good results"
     46msgstr[0] "%(num)d gutes Resultat"
     47msgstr[1] "%(num)d guten Resultate"
     48
     49#: models.py:11
    3850msgctxt "search"
    3951msgid "%d result"
    4052msgid_plural "%d results"
    msgstr "Es gibt %(num_comments)s Kommentare" 
    7587#: models.py:23
    7688msgctxt "other comment count"
    7789msgid "There are %(num_comments)s comments"
    78 msgstr "Andere: Es gibt %(num_comments)s Kommentare"
    79  No newline at end of file
     90msgstr "Andere: Es gibt %(num_comments)s Kommentare"
  • tests/regressiontests/i18n/tests.py

    diff --git a/tests/regressiontests/i18n/tests.py b/tests/regressiontests/i18n/tests.py
    index 4054f85..7e149a6 100644
    a b from django.utils.safestring import mark_safe, SafeBytes, SafeString, SafeText 
    2222from django.utils import six
    2323from django.utils.six import PY3
    2424from django.utils.translation import (ugettext, ugettext_lazy, activate,
    25     deactivate, gettext_lazy, pgettext, npgettext, to_locale,
     25    deactivate, gettext_lazy, ungettext_lazy, pgettext, npgettext, to_locale,
    2626    get_language_info, get_language, get_language_from_request, trans_real)
    2727
    2828
    extended_locale_paths = settings.LOCALE_PATHS + ( 
    5050)
    5151
    5252class TranslationTests(TestCase):
    53 
    5453    def test_override(self):
    5554        activate('de')
    5655        with translation.override('pl'):
    class TranslationTests(TestCase): 
    9089        self.assertEqual(six.text_type(s2), "test")
    9190
    9291    @override_settings(LOCALE_PATHS=extended_locale_paths)
     92    def test_ungettext_lazy(self):
     93        s = ungettext_lazy("%d good result", "%d good result")
     94        with translation.override('de'):
     95            self.assertEqual(s.resolve(1) % 1, "1 gutes Resultat")
     96            self.assertEqual(s.resolve(4) % 4, "4 guten Resultate")
     97
     98        s1 = ungettext_lazy("%(num)d good result", "%(num)d good results", 4)
     99        s2 = ungettext_lazy("%(num)d good result", "%(num)d good results")
     100        s3 = ungettext_lazy("%(num)d good result", "%(num)d good results")
     101        with translation.override('de'):
     102            self.assertEqual(s1 % {'num': 4}, "4 guten Resultate")
     103            self.assertEqual(s2.resolve(1) % {'num': 1}, "1 gutes Resultat")
     104            self.assertEqual(s2.resolve(4) % {'num': 4}, "4 guten Resultate")
     105            self.assertEqual(s3.resolve(5) % {'num': 5}, "5 guten Resultate")
     106
     107    @override_settings(LOCALE_PATHS=extended_locale_paths)
    93108    def test_pgettext(self):
    94109        trans_real._active = local()
    95110        trans_real._translations = {}
Back to Top