Mercurial > public > src > rhodecode
comparison pylons_app/lib/utils.py @ 384:23e720be5f44
Added implementation of Ordered Dict.
author | Marcin Kuzminski <marcin@python-works.com> |
---|---|
date | Sat, 24 Jul 2010 00:50:41 +0200 |
parents | d09381593b12 |
children | a26f48ad7a8a |
comparison
equal
deleted
inserted
replaced
383:ebdd1a89cdd9 | 384:23e720be5f44 |
---|---|
224 sa.delete(repo) | 224 sa.delete(repo) |
225 sa.commit() | 225 sa.commit() |
226 | 226 |
227 | 227 |
228 meta.Session.remove() | 228 meta.Session.remove() |
229 | |
230 from UserDict import DictMixin | |
231 | |
232 class OrderedDict(dict, DictMixin): | |
233 | |
234 def __init__(self, *args, **kwds): | |
235 if len(args) > 1: | |
236 raise TypeError('expected at most 1 arguments, got %d' % len(args)) | |
237 try: | |
238 self.__end | |
239 except AttributeError: | |
240 self.clear() | |
241 self.update(*args, **kwds) | |
242 | |
243 def clear(self): | |
244 self.__end = end = [] | |
245 end += [None, end, end] # sentinel node for doubly linked list | |
246 self.__map = {} # key --> [key, prev, next] | |
247 dict.clear(self) | |
248 | |
249 def __setitem__(self, key, value): | |
250 if key not in self: | |
251 end = self.__end | |
252 curr = end[1] | |
253 curr[2] = end[1] = self.__map[key] = [key, curr, end] | |
254 dict.__setitem__(self, key, value) | |
255 | |
256 def __delitem__(self, key): | |
257 dict.__delitem__(self, key) | |
258 key, prev, next = self.__map.pop(key) | |
259 prev[2] = next | |
260 next[1] = prev | |
261 | |
262 def __iter__(self): | |
263 end = self.__end | |
264 curr = end[2] | |
265 while curr is not end: | |
266 yield curr[0] | |
267 curr = curr[2] | |
268 | |
269 def __reversed__(self): | |
270 end = self.__end | |
271 curr = end[1] | |
272 while curr is not end: | |
273 yield curr[0] | |
274 curr = curr[1] | |
275 | |
276 def popitem(self, last=True): | |
277 if not self: | |
278 raise KeyError('dictionary is empty') | |
279 if last: | |
280 key = reversed(self).next() | |
281 else: | |
282 key = iter(self).next() | |
283 value = self.pop(key) | |
284 return key, value | |
285 | |
286 def __reduce__(self): | |
287 items = [[k, self[k]] for k in self] | |
288 tmp = self.__map, self.__end | |
289 del self.__map, self.__end | |
290 inst_dict = vars(self).copy() | |
291 self.__map, self.__end = tmp | |
292 if inst_dict: | |
293 return (self.__class__, (items,), inst_dict) | |
294 return self.__class__, (items,) | |
295 | |
296 def keys(self): | |
297 return list(self) | |
298 | |
299 setdefault = DictMixin.setdefault | |
300 update = DictMixin.update | |
301 pop = DictMixin.pop | |
302 values = DictMixin.values | |
303 items = DictMixin.items | |
304 iterkeys = DictMixin.iterkeys | |
305 itervalues = DictMixin.itervalues | |
306 iteritems = DictMixin.iteritems | |
307 | |
308 def __repr__(self): | |
309 if not self: | |
310 return '%s()' % (self.__class__.__name__,) | |
311 return '%s(%r)' % (self.__class__.__name__, self.items()) | |
312 | |
313 def copy(self): | |
314 return self.__class__(self) | |
315 | |
316 @classmethod | |
317 def fromkeys(cls, iterable, value=None): | |
318 d = cls() | |
319 for key in iterable: | |
320 d[key] = value | |
321 return d | |
322 | |
323 def __eq__(self, other): | |
324 if isinstance(other, OrderedDict): | |
325 return len(self) == len(other) and self.items() == other.items() | |
326 return dict.__eq__(self, other) | |
327 | |
328 def __ne__(self, other): | |
329 return not self == other |