[Checkins] SVN: zc.dict/trunk/src/zc/dict/ make ordered dict
subclass of dict. Meanwhile it gains other previously missing
methods.
Gary Poster
gary at zope.com
Wed Mar 5 07:48:41 EST 2008
Log message for revision 84479:
make ordered dict subclass of dict. Meanwhile it gains other previously missing methods.
Changed:
U zc.dict/trunk/src/zc/dict/__init__.py
U zc.dict/trunk/src/zc/dict/dict.py
D zc.dict/trunk/src/zc/dict/ordered.py
U zc.dict/trunk/src/zc/dict/ordered.txt
-=-
Modified: zc.dict/trunk/src/zc/dict/__init__.py
===================================================================
--- zc.dict/trunk/src/zc/dict/__init__.py 2008-03-05 09:33:15 UTC (rev 84478)
+++ zc.dict/trunk/src/zc/dict/__init__.py 2008-03-05 12:48:41 UTC (rev 84479)
@@ -1,2 +1 @@
-from zc.dict.dict import Dict # reexport
-from zc.dict.ordered import OrderedDict
+from zc.dict.dict import Dict, OrderedDict
Modified: zc.dict/trunk/src/zc/dict/dict.py
===================================================================
--- zc.dict/trunk/src/zc/dict/dict.py 2008-03-05 09:33:15 UTC (rev 84478)
+++ zc.dict/trunk/src/zc/dict/dict.py 2008-03-05 12:48:41 UTC (rev 84479)
@@ -15,23 +15,23 @@
$Id$
"""
-from BTrees.OOBTree import OOBTree
-from BTrees.Length import Length
-from persistent import Persistent
+import copy
+import BTrees
+import BTrees.Length
+import persistent
+import persistent.list
-class Dict(Persistent):
+
+class Dict(persistent.Persistent):
"""A BTree-based dict-like persistent object that can be safely
inherited from.
"""
- def __init__(self, dict=None, **kwargs):
- self._data = OOBTree()
- self._len = Length()
- if dict is not None:
- self.update(dict)
- if len(kwargs):
- self.update(kwargs)
+ def __init__(self, *args, **kwargs):
+ self._data = BTrees.OOBTree.OOBTree()
+ self._len = BTrees.Length.Length()
+ self.update(*args, **kwargs)
def __setitem__(self, key, value):
delta = 1
@@ -42,8 +42,7 @@
self._len.change(delta)
def __delitem__(self, key):
- del self._data[key]
- self._len.change(-1)
+ self.pop(key)
def update(self, *args, **kwargs):
if args:
@@ -67,8 +66,7 @@
res = self._data[key]
except KeyError:
res = failobj
- self._data[key] = res
- self._len.change(1)
+ self[key] = res
return res
def pop(self, key, *args):
@@ -101,15 +99,14 @@
def copy(self):
if self.__class__ is Dict:
- return Dict(OOBTree(self._data))
- import copy
+ return Dict(self._data)
data = self._data
try:
- self._data = OOBTree()
+ self._data = BTrees.OOBTree.OOBTree()
c = copy.copy(self)
finally:
self._data = data
- c.update(self)
+ c.update(self._data)
return c
def __getitem__(self, key): return self._data[key]
@@ -129,3 +126,99 @@
del self[k]
return (k, v)
+
+class OrderedDict(Dict):
+ """A Ordered BTree-based dict-like persistent object that can be safely
+ inherited from.
+
+ This class does not have as good behavior with large numbers of members
+ as the Dict class because the _order object is not in buckets.
+ """
+
+ # what do we get from the superclass:
+ # update, setdefault, __len__, popitem, __getitem__, has_key, __contains__,
+ # get, __delitem__
+
+ def __init__(self, *args, **kwargs):
+ self._order = persistent.list.PersistentList()
+ super(OrderedDict, self).__init__(*args, **kwargs)
+
+ def keys(self):
+ return self._order[:]
+
+ def __iter__(self):
+ return iter(self._order)
+
+ def values(self):
+ return [self._data[key] for key in self._order]
+
+ def items(self):
+ return [(key, self._data[key]) for key in self._order]
+
+ def __setitem__(self, key, value):
+ delta = 1
+ if key in self._data:
+ delta = 0
+ self._data[key] = value
+ if delta:
+ self._order.append(key)
+ self._len.change(delta)
+
+ def updateOrder(self, order):
+ order = persistent.list.PersistentList(order)
+
+ if len(order) != len(self._order):
+ raise ValueError("Incompatible key set.")
+
+ order_set = set(order)
+
+ if len(order) != len(order_set):
+ raise ValueError("Duplicate keys in order")
+
+ if order_set.difference(self._order):
+ raise ValueError("Incompatible key set.")
+
+ self._order = order
+
+ def clear(self):
+ super(OrderedDict, self).clear()
+ del self._order[:]
+
+ def copy(self):
+ if self.__class__ is OrderedDict:
+ return OrderedDict(self)
+ data = self._data
+ order = self._order
+ try:
+ self._data = OOBTree()
+ self._order = persistent.list.PersistentList()
+ c = copy.copy(self)
+ finally:
+ self._data = data
+ self._order = order
+ c.update(self)
+ return c
+
+ def iteritems(self):
+ return ((key, self._data[key]) for key in self._order)
+
+ def iterkeys(self):
+ return iter(self._order)
+
+ def itervalues(self):
+ return (self._data[key] for key in self._order)
+
+ def pop(self, key, *args):
+ try:
+ res = self._data.pop(key)
+ except KeyError:
+ if args:
+ res = args[0]
+ else:
+ raise
+ else:
+ self._len.change(-1)
+ self._order.remove(key)
+ return res
+
+
Deleted: zc.dict/trunk/src/zc/dict/ordered.py
===================================================================
--- zc.dict/trunk/src/zc/dict/ordered.py 2008-03-05 09:33:15 UTC (rev 84478)
+++ zc.dict/trunk/src/zc/dict/ordered.py 2008-03-05 12:48:41 UTC (rev 84479)
@@ -1,130 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2007 Zope Corporation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""zc.dict -- A BTree based persistent mapping
-
-$Id: $
-"""
-from BTrees.OOBTree import OOBTree
-from BTrees.Length import Length
-from persistent import Persistent
-from persistent.list import PersistentList
-from types import StringTypes, TupleType, ListType
-
-class OrderedDict(Persistent):
- """A Ordered BTree-based dict-like persistent object that can be safely
- inherited from.
- """
-
- def __init__(self, dict=None, **kwargs):
- self._order = PersistentList()
- self._data = OOBTree()
- self._len = Length()
- if dict is not None:
- self.update(dict)
- if len(kwargs):
- self.update(kwargs)
-
- def keys(self):
- return self._order[:]
-
- def __iter__(self):
- return iter(self.keys())
-
- def __getitem__(self, key):
- return self._data[key]
-
- def values(self):
- return [self._data[i] for i in self._order]
-
- def __len__(self):
- return self._len()
-
- def items(self):
- return [(i, self._data[i]) for i in self._order]
-
- def __contains__(self, key): return self._data.__contains__(key)
-
- def has_key(self, key): return bool(self._data.has_key(key))
-
- def __setitem__(self, key, value):
- delta = 1
- if key in self._data:
- delta = 0
- self._data[key] = value
- if delta:
- self._order.append(key)
- self._len.change(delta)
-
- def __delitem__(self, key):
- del self._data[key]
- self._order.remove(key)
- self._len.change(-1)
-
- def updateOrder(self, order):
- if not isinstance(order, ListType) and \
- not isinstance(order, TupleType):
- raise TypeError('order must be a tuple or a list.')
-
- if len(order) != len(self._order):
- raise ValueError("Incompatible key set.")
-
- was_dict = {}
- will_be_dict = {}
- new_order = PersistentList()
-
- for i in range(len(order)):
- was_dict[self._order[i]] = 1
- will_be_dict[order[i]] = 1
- new_order.append(order[i])
-
- if will_be_dict != was_dict:
- raise ValueError("Incompatible key set.")
-
- self._order = new_order
-
- def update(self, other):
- for k, v in other.iteritems():
- self[k] = v
-
- def clear(self):
- self._data.clear()
- self._order = PersistentList()
- self._len.set(0)
-
- def copy(self):
- import copy
- data = self._data
- order = self._order
- try:
- self._data = OOBTree()
- self._order = PersistentList()
- c = copy.copy(self)
- finally:
- self._data = data
- self._order = order
- c.update(self)
- return c
-
- def iteritems(self):
- return iter(self.items())
-
- def iterkeys(self):
- return iter(self.keys())
-
- def itervalues(self):
- return iter(self.values())
-
- def get(self, key, failobj=None):
- return self._data.get(key, failobj)
-
Modified: zc.dict/trunk/src/zc/dict/ordered.txt
===================================================================
--- zc.dict/trunk/src/zc/dict/ordered.txt 2008-03-05 09:33:15 UTC (rev 84478)
+++ zc.dict/trunk/src/zc/dict/ordered.txt 2008-03-05 12:48:41 UTC (rev 84479)
@@ -14,7 +14,7 @@
>>> from zc.dict import OrderedDict
>>> d = OrderedDict()
>>> d
- <zc.dict.ordered.OrderedDict object at ...>
+ <zc.dict.dict.OrderedDict object at ...>
Let us add a couple of items
@@ -66,10 +66,10 @@
<iterator object at ...>
>>> d.iteritems()
- <listiterator object at ...>
+ <generator object at ...>
>>> d.itervalues()
- <listiterator object at ...>
+ <generator object at ...>
OrderedDict also provides a copy method
@@ -89,7 +89,7 @@
[('two', 'Two'), ('one', 'One'), ('five', 'Five'), ('six', 'Six')]
-But if the argument is a regular Dict, then the order of the newly added
+But if the argument is a non-ordered dict, then the order of the newly added
elements in the resulting OrderedDict object cannot be guaranteed.
clear removes all the keys from the dict:
More information about the Checkins
mailing list