[4025019] | 1 | #!/usr/bin/env python |
---|
| 2 | """Backport from python2.7 to python <= 2.6.""" |
---|
| 3 | |
---|
| 4 | from itertools import repeat as _repeat, chain as _chain, starmap as _starmap |
---|
| 5 | |
---|
| 6 | try: |
---|
| 7 | from itertools import izip_longest as _zip_longest |
---|
| 8 | except ImportError: |
---|
| 9 | |
---|
| 10 | from itertools import izip |
---|
| 11 | |
---|
| 12 | def _zip_longest(*args, **kwds): |
---|
| 13 | # izip_longest('ABCD', 'xy', fillvalue='-') --> Ax By C- D- |
---|
| 14 | fillvalue = kwds.get('fillvalue') |
---|
| 15 | def sentinel(counter = ([fillvalue]*(len(args)-1)).pop): |
---|
| 16 | yield counter() # yields the fillvalue, or raises IndexError |
---|
| 17 | fillers = _repeat(fillvalue) |
---|
| 18 | iters = [_chain(it, sentinel(), fillers) for it in args] |
---|
| 19 | try: |
---|
| 20 | for tup in izip(*iters): |
---|
| 21 | yield tup |
---|
| 22 | except IndexError: |
---|
| 23 | pass |
---|
| 24 | |
---|
| 25 | class OrderedDict(dict): |
---|
| 26 | |
---|
| 27 | def __init__(self, *args, **kwds): |
---|
| 28 | if len(args) > 1: |
---|
| 29 | raise TypeError('expected at most 1 arguments, got %d' % len(args)) |
---|
| 30 | if not hasattr(self, '_keys'): |
---|
| 31 | self._keys = [] |
---|
| 32 | self.update(*args, **kwds) |
---|
| 33 | |
---|
| 34 | def clear(self): |
---|
| 35 | del self._keys[:] |
---|
| 36 | dict.clear(self) |
---|
| 37 | |
---|
| 38 | def __setitem__(self, key, value): |
---|
| 39 | if key not in self: |
---|
| 40 | self._keys.append(key) |
---|
| 41 | dict.__setitem__(self, key, value) |
---|
| 42 | |
---|
| 43 | def __delitem__(self, key): |
---|
| 44 | dict.__delitem__(self, key) |
---|
| 45 | self._keys.remove(key) |
---|
| 46 | |
---|
| 47 | def __iter__(self): |
---|
| 48 | return iter(self._keys) |
---|
| 49 | |
---|
| 50 | def __reversed__(self): |
---|
| 51 | return reversed(self._keys) |
---|
| 52 | |
---|
| 53 | def popitem(self): |
---|
| 54 | if not self: |
---|
| 55 | raise KeyError('dictionary is empty') |
---|
| 56 | key = self._keys.pop() |
---|
| 57 | value = dict.pop(self, key) |
---|
| 58 | return key, value |
---|
| 59 | |
---|
| 60 | def __reduce__(self): |
---|
| 61 | items = [[k, self[k]] for k in self] |
---|
| 62 | inst_dict = vars(self).copy() |
---|
| 63 | inst_dict.pop('_keys', None) |
---|
| 64 | return (self.__class__, (items,), inst_dict) |
---|
| 65 | |
---|
| 66 | def setdefault(self, key, default=None): |
---|
| 67 | try: |
---|
| 68 | return self[key] |
---|
| 69 | except KeyError: |
---|
| 70 | self[key] = default |
---|
| 71 | return default |
---|
| 72 | |
---|
| 73 | def update(self, other=(), **kwds): |
---|
| 74 | if hasattr(other, "keys"): |
---|
| 75 | for key in other.keys(): |
---|
| 76 | self[key] = other[key] |
---|
| 77 | else: |
---|
| 78 | for key, value in other: |
---|
| 79 | self[key] = value |
---|
| 80 | for key, value in kwds.items(): |
---|
| 81 | self[key] = value |
---|
| 82 | |
---|
| 83 | __marker = object() |
---|
| 84 | |
---|
| 85 | def pop(self, key, default=__marker): |
---|
| 86 | try: |
---|
| 87 | value = self[key] |
---|
| 88 | except KeyError: |
---|
| 89 | if default is self.__marker: |
---|
| 90 | raise |
---|
| 91 | return default |
---|
| 92 | else: |
---|
| 93 | del self[key] |
---|
| 94 | return value |
---|
| 95 | |
---|
| 96 | def keys(self): |
---|
| 97 | return list(self) |
---|
| 98 | |
---|
| 99 | def values(self): |
---|
| 100 | return [self[key] for key in self] |
---|
| 101 | |
---|
| 102 | def items(self): |
---|
| 103 | return [(key, self[key]) for key in self] |
---|
| 104 | |
---|
| 105 | def __repr__(self): |
---|
| 106 | if not self: |
---|
| 107 | return '%s()' % (self.__class__.__name__,) |
---|
| 108 | return '%s(%r)' % (self.__class__.__name__, list(self.items())) |
---|
| 109 | |
---|
| 110 | def copy(self): |
---|
| 111 | return self.__class__(self) |
---|
| 112 | |
---|
| 113 | @classmethod |
---|
| 114 | def fromkeys(cls, iterable, value=None): |
---|
| 115 | d = cls() |
---|
| 116 | for key in iterable: |
---|
| 117 | d[key] = value |
---|
| 118 | return d |
---|
| 119 | |
---|
| 120 | def __eq__(self, other): |
---|
| 121 | if isinstance(other, OrderedDict): |
---|
| 122 | return all(p==q for p, q in _zip_longest(self.items(), other.items())) |
---|
| 123 | return dict.__eq__(self, other) |
---|
| 124 | |
---|
| 125 | |
---|
| 126 | |
---|
| 127 | # End class OrderedDict |
---|
| 128 | |
---|