Don't use ORderedDict backport on python 3

This commit is contained in:
Luke Campagnola 2017-10-11 09:05:32 -07:00
parent 30997d999d
commit d32454ebb8

View File

@ -20,108 +20,112 @@
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
# OTHER DEALINGS IN THE SOFTWARE. # OTHER DEALINGS IN THE SOFTWARE.
from UserDict import DictMixin import sys
if sys.version[0] > '2':
from collections import OrderedDict
else:
from UserDict import DictMixin
class OrderedDict(dict, DictMixin): class OrderedDict(dict, DictMixin):
def __init__(self, *args, **kwds): def __init__(self, *args, **kwds):
if len(args) > 1: if len(args) > 1:
raise TypeError('expected at most 1 arguments, got %d' % len(args)) raise TypeError('expected at most 1 arguments, got %d' % len(args))
try: try:
self.__end self.__end
except AttributeError: except AttributeError:
self.clear() self.clear()
self.update(*args, **kwds) self.update(*args, **kwds)
def clear(self): def clear(self):
self.__end = end = [] self.__end = end = []
end += [None, end, end] # sentinel node for doubly linked list end += [None, end, end] # sentinel node for doubly linked list
self.__map = {} # key --> [key, prev, next] self.__map = {} # key --> [key, prev, next]
dict.clear(self) dict.clear(self)
def __setitem__(self, key, value): def __setitem__(self, key, value):
if key not in self: if key not in self:
end = self.__end
curr = end[1]
curr[2] = end[1] = self.__map[key] = [key, curr, end]
dict.__setitem__(self, key, value)
def __delitem__(self, key):
dict.__delitem__(self, key)
key, prev, next = self.__map.pop(key)
prev[2] = next
next[1] = prev
def __iter__(self):
end = self.__end
curr = end[2]
while curr is not end:
yield curr[0]
curr = curr[2]
def __reversed__(self):
end = self.__end end = self.__end
curr = end[1] curr = end[1]
curr[2] = end[1] = self.__map[key] = [key, curr, end] while curr is not end:
dict.__setitem__(self, key, value) yield curr[0]
curr = curr[1]
def __delitem__(self, key): def popitem(self, last=True):
dict.__delitem__(self, key) if not self:
key, prev, next = self.__map.pop(key) raise KeyError('dictionary is empty')
prev[2] = next if last:
next[1] = prev key = reversed(self).next()
else:
key = iter(self).next()
value = self.pop(key)
return key, value
def __iter__(self): def __reduce__(self):
end = self.__end items = [[k, self[k]] for k in self]
curr = end[2] tmp = self.__map, self.__end
while curr is not end: del self.__map, self.__end
yield curr[0] inst_dict = vars(self).copy()
curr = curr[2] self.__map, self.__end = tmp
if inst_dict:
return (self.__class__, (items,), inst_dict)
return self.__class__, (items,)
def __reversed__(self): def keys(self):
end = self.__end return list(self)
curr = end[1]
while curr is not end:
yield curr[0]
curr = curr[1]
def popitem(self, last=True): setdefault = DictMixin.setdefault
if not self: update = DictMixin.update
raise KeyError('dictionary is empty') pop = DictMixin.pop
if last: values = DictMixin.values
key = reversed(self).next() items = DictMixin.items
else: iterkeys = DictMixin.iterkeys
key = iter(self).next() itervalues = DictMixin.itervalues
value = self.pop(key) iteritems = DictMixin.iteritems
return key, value
def __reduce__(self): def __repr__(self):
items = [[k, self[k]] for k in self] if not self:
tmp = self.__map, self.__end return '%s()' % (self.__class__.__name__,)
del self.__map, self.__end return '%s(%r)' % (self.__class__.__name__, self.items())
inst_dict = vars(self).copy()
self.__map, self.__end = tmp
if inst_dict:
return (self.__class__, (items,), inst_dict)
return self.__class__, (items,)
def keys(self): def copy(self):
return list(self) return self.__class__(self)
setdefault = DictMixin.setdefault @classmethod
update = DictMixin.update def fromkeys(cls, iterable, value=None):
pop = DictMixin.pop d = cls()
values = DictMixin.values for key in iterable:
items = DictMixin.items d[key] = value
iterkeys = DictMixin.iterkeys return d
itervalues = DictMixin.itervalues
iteritems = DictMixin.iteritems
def __repr__(self): def __eq__(self, other):
if not self: if isinstance(other, OrderedDict):
return '%s()' % (self.__class__.__name__,) if len(self) != len(other):
return '%s(%r)' % (self.__class__.__name__, self.items())
def copy(self):
return self.__class__(self)
@classmethod
def fromkeys(cls, iterable, value=None):
d = cls()
for key in iterable:
d[key] = value
return d
def __eq__(self, other):
if isinstance(other, OrderedDict):
if len(self) != len(other):
return False
for p, q in zip(self.items(), other.items()):
if p != q:
return False return False
return True for p, q in zip(self.items(), other.items()):
return dict.__eq__(self, other) if p != q:
return False
return True
return dict.__eq__(self, other)
def __ne__(self, other): def __ne__(self, other):
return not self == other return not self == other