1
2 r"""
3 speaklater
4 ~~~~~~~~~~
5
6 A module that provides lazy strings for translations. Basically you
7 get an object that appears to be a string but changes the value every
8 time the value is evaluated based on a callable you provide.
9
10 For example you can have a global `lazy_gettext` function that returns
11 a lazy string with the value of the current set language.
12
13 Example:
14
15 >>> from speaklater import make_lazy_string
16 >>> sval = u'Hello World'
17 >>> string = make_lazy_string(lambda: sval)
18
19 This lazy string will evaluate to the value of the `sval` variable.
20
21 >>> string
22 lu'Hello World'
23 >>> unicode(string)
24 u'Hello World'
25 >>> string.upper()
26 u'HELLO WORLD'
27
28 If you change the value, the lazy string will change as well:
29
30 >>> sval = u'Hallo Welt'
31 >>> string.upper()
32 u'HALLO WELT'
33
34 This is especially handy when combined with a thread local and gettext
35 translations or dicts of translatable strings:
36
37 >>> from speaklater import make_lazy_gettext
38 >>> from threading import local
39 >>> l = local()
40 >>> l.translations = {u'Yes': 'Ja'}
41 >>> lazy_gettext = make_lazy_gettext(lambda: l.translations.get)
42 >>> yes = lazy_gettext(u'Yes')
43 >>> print yes
44 Ja
45 >>> l.translations[u'Yes'] = u'Si'
46 >>> print yes
47 Si
48
49 Lazy strings are no real strings so if you pass this sort of string to
50 a function that performs an instance check, it will fail. In that case
51 you have to explicitly convert it with `unicode` and/or `string` depending
52 on what string type the lazy string encapsulates.
53
54 To check if a string is lazy, you can use the `is_lazy_string` function:
55
56 >>> from speaklater import is_lazy_string
57 >>> is_lazy_string(u'yes')
58 False
59 >>> is_lazy_string(yes)
60 True
61
62 New in version 1.2: It's now also possible to pass keyword arguments to
63 the callback used with `make_lazy_string`.
64
65 :copyright: (c) 2010 by Armin Ronacher.
66 :license: BSD, see LICENSE for more details.
67 """
68
69
71 """Checks if the given object is a lazy string."""
72 return isinstance(obj, _LazyString)
73
74
76 """Creates a lazy string by invoking func with args."""
77 return _LazyString(__func, args, kwargs)
78
79
80 -def make_lazy_gettext(lookup_func):
81 """Creates a lazy gettext function dispatches to a gettext
82 function as returned by `lookup_func`.
83
84 Example:
85
86 >>> translations = {u'Yes': u'Ja'}
87 >>> lazy_gettext = make_lazy_gettext(lambda: translations.get)
88 >>> x = lazy_gettext(u'Yes')
89 >>> x
90 lu'Ja'
91 >>> translations[u'Yes'] = u'Si'
92 >>> x
93 lu'Si'
94 """
95 def lazy_gettext(string):
96 if is_lazy_string(string):
97 return string
98 return make_lazy_string(lookup_func(), string)
99 return lazy_gettext
100
101
103 """Class for strings created by a function call.
104
105 The proxy implementation attempts to be as complete as possible, so that
106 the lazy objects should mostly work as expected, for example for sorting.
107 """
108 __slots__ = ('_func', '_args', '_kwargs')
109
110 - def __init__(self, func, args, kwargs):
114
115 value = property(lambda x: x._func(*x._args, **x._kwargs))
116
118 return key in self.value
119
121 return bool(self.value)
122
125
127 return iter(self.value)
128
130 return len(self.value)
131
133 return str(self.value)
134
136 return unicode(self.value)
137
139 return self.value + other
140
142 return other + self.value
143
145 return self.value % other
146
148 return other % self.value
149
151 return self.value * other
152
154 return other * self.value
155
157 return self.value < other
158
160 return self.value <= other
161
163 return self.value == other
164
166 return self.value != other
167
169 return self.value > other
170
172 return self.value >= other
173
175 if name == '__members__':
176 return self.__dir__()
177 return getattr(self.value, name)
178
181
184
186 return self.value[key]
187
190
192 try:
193 return 'l' + repr(self.value)
194 except Exception:
195 return '<%s broken>' % self.__class__.__name__
196
197
198 if __name__ == '__main__':
199 import doctest
200 doctest.testmod()
201