Some changes to SortedDict to make it faster under py2

Refs #19276
This commit is contained in:
Anssi Kääriäinen 2012-11-11 00:35:46 +02:00
parent 5e9af1600d
commit 538d6c0fcd
1 changed files with 14 additions and 19 deletions

View File

@ -1,6 +1,5 @@
import copy import copy
import warnings import warnings
from types import GeneratorType
from django.utils import six from django.utils import six
@ -120,27 +119,23 @@ class SortedDict(dict):
return instance return instance
def __init__(self, data=None): def __init__(self, data=None):
if data is None: if data is None or isinstance(data, dict):
data = {} data = data or []
elif isinstance(data, GeneratorType): super(SortedDict, self).__init__(data)
# Unfortunately we need to be able to read a generator twice. Once self.keyOrder = list(data) if data else []
# to get the data into self with our super().__init__ call and a
# second time to setup keyOrder correctly
data = list(data)
super(SortedDict, self).__init__(data)
if isinstance(data, dict):
self.keyOrder = list(data)
else: else:
self.keyOrder = [] super(SortedDict, self).__init__()
seen = set() super_set = super(SortedDict, self).__setitem__
for key, value in data: for key, value in data:
if key not in seen: # Take the ordering from first key
if key not in self:
self.keyOrder.append(key) self.keyOrder.append(key)
seen.add(key) # But override with last value in data (dict() does this)
super_set(key, value)
def __deepcopy__(self, memo): def __deepcopy__(self, memo):
return self.__class__([(key, copy.deepcopy(value, memo)) return self.__class__([(key, copy.deepcopy(value, memo))
for key, value in six.iteritems(self)]) for key, value in self.items()])
def __copy__(self): def __copy__(self):
# The Python's default copy implementation will alter the state # The Python's default copy implementation will alter the state
@ -199,13 +194,13 @@ class SortedDict(dict):
itervalues = _itervalues itervalues = _itervalues
def items(self): def items(self):
return list(self.iteritems()) return [(k, self[k]) for k in self.keyOrder]
def keys(self): def keys(self):
return list(self.iterkeys()) return self.keyOrder[:]
def values(self): def values(self):
return list(self.itervalues()) return [self[k] for k in self.keyOrder]
def update(self, dict_): def update(self, dict_):
for k, v in six.iteritems(dict_): for k, v in six.iteritems(dict_):