[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