Package horizons :: Package ext :: Module speaklater
[hide private]
[frames] | no frames]

Source Code for Module horizons.ext.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:
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 @property
116 - def value(self):
117 try: 118 return self._func(*self._args,**self._kwargs) 119 except AttributeError as e: 120 raise RuntimeError("Suppressed AttributeError: " + str(e))
121
122 - def __contains__(self, key):
123 return key in self.value
124
125 - def __bool__(self):
126 return bool(self.value)
127
128 - def __dir__(self):
129 return dir(str)
130
131 - def __iter__(self):
132 return iter(self.value)
133
134 - def __len__(self):
135 return len(self.value)
136
137 - def __str__(self):
138 return str(self.value)
139
140 - def __unicode__(self):
141 return str(self.value)
142
143 - def __add__(self, other):
144 return self.value + other
145
146 - def __radd__(self, other):
147 return other + self.value
148
149 - def __mod__(self, other):
150 return self.value % other
151
152 - def __rmod__(self, other):
153 return other % self.value
154
155 - def __mul__(self, other):
156 return self.value * other
157
158 - def __rmul__(self, other):
159 return other * self.value
160
161 - def __lt__(self, other):
162 return self.value < other
163
164 - def __le__(self, other):
165 return self.value <= other
166
167 - def __eq__(self, other):
168 return self.value == other
169
170 - def __ne__(self, other):
171 return self.value != other
172
173 - def __gt__(self, other):
174 return self.value > other
175
176 - def __ge__(self, other):
177 return self.value >= other
178
179 - def __hash__(self):
180 return hash(self.value)
181
182 - def __getattr__(self, name):
183 if name == '__members__': 184 return self.__dir__() 185 return getattr(self.value, name)
186
187 - def __getstate__(self):
188 return self._func, self._args, self._kwargs
189
190 - def __setstate__(self, tup):
191 self._func, self._args, self._kwargs = tup
192
193 - def __getitem__(self, key):
194 return self.value[key]
195
196 - def __copy__(self):
197 return self
198
199 - def __repr__(self):
200 try: 201 return 'l' + repr(self.value) 202 except Exception: 203 return '<%s broken>' % self.__class__.__name__
204 205 206 if __name__ == '__main__': 207 import doctest 208 doctest.testmod() 209