[Zope3-checkins] CVS: Zope3/src/zope/app/container - ordered.py:1.2
Chris McDonough
chrism@zope.com
Mon, 23 Jun 2003 18:46:45 -0400
Update of /cvs-repository/Zope3/src/zope/app/container
In directory cvs.zope.org:/tmp/cvs-serv30079/src/zope/app/container
Added Files:
ordered.py
Log Message:
Merge pluggable_authentication_service-branch to HEAD.
You can now use a pluggable authentication service in place of a simple authentication service.
=== Zope3/src/zope/app/container/ordered.py 1.1 => 1.2 ===
--- /dev/null Mon Jun 23 18:46:45 2003
+++ Zope3/src/zope/app/container/ordered.py Mon Jun 23 18:46:14 2003
@@ -0,0 +1,276 @@
+##############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (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.
+#
+##############################################################################
+"""Ordered container implementation.
+
+Revision information:
+$Id$
+"""
+
+from zope.app.interfaces.container import IOrderedContainer
+from zope.interface import implements
+from persistence import Persistent
+from persistence.dict import PersistentDict
+from persistence.list import PersistentList
+from types import StringTypes
+
+class OrderedContainer(Persistent):
+ """ OrderedContainer maintains entries' order as added and moved.
+
+ >>> oc = OrderedContainer()
+ >>> IOrderedContainer.isImplementedBy(oc)
+ True
+ >>> len(oc)
+ 0
+ """
+
+ implements(IOrderedContainer)
+
+ def __init__(self):
+
+ self._data = PersistentDict()
+ self._order = PersistentList()
+
+ def keys(self):
+ """ See IOrderedContainer.
+
+ >>> oc = OrderedContainer()
+ >>> oc.keys()
+ []
+ >>> key = oc.setObject('foo', 'bar')
+ >>> oc.keys()
+ ['foo']
+ >>> key = oc.setObject('baz', 'quux')
+ >>> oc.keys()
+ ['foo', 'baz']
+ >>> int(len(oc._order) == len(oc._data))
+ 1
+ """
+
+ return self._order[:]
+
+ def __iter__(self):
+ """ See IOrderedContainer.
+
+ >>> oc = OrderedContainer()
+ >>> oc.keys()
+ []
+ >>> key = oc.setObject('foo', 'bar')
+ >>> key = oc.setObject('baz', 'quux')
+ >>> [i for i in oc]
+ ['foo', 'baz']
+ >>> int(len(oc._order) == len(oc._data))
+ 1
+ """
+
+ return iter(self.keys())
+
+ def __getitem__(self, key):
+ """ See IOrderedContainer
+
+ >>> oc = OrderedContainer()
+ >>> key = oc.setObject('foo', 'bar')
+ >>> oc['foo']
+ 'bar'
+ """
+
+ return self._data[key]
+
+ def get(self, key, default=None):
+ """ See IOrderedContainer
+
+ >>> oc = OrderedContainer()
+ >>> key = oc.setObject('foo', 'bar')
+ >>> oc.get('foo')
+ 'bar'
+ >>> oc.get('funky', 'No chance, dude.')
+ 'No chance, dude.'
+ """
+
+ return self._data.get(key, default)
+
+ def values(self):
+ """ See IOrderedContainer.
+
+ >>> oc = OrderedContainer()
+ >>> oc.keys()
+ []
+ >>> key = oc.setObject('foo', 'bar')
+ >>> oc.values()
+ ['bar']
+ >>> key = oc.setObject('baz', 'quux')
+ >>> oc.values()
+ ['bar', 'quux']
+ >>> int(len(oc._order) == len(oc._data))
+ 1
+ """
+
+ return [self._data[i] for i in self._order]
+
+ def __len__(self):
+ """ See IOrderedContainer
+
+ >>> oc = OrderedContainer()
+ >>> int(len(oc) == 0)
+ 1
+ >>> key = oc.setObject('foo', 'bar')
+ >>> int(len(oc) == 1)
+ 1
+ """
+
+ return len(self._data)
+
+ def items(self):
+ """ See IOrderedContainer.
+
+ >>> oc = OrderedContainer()
+ >>> oc.keys()
+ []
+ >>> key = oc.setObject('foo', 'bar')
+ >>> oc.items()
+ [('foo', 'bar')]
+ >>> key = oc.setObject('baz', 'quux')
+ >>> oc.items()
+ [('foo', 'bar'), ('baz', 'quux')]
+ >>> int(len(oc._order) == len(oc._data))
+ 1
+ """
+
+ return [(i, self._data[i]) for i in self._order]
+
+ def __contains__(self, key):
+ """ See IOrderedContainer.
+
+ >>> oc = OrderedContainer()
+ >>> key = oc.setObject('foo', 'bar')
+ >>> int('foo' in oc)
+ 1
+ >>> int('quux' in oc)
+ 0
+ """
+
+ return self._data.has_key(key)
+
+ has_key = __contains__
+
+ def setObject(self, key, object):
+ """ See IOrderedContainer.
+
+ >>> oc = OrderedContainer()
+ >>> oc.keys()
+ []
+ >>> key = oc.setObject('foo', 'bar')
+ >>> oc._order
+ ['foo']
+ >>> key = oc.setObject('baz', 'quux')
+ >>> oc._order
+ ['foo', 'baz']
+ >>> int(len(oc._order) == len(oc._data))
+ 1
+ """
+
+ existed = self._data.has_key(key)
+
+ bad = False
+ if isinstance(key, StringTypes):
+ try:
+ unicode(key)
+ except UnicodeError:
+ bad = True
+ else:
+ bad = True
+ if bad:
+ raise TypeError("'%s' is invalid, the key must be an "
+ "ascii or unicode string" % key)
+ if len(key) == 0:
+ raise ValueError("The key cannot be an empty string")
+ self._data[key] = object
+
+ if not existed:
+ self._order.append(key)
+
+ return key
+
+ def __delitem__(self, key):
+ """ See IOrderedContainer.
+
+ >>> oc = OrderedContainer()
+ >>> oc.keys()
+ []
+ >>> key = oc.setObject('foo', 'bar')
+ >>> key = oc.setObject('baz', 'quux')
+ >>> key = oc.setObject('zork', 'grue')
+ >>> oc.items()
+ [('foo', 'bar'), ('baz', 'quux'), ('zork', 'grue')]
+ >>> int(len(oc._order) == len(oc._data))
+ 1
+ >>> del oc['baz']
+ >>> oc.items()
+ [('foo', 'bar'), ('zork', 'grue')]
+ >>> int(len(oc._order) == len(oc._data))
+ 1
+ """
+
+ del self._data[key]
+ self._order.remove(key)
+
+ def updateOrder(self, order):
+ """ See IOrderedContainer
+
+ >>> oc = OrderedContainer()
+ >>> key = oc.setObject('foo', 'bar')
+ >>> key = oc.setObject('baz', 'quux')
+ >>> key = oc.setObject('zork', 'grue')
+ >>> oc.keys()
+ ['foo', 'baz', 'zork']
+ >>> oc.updateOrder(['baz', 'foo', 'zork'])
+ >>> oc.keys()
+ ['baz', 'foo', 'zork']
+ >>> oc.updateOrder(['baz', 'zork', 'foo'])
+ >>> oc.keys()
+ ['baz', 'zork', 'foo']
+ >>> oc.updateOrder(['baz', 'zork', 'foo'])
+ >>> oc.keys()
+ ['baz', 'zork', 'foo']
+ >>> oc.updateOrder(['baz', 'zork'])
+ Traceback (most recent call last):
+ ...
+ ValueError: Incompatible key set.
+ >>> oc.updateOrder(['foo', 'bar', 'baz', 'quux'])
+ Traceback (most recent call last):
+ ...
+ ValueError: Incompatible key set.
+ >>> oc.updateOrder(1)
+ Traceback (most recent call last):
+ ...
+ TypeError: len() of unsized object
+ >>> oc.updateOrder(['baz', 'zork', 'quux'])
+ Traceback (most recent call last):
+ ...
+ ValueError: Incompatible key set.
+ """
+
+ if len(order) != len(self._order):
+ raise ValueError("Incompatible key set.")
+
+ was_dict = {}
+ will_be_dict = {}
+
+ for i in range(len(order)):
+ was_dict[self._order[i]] = 1
+ will_be_dict[order[i]] = 1
+
+ if will_be_dict != was_dict:
+ raise ValueError("Incompatible key set.")
+
+ self._order = order