[Zope3-checkins] CVS: Zope3/src/zope/app/container - zopecontainer.py:1.22

Steve Alexander steve@cat-box.net
Sun, 15 Jun 2003 12:11:13 -0400


Update of /cvs-repository/Zope3/src/zope/app/container
In directory cvs.zope.org:/tmp/cvs-serv18616/src/zope/app/container

Modified Files:
	zopecontainer.py 
Log Message:
Added ZopeContainerDecorators for all kinds of container.

One notable feature is that an IItemContainer is decorated to become
an IZopeSimpleReadContainer. The decorator implements ISimpleReadContainer
in terms of IItemContainer.


=== Zope3/src/zope/app/container/zopecontainer.py 1.21 => 1.22 ===
--- Zope3/src/zope/app/container/zopecontainer.py:1.21	Sat Jun 14 10:41:16 2003
+++ Zope3/src/zope/app/container/zopecontainer.py	Sun Jun 15 12:10:43 2003
@@ -17,6 +17,9 @@
 $Id$
 """
 
+from zope.app.interfaces.container import IZopeSimpleReadContainer
+from zope.app.interfaces.container import IZopeReadContainer
+from zope.app.interfaces.container import IZopeWriteContainer
 from zope.app.interfaces.container import IZopeContainer
 from zope.app.interfaces.container import IOptionalNamesContainer
 from zope.app.interfaces.container import IContainerNamesContainer
@@ -34,15 +37,38 @@
 from zope.interface import implements
 
 _marker = object()
+class ZopeItemContainerDecorator(Wrapper):
+    """Decorates an IItemContainer object for context-awareness.
 
-class ZopeContainerDecorator(Wrapper):
-    implements(IZopeContainer)
+    Also, upgrades it to IZopeSimpleReadContainer.
+    """
+    implements(IZopeSimpleReadContainer)
 
     def __getitem__(self, key):
         "See IZopeItemContainer"
-        container = getProxiedObject(self)
-        value = container[key]
-        return ContextWrapper(value, self, name=key)
+        return ContextWrapper(getProxiedObject(self)[key], self, name=key)
+
+    def get(self, key, default=None):
+        "See IZopeSimpleReadContainer"
+        # 'get' defined in terms of __getitem__
+        try:
+            return self[key]
+        except KeyError:
+            return default
+
+    def __contains__(self, key):
+        "See IReadMapping"
+        # '__contains__' in terms of __getitem__ on the proxied object
+        container = getProxiedObject(self)
+        try:
+            container[key]
+            return True
+        except KeyError:
+            return False
+
+
+class ZopeSimpleReadContainerDecorator(ZopeItemContainerDecorator):
+    implements(IZopeSimpleReadContainer)
 
     def get(self, key, default=None):
         "See IZopeSimpleReadContainer"
@@ -53,6 +79,10 @@
         else:
             return default
 
+
+class ZopeReadContainerDecorator(ZopeSimpleReadContainerDecorator):
+    implements(IZopeReadContainer)
+
     def values(self):
         "See IZopeReadContainer"
         container = getProxiedObject(self)
@@ -69,6 +99,13 @@
             result.append((key, ContextWrapper(value, self, name=key)))
         return result
 
+
+class ZopeWriteContainerDecorator(ZopeItemContainerDecorator):
+    # Both setObject and __delitem__ depend on the decorator having
+    # __getitem__
+
+    implements(IZopeWriteContainer)
+
     def setObject(self, key, object):
         "See IZopeWriteContainer"
         if not isinstance(key, StringTypes):
@@ -92,6 +129,8 @@
         # We explicitly get the object back from the container with
         # container[key], because some kinds of container may choose
         # to store a different object than the exact one we added.
+        #
+        # Dependency Note: This is a dependency on IItemContainer
         object = self[key]
         publish(self, ObjectAddedEvent(object))
 
@@ -107,6 +146,7 @@
         "See IZopeWriteContainer"
         container = getProxiedObject(self)
 
+        # Dependency Note: This is a dependency on IItemContainer
         object = ContextWrapper(container[key], self, name=key)
 
         # Call the before delete hook, if necessary
@@ -126,6 +166,15 @@
 
         return key
 
+
+class ZopeContainerDecorator(ZopeWriteContainerDecorator,
+                             ZopeReadContainerDecorator):
+    implements(IZopeContainer)
+
+    # XXX: rename should really be in IZopeWriteContainer, and should
+    #      lose its dependence on decorator.get(). However, the whole
+    #      renaming business will be refactored soon, so this method
+    #      will go away at that point.
     def rename(self, currentKey, newKey):
         """Put the object found at 'currentKey' under 'newKey' instead.