[Checkins] SVN: zc.dict/trunk/ merging changes to the trunk
Satchidanand Haridas
satchit at zope.com
Sun Dec 16 01:30:47 EST 2007
Log message for revision 82295:
merging changes to the trunk
Changed:
A zc.dict/trunk/CHANGES.txt
U zc.dict/trunk/README.txt
U zc.dict/trunk/setup.py
U zc.dict/trunk/src/zc/dict/__init__.py
A zc.dict/trunk/src/zc/dict/ordered.py
A zc.dict/trunk/src/zc/dict/ordered.txt
U zc.dict/trunk/src/zc/dict/tests.py
-=-
Copied: zc.dict/trunk/CHANGES.txt (from rev 82294, zc.dict/branches/satchit-ordered-dict/CHANGES.txt)
===================================================================
--- zc.dict/trunk/CHANGES.txt (rev 0)
+++ zc.dict/trunk/CHANGES.txt 2007-12-16 06:30:47 UTC (rev 82295)
@@ -0,0 +1,12 @@
+1.2 (unreleased)
+-----------------
+
+
+1.1 (2007-12-16)
+----------------
+
+* Added OrderedDict class that maintains the order in which items are added.
+
+
+1.1b
+----
Modified: zc.dict/trunk/README.txt
===================================================================
--- zc.dict/trunk/README.txt 2007-12-16 06:22:49 UTC (rev 82294)
+++ zc.dict/trunk/README.txt 2007-12-16 06:30:47 UTC (rev 82295)
@@ -1,5 +1,6 @@
-A BTree-based persistent dict-like object that can be used as a base class.
+BTree-based persistent dict-like objects (regular dict and ordered) that can be
+used as base classes.
-This is a bit of a heavyweight solution, as every zc.dict.Dict is at
-least 3 persistent objects. Keep this in mind if you intend to create
-lots and lots of these.
+This is a bit of a heavyweight solution, as every zc.dict.Dict (and
+zc.dict.OrderedDict) is at least 3 persistent objects. Keep this in mind if you
+intend to create lots and lots of these.
Modified: zc.dict/trunk/setup.py
===================================================================
--- zc.dict/trunk/setup.py 2007-12-16 06:22:49 UTC (rev 82294)
+++ zc.dict/trunk/setup.py 2007-12-16 06:30:47 UTC (rev 82295)
@@ -1,8 +1,11 @@
from setuptools import setup
+long_description = (open("src/zc/dict/dict.txt").read() +
+ '\n\n' +
+ open("src/zc/dict/ordered.txt").read())
setup(
name="zc.dict",
- version="1.0b1",
+ version="1.1b1",
license="ZPL 2.1",
author="Zope Corporation",
author_email="zope3-dev at zope.org",
@@ -14,7 +17,7 @@
install_requires=["setuptools", "zope.interface", "ZODB3"],
tests_require=["zope.testing"],
description=open('README.txt').read(),
- long_description=open("src/zc/dict/dict.txt").read(),
+ long_description=long_description,
keywords="zope zope3",
zip_safe=False
)
Modified: zc.dict/trunk/src/zc/dict/__init__.py
===================================================================
--- zc.dict/trunk/src/zc/dict/__init__.py 2007-12-16 06:22:49 UTC (rev 82294)
+++ zc.dict/trunk/src/zc/dict/__init__.py 2007-12-16 06:30:47 UTC (rev 82295)
@@ -1 +1,2 @@
from zc.dict.dict import Dict # reexport
+from zc.dict.ordered import OrderedDict
Copied: zc.dict/trunk/src/zc/dict/ordered.py (from rev 82294, zc.dict/branches/satchit-ordered-dict/src/zc/dict/ordered.py)
===================================================================
--- zc.dict/trunk/src/zc/dict/ordered.py (rev 0)
+++ zc.dict/trunk/src/zc/dict/ordered.py 2007-12-16 06:30:47 UTC (rev 82295)
@@ -0,0 +1,130 @@
+##############################################################################
+#
+# 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)
+
Copied: zc.dict/trunk/src/zc/dict/ordered.txt (from rev 82294, zc.dict/branches/satchit-ordered-dict/src/zc/dict/ordered.txt)
===================================================================
--- zc.dict/trunk/src/zc/dict/ordered.txt (rev 0)
+++ zc.dict/trunk/src/zc/dict/ordered.txt 2007-12-16 06:30:47 UTC (rev 82295)
@@ -0,0 +1,96 @@
+Ordered Dict: An persistent container that maintains order
+==========================================================
+
+An OrderedDict provides most of the functionality of a Dict, with the
+additional feature that it remembers the order in which items were added.
+It also provides the API to reorder the items.
+
+ >>> from zc.dict import OrderedDict
+ >>> d = OrderedDict()
+ >>> d
+ <zc.dict.ordered.OrderedDict object at ...>
+
+Let us add a couple of items
+
+ >>> d['one'] = 'One'
+ >>> len(d)
+ 1
+
+ >>> d['two'] = 'Two'
+ >>> len(d)
+ 2
+
+ >>> d.keys()
+ ['one', 'two']
+
+ >>> d.values()
+ ['One', 'Two']
+
+The order can be changed easily
+
+ >>> d.updateOrder(['two', 'one'])
+ >>> d.keys()
+ ['two', 'one']
+
+ >>> d.values()
+ ['Two', 'One']
+
+
+`updateOrder` expects the entire list of keys in the new order
+
+ >>> d.updateOrder(['two'])
+ Traceback (most recent call last):
+ ...
+ ValueError: Incompatible key set.
+
+
+Length is implemented in the same way as a Dict
+
+ >>> d._len
+ <BTrees.Length.Length object at ...>
+ >>> d._len()
+ 2
+
+
+OrderedDict also provides API that return iterators of the above methods.
+
+ >>> iter(d)
+ <iterator object at ...>
+ >>> d.iterkeys()
+ <iterator object at ...>
+
+ >>> d.iteritems()
+ <listiterator object at ...>
+
+ >>> d.itervalues()
+ <listiterator object at ...>
+
+
+OrderedDict also provides a copy method
+
+ >>> c = d.copy()
+ >>> c.items() == d.items()
+ True
+
+The `update` method is also provided. If it is provided with an OrderedDict,
+then the new elements are added in the same order as in the argument.
+
+ >>> d2 = OrderedDict()
+ >>> d2['five'] = 'Five'
+ >>> d2['six'] = 'Six'
+ >>> d.update(d2)
+ >>> d.items()
+ [('two', 'Two'), ('one', 'One'), ('five', 'Five'), ('six', 'Six')]
+
+
+But if the argument is a regular 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:
+
+ >>> d.clear()
+ >>> d.keys()
+ []
+ >>> len(d)
+ 0
+
Modified: zc.dict/trunk/src/zc/dict/tests.py
===================================================================
--- zc.dict/trunk/src/zc/dict/tests.py 2007-12-16 06:22:49 UTC (rev 82294)
+++ zc.dict/trunk/src/zc/dict/tests.py 2007-12-16 06:30:47 UTC (rev 82295)
@@ -20,7 +20,7 @@
def test_suite():
return unittest.TestSuite([
- doctest.DocFileSuite('dict.txt',
+ doctest.DocFileSuite('dict.txt', 'ordered.txt',
optionflags=doctest.INTERPRET_FOOTNOTES
|doctest.REPORT_NDIFF|doctest.ELLIPSIS),
])
More information about the Checkins
mailing list