Code

Ticket #13370: django-i18n-pickling.diff

File django-i18n-pickling.diff, 2.9 KB (added by Alex, 4 years ago)
Line 
1diff --git a/django/utils/functional.py b/django/utils/functional.py
2index b66fdd3..fecf9f0 100644
3--- a/django/utils/functional.py
4+++ b/django/utils/functional.py
5@@ -147,11 +147,6 @@ def lazy(func, *resultclasses):
6     the lazy evaluation code is triggered. Results are not memoized; the
7     function is evaluated on every access.
8     """
9-    # When lazy() is called by the __reduce_ex__ machinery to reconstitute the
10-    # __proxy__ class it can't call with *args, so the first item will just be
11-    # a tuple.
12-    if len(resultclasses) == 1 and isinstance(resultclasses[0], tuple):
13-        resultclasses = resultclasses[0]
14 
15     class __proxy__(Promise):
16         """
17@@ -168,8 +163,11 @@ def lazy(func, *resultclasses):
18             if self.__dispatch is None:
19                 self.__prepare_class__()
20 
21-        def __reduce_ex__(self, protocol):
22-            return (lazy, (self.__func, resultclasses), self.__dict__)
23+        def __reduce__(self):
24+            return (
25+                lazy_proxy_unpickle,
26+                (self.__func, self.__args, self.__kw) + resultclasses
27+            )
28 
29         def __prepare_class__(cls):
30             cls.__dispatch = {}
31@@ -249,6 +247,9 @@ def lazy(func, *resultclasses):
32 
33     return wraps(func)(__wrapper__)
34 
35+def lazy_proxy_unpickle(func, args, kwargs, *resultclasses):
36+    return lazy(func, *resultclasses)(*args, **kwargs)
37+
38 def allow_lazy(func, *resultclasses):
39     """
40     A decorator that allows a function to be called with one or more lazy
41diff --git a/tests/regressiontests/i18n/tests.py b/tests/regressiontests/i18n/tests.py
42index 17e53df..bb6d0a7 100644
43--- a/tests/regressiontests/i18n/tests.py
44+++ b/tests/regressiontests/i18n/tests.py
45@@ -1,15 +1,18 @@
46 # -*- encoding: utf-8 -*-
47+import datetime
48+import decimal
49 import os
50 import sys
51-import decimal
52-import datetime
53+import pickle
54 
55 from django.template import Template, Context
56 from django.conf import settings
57-from django.utils.formats import get_format, date_format, time_format, localize, localize_input
58+from django.utils.formats import (get_format, date_format, time_format, localize,
59+    localize_input)
60 from django.utils.numberformat import format as nformat
61 from django.test import TestCase
62-from django.utils.translation import ugettext, ugettext_lazy, activate, deactivate, gettext_lazy, to_locale
63+from django.utils.translation import (ugettext, ugettext_lazy, activate,
64+    deactivate, gettext_lazy, to_locale)
65 
66 from forms import I18nForm, SelectDateForm, SelectDateWidget, CompanyForm
67 
68@@ -40,6 +43,12 @@ class TranslationTests(TestCase):
69         self.assertEqual(True, s == s2)
70         s4 = ugettext_lazy('Some other string')
71         self.assertEqual(False, s == s4)
72+   
73+    def test_lazy_pickle(self):
74+        s1 = ugettext_lazy("test")
75+        self.assertEqual(unicode(s1), "test")
76+        s2 = pickle.loads(pickle.dumps(s1))
77+        self.assertEqual(unicode(s2), "test")
78 
79     def test_string_concat(self):
80         """