Module speaklater
[hide private]
[frames] | no frames]

Source Code for Module speaklater

  1  # -*- coding: utf-8 -*- 
  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   
70 -def is_lazy_string(obj):
71 """Checks if the given object is a lazy string.""" 72 return isinstance(obj, _LazyString)
73 74
75 -def make_lazy_string(__func, *args, **kwargs):
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
102 -class _LazyString(object):
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):
111 self._func = func 112 self._args = args 113 self._kwargs = kwargs
114 115 value = property(lambda x: x._func(*x._args, **x._kwargs)) 116
117 - def __contains__(self, key):
118 return key in self.value
119
120 - def __nonzero__(self):
121 return bool(self.value)
122
123 - def __dir__(self):
124 return dir(unicode)
125
126 - def __iter__(self):
127 return iter(self.value)
128
129 - def __len__(self):
130 return len(self.value)
131
132 - def __str__(self):
133 return str(self.value)
134
135 - def __unicode__(self):
136 return unicode(self.value)
137
138 - def __add__(self, other):
139 return self.value + other
140
141 - def __radd__(self, other):
142 return other + self.value
143
144 - def __mod__(self, other):
145 return self.value % other
146
147 - def __rmod__(self, other):
148 return other % self.value
149
150 - def __mul__(self, other):
151 return self.value * other
152
153 - def __rmul__(self, other):
154 return other * self.value
155
156 - def __lt__(self, other):
157 return self.value < other
158
159 - def __le__(self, other):
160 return self.value <= other
161
162 - def __eq__(self, other):
163 return self.value == other
164
165 - def __ne__(self, other):
166 return self.value != other
167
168 - def __gt__(self, other):
169 return self.value > other
170
171 - def __ge__(self, other):
172 return self.value >= other
173
174 - def __getattr__(self, name):
175 if name == '__members__': 176 return self.__dir__() 177 return getattr(self.value, name)
178
179 - def __getstate__(self):
180 return self._func, self._args, self._kwargs
181
182 - def __setstate__(self, tup):
183 self._func, self._args, self._kwargs = tup
184
185 - def __getitem__(self, key):
186 return self.value[key]
187
188 - def __copy__(self):
189 return self
190
191 - def __repr__(self):
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