[Zope3-checkins] CVS: Zope3/src/zope/app/container - btree.py:1.3.26.1 configure.zcml:1.10.16.1 copypastemove.py:1.5.16.1 dependency.py:1.5.16.1 directory.py:1.3.16.1 find.py:1.2.26.1 sample.py:1.6.10.1 size.py:1.2.18.1 traversal.py:1.7.10.1 zopecontainer.py:1.15.4.1

Grégoire Weber zope@i-con.ch
Sun, 22 Jun 2003 10:23:56 -0400


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

Modified Files:
      Tag: cw-mail-branch
	btree.py configure.zcml copypastemove.py dependency.py 
	directory.py find.py sample.py size.py traversal.py 
	zopecontainer.py 
Log Message:
Synced up with HEAD

=== Zope3/src/zope/app/container/btree.py 1.3 => 1.3.26.1 ===
--- Zope3/src/zope/app/container/btree.py:1.3	Mon Dec 30 15:43:49 2002
+++ Zope3/src/zope/app/container/btree.py	Sun Jun 22 10:22:55 2003
@@ -29,7 +29,7 @@
 
 class BTreeContainer(SampleContainer, Persistent):
 
-    __implements__ = SampleContainer.__implements__, Persistent.__implements__
+    # implements(what my base classes implement)
 
     # XXX It appears that BTreeContainer uses SampleContainer only to
     # get the implementation of setObject().  All the other methods


=== Zope3/src/zope/app/container/configure.zcml 1.10 => 1.10.16.1 ===
--- Zope3/src/zope/app/container/configure.zcml:1.10	Mon Mar 31 09:48:40 2003
+++ Zope3/src/zope/app/container/configure.zcml	Sun Jun 22 10:22:55 2003
@@ -5,79 +5,80 @@
    xmlns:event="http://namespaces.zope.org/event"
 >
 
-  <adapter 
+  <adapter
      provides="zope.app.interfaces.container.find.IFind"
      for="zope.app.interfaces.container.IReadContainer"
-     permission="zope.ManageContent" 
-     factory="zope.app.container.find.FindAdapter" 
+     permission="zope.ManageContent"
+     factory="zope.app.container.find.FindAdapter"
      />
 
-  <adapter 
+  <adapter
       for="zope.app.interfaces.container.IReadContainer"
       provides="zope.app.interfaces.file.IReadDirectory"
       factory=".directory.noop"
       />
 
-  <adapter 
+  <adapter
       for="zope.app.interfaces.container.IWriteContainer"
       provides="zope.app.interfaces.file.IWriteDirectory"
       factory=".directory.noop"
       />
 
-  <adapter factory="zope.app.container.traversal.ContainerTraversable"
-           provides="zope.app.interfaces.traversing.ITraversable"
-           for="zope.app.interfaces.container.IReadContainer" 
-           />
-
-  <adapter factory="zope.app.container.zopecontainer.ZopeContainerAdapter"
-           provides="zope.app.interfaces.container.IZopeContainer"
-           for="zope.app.interfaces.container.IContainer" 
-           />
-
-  <adapter factory="zope.app.container.size.ContainerSized"
-           provides="zope.app.interfaces.size.ISized"
-           for="zope.app.interfaces.container.IContainer" 
-           />
-
-  <adapter 
-     provides="zope.app.interfaces.container.ICopySource"
-     for="zope.app.interfaces.content.folder.IFolder"
-     permission="zope.ManageContent" 
-     factory="zope.app.container.copypastemove.CopySource" 
-     />
-
-  <adapter 
-     provides="zope.app.interfaces.container.INoChildrenCopySource"
-     for="zope.app.interfaces.content.folder.IFolder"
-     permission="zope.ManageContent" 
-     factory="zope.app.container.copypastemove.NoChildrenCopySource" 
-     />
-
-  <adapter 
-     provides="zope.app.interfaces.container.IMoveSource"
-     for="zope.app.interfaces.content.folder.IFolder"
-     permission="zope.ManageContent" 
-     factory="zope.app.container.copypastemove.MoveSource" 
-     />
+  <adapter
+      factory="zope.app.container.traversal.ContainerTraversable"
+      provides="zope.app.interfaces.traversing.ITraversable"
+      for="zope.app.interfaces.container.IReadContainer"
+      />
 
-  <adapter 
-     provides="zope.app.interfaces.container.IPasteTarget"
-     for="zope.app.interfaces.content.folder.IFolder"
-     permission="zope.ManageContent" 
-     factory="zope.app.container.copypastemove.PasteTarget" 
-     />
-           
-  <adapter 
-     provides="zope.app.interfaces.container.IPasteNamesChooser"
-     for="zope.app.interfaces.content.folder.IFolder"
-     permission="zope.ManageContent" 
-     factory="zope.app.container.copypastemove.PasteNamesChooser" 
-     />
+  <!-- Decorators for different flavours of container -->
+  <adapter
+      factory="zope.app.container.zopecontainer.ZopeItemContainerDecorator"
+      provides="zope.app.interfaces.context.IZopeContextWrapper"
+      for="zope.app.interfaces.container.IItemContainer"
+      />
+  <adapter
+      factory="
+      zope.app.container.zopecontainer.ZopeSimpleReadContainerDecorator"
+      provides="zope.app.interfaces.context.IZopeContextWrapper"
+      for="zope.app.interfaces.container.ISimpleReadContainer"
+      />
+  <adapter
+      factory="
+      zope.app.container.zopecontainer.ZopeReadContainerDecorator"
+      provides="zope.app.interfaces.context.IZopeContextWrapper"
+      for="zope.app.interfaces.container.IReadContainer"
+      />
+  <adapter
+      factory="
+      zope.app.container.zopecontainer.ZopeItemWriteContainerDecorator"
+      provides="zope.app.interfaces.context.IZopeContextWrapper"
+      for="zope.app.interfaces.container.IItemWriteContainer"
+      />
+  <adapter
+      factory="zope.app.container.zopecontainer.ZopeContainerDecorator"
+      provides="zope.app.interfaces.context.IZopeContextWrapper"
+      for="zope.app.interfaces.container.IContainer"
+      />
 
+  <!-- XXX There is a sticky question of what permission 'rename' should have.
+           See src/zope/app/context.txt for further discussion.
+    -->
+  <class class="zope.app.container.zopecontainer.ZopeContainerDecorator">
+    <require
+        attributes="rename"
+        permission="zope.ManageServices"
+        />
+  </class>
+
+  <adapter
+      factory="zope.app.container.size.ContainerSized"
+      provides="zope.app.interfaces.size.ISized"
+      for="zope.app.interfaces.container.IReadContainer"
+      />
 
-  <event:subscribe 
-      subscriber = ".dependency.CheckDependency"
-      event_types = "zope.app.interfaces.event.IObjectRemovedEvent"
+  <event:subscribe
+      subscriber=".dependency.CheckDependency"
+      event_types="zope.app.interfaces.event.IObjectRemovedEvent"
       />
 
 </zopeConfigure>


=== Zope3/src/zope/app/container/copypastemove.py 1.5 => 1.5.16.1 ===
--- Zope3/src/zope/app/container/copypastemove.py:1.5	Mon Mar 31 09:48:40 2003
+++ Zope3/src/zope/app/container/copypastemove.py	Sun Jun 22 10:22:55 2003
@@ -17,25 +17,27 @@
 $Id$
 """
 
-from zope.app.interfaces.container import IOptionalNamesContainer
+from types import StringTypes
+from zope.app.event import publish
+from zope.app.event.objectevent import ObjectModifiedEvent
+from zope.app.interfaces.container import IContainer
 from zope.app.interfaces.container import IContainerNamesContainer
-from zope.app.interfaces.container import IMoveSource
 from zope.app.interfaces.container import ICopySource, INoChildrenCopySource
-from zope.app.interfaces.container import IPasteTarget
+from zope.app.interfaces.container import IMoveSource
+from zope.app.interfaces.container import IOptionalNamesContainer
 from zope.app.interfaces.container import IPasteNamesChooser
+from zope.app.interfaces.container import IPasteTarget
 from zope.app.interfaces.content.folder import ICloneWithoutChildren
 from zope.component import getAdapter
-from zope.proxy.introspection import removeAllProxies
-from zope.app.event.objectevent import ObjectModifiedEvent
-from zope.proxy.context import ContextWrapper
-from zope.app.event import publish
-from zope.proxy.introspection import removeAllProxies
-from types import StringTypes
+from zope.interface import implements
+from zope.app.context import ContextWrapper
+from zope.proxy import removeAllProxies
 import copy
 
 class PasteTarget:
 
-    __implements__ = IPasteTarget
+    implements(IPasteTarget)
+    __used_for__ = IContainer
 
     def __init__(self, container):
         self.context = container
@@ -97,7 +99,7 @@
 
 class MoveSource:
 
-    __implements__ = IMoveSource
+    implements(IMoveSource)
 
     def __init__(self, container):
         self.context = container
@@ -127,7 +129,7 @@
 
 class CopySource:
 
-    __implements__ = ICopySource
+    implements(ICopySource)
 
     def __init__(self, container):
         self.context = container
@@ -147,7 +149,7 @@
 
 class NoChildrenCopySource:
 
-    __implements__ = INoChildrenCopySource
+    implements(INoChildrenCopySource)
 
     def __init__(self, container):
         self.context = container
@@ -168,7 +170,7 @@
 
 class PasteNamesChooser:
 
-    __implements__ = IPasteNamesChooser
+    implements(IPasteNamesChooser)
 
     def __init__(self, container):
         self.context = container


=== Zope3/src/zope/app/container/dependency.py 1.5 => 1.5.16.1 ===
--- Zope3/src/zope/app/container/dependency.py:1.5	Fri Mar 21 10:29:07 2003
+++ Zope3/src/zope/app/container/dependency.py	Sun Jun 22 10:22:55 2003
@@ -19,13 +19,14 @@
 from zope.app.interfaces.dependable import IDependable
 from zope.app.interfaces.dependable import DependencyError
 from zope.app.interfaces.event import ISubscriber
-from zope.proxy.introspection import removeAllProxies
+from zope.proxy import removeAllProxies
 from zope.app.traversing import getPath, canonicalPath
+from zope.interface import implements
 
 class DependencyChecker:
     """Checking dependency  while deleting object
     """
-    __implements__ = ISubscriber
+    implements(ISubscriber)
 
     def __init__(self):
         pass


=== Zope3/src/zope/app/container/directory.py 1.3 => 1.3.16.1 ===
--- Zope3/src/zope/app/container/directory.py:1.3	Mon Mar 31 12:13:07 2003
+++ Zope3/src/zope/app/container/directory.py	Sun Jun 22 10:22:55 2003
@@ -26,7 +26,8 @@
 __metaclass__ = type
 
 import zope.app.interfaces.file
-from zope.proxy.introspection import removeAllProxies
+from zope.proxy import removeAllProxies
+from zope.interface import implements
 
 def noop(container):
     """XXX adapt an IContainer to an IWriteDirectory by just returning it
@@ -41,10 +42,9 @@
 
     This adapter provides a factory that creates a new empty container
     of the same class as it's context.
-    
     """
 
-    __implements__ = zope.app.interfaces.file.IDirectoryFactory
+    implements(zope.app.interfaces.file.IDirectoryFactory)
 
     def __init__(self, context):
         self.context = context


=== Zope3/src/zope/app/container/find.py 1.2 => 1.2.26.1 ===
--- Zope3/src/zope/app/container/find.py:1.2	Wed Dec 25 09:12:46 2002
+++ Zope3/src/zope/app/container/find.py	Sun Jun 22 10:22:55 2003
@@ -19,12 +19,13 @@
 
 from zope.app.interfaces.container.find import IFind, IIdFindFilter
 from zope.app.interfaces.container import IReadContainer
+from zope.interface import implements
 # XXX need to do this manually to wrap objects
-from zope.proxy.context import ContextWrapper
+from zope.app.context import ContextWrapper
 
 class FindAdapter(object):
 
-    __implements__ =  IFind
+    implements(IFind)
 
     __used_for__ = IReadContainer
 
@@ -71,7 +72,7 @@
 
 class SimpleIdFindFilter(object):
 
-    __implements__ =  IIdFindFilter
+    implements(IIdFindFilter)
 
     def __init__(self, ids):
         self._ids = ids


=== Zope3/src/zope/app/container/sample.py 1.6 => 1.6.10.1 ===
--- Zope3/src/zope/app/container/sample.py:1.6	Thu May  1 15:35:09 2003
+++ Zope3/src/zope/app/container/sample.py	Sun Jun 22 10:22:55 2003
@@ -25,6 +25,7 @@
 from types import StringTypes
 
 from zope.app.interfaces.container import IContainer
+from zope.interface import implements
 
 class SampleContainer(object):
     """Sample container implementation suitable for testing.
@@ -33,8 +34,7 @@
     overrides _Container__newData to return a persistent mapping
     object.
     """
-
-    __implements__ =  IContainer
+    implements(IContainer)
 
     def __init__(self):
         self.__data = self._newContainerData()


=== Zope3/src/zope/app/container/size.py 1.2 => 1.2.18.1 ===
--- Zope3/src/zope/app/container/size.py:1.2	Wed Mar 12 05:04:46 2003
+++ Zope3/src/zope/app/container/size.py	Sun Jun 22 10:22:55 2003
@@ -18,12 +18,13 @@
 """
 
 from zope.app.interfaces.size import ISized
+from zope.interface import implements
 
 __metaclass__ = type
 
 class ContainerSized:
 
-    __implements__ = ISized
+    implements(ISized)
 
     def __init__(self, container):
         self._container = container


=== Zope3/src/zope/app/container/traversal.py 1.7 => 1.7.10.1 ===
--- Zope3/src/zope/app/container/traversal.py:1.7	Thu May  1 15:35:09 2003
+++ Zope3/src/zope/app/container/traversal.py	Sun Jun 22 10:22:55 2003
@@ -27,13 +27,14 @@
 from zope.app.traversing.namespace import UnexpectedParameters
 from zope.app.interfaces.container import IReadContainer
 from zope.exceptions import NotFoundError
+from zope.interface import implements
 
 # Note that the next two classes are included here because they
 # can be used for multiple view types.
 
 class ContainerTraverser:
 
-    __implements__ = IBrowserPublisher, IXMLRPCPublisher
+    implements(IBrowserPublisher, IXMLRPCPublisher)
     __used_for__ = ISimpleReadContainer
 
     def __init__(self, container, request):
@@ -84,7 +85,7 @@
     """Traverses containers via getattr and get.
     """
 
-    __implements__ = ITraversable
+    implements(ITraversable)
     __used_for__ = IReadContainer
 
     def __init__(self, container):


=== Zope3/src/zope/app/container/zopecontainer.py 1.15 => 1.15.4.1 ===
--- Zope3/src/zope/app/container/zopecontainer.py:1.15	Thu May  8 06:57:55 2003
+++ Zope3/src/zope/app/container/zopecontainer.py	Sun Jun 22 10:22:55 2003
@@ -17,80 +17,105 @@
 $Id$
 """
 
+from zope.app.interfaces.container import IZopeSimpleReadContainer
+from zope.app.interfaces.container import IZopeReadContainer
+from zope.app.interfaces.container import IZopeItemWriteContainer
 from zope.app.interfaces.container import IZopeContainer
 from zope.app.interfaces.container import IOptionalNamesContainer
 from zope.app.interfaces.container import IContainerNamesContainer
 from zope.component import queryAdapter, getAdapter
-from zope.proxy.context import ContextWrapper
+from zope.app.context import ContextWrapper, Wrapper
 from zope.app.event import publish
 from zope.app.interfaces.container import IAddNotifiable
 from zope.app.interfaces.container import IDeleteNotifiable
 from zope.app.interfaces.copypastemove import IObjectMover
 from types import StringTypes
-from zope.proxy.introspection import removeAllProxies
+from zope.proxy import removeAllProxies, getProxiedObject
 from zope.exceptions import NotFoundError, DuplicationError
-from zope.app.event.objectevent \
-     import ObjectRemovedEvent, ObjectModifiedEvent, ObjectAddedEvent
+from zope.app.event.objectevent import ObjectRemovedEvent
+from zope.app.event.objectevent import ObjectModifiedEvent, ObjectAddedEvent
+from zope.interface import implements
 
 _marker = object()
+class ZopeItemContainerDecorator(Wrapper):
+    """Decorates an IItemContainer object for context-awareness.
 
-class ZopeContainerAdapter:
-
-    __implements__ = IZopeContainer
-
-    def __init__(self, container):
-        self.context = container
+    Also, upgrades it to IZopeSimpleReadContainer.
+    """
+    implements(IZopeSimpleReadContainer)
 
     def __getitem__(self, key):
         "See IZopeItemContainer"
-        value = self.context[key]
-        return ContextWrapper(value, self.context, 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"
-        value = self.context.get(key, _marker)
+        container = getProxiedObject(self)
+        value = container.get(key, _marker)
         if value is not _marker:
-            return ContextWrapper(value, self.context, name=key)
+            return ContextWrapper(value, self, name=key)
         else:
             return default
 
-    def __contains__(self, key):
-        '''See interface IReadContainer'''
-        return key in self.context
 
+class ZopeReadContainerDecorator(ZopeSimpleReadContainerDecorator):
+    implements(IZopeReadContainer)
 
     def values(self):
         "See IZopeReadContainer"
-        container = self.context
+        container = getProxiedObject(self)
         result = []
         for key, value in container.items():
-            result.append(ContextWrapper(value, container, name=key))
+            result.append(ContextWrapper(value, self, name=key))
         return result
 
-    def keys(self):
-        '''See interface IReadContainer'''
-        return self.context.keys()
-
-    def __len__(self):
-        '''See interface IReadContainer'''
-        return len(self.context)
-
     def items(self):
         "See IZopeReadContainer"
-        container = self.context
+        container = getProxiedObject(self)
         result = []
         for key, value in container.items():
-            result.append((key, ContextWrapper(value, container, name=key)))
+            result.append((key, ContextWrapper(value, self, name=key)))
         return result
 
 
+class ZopeItemWriteContainerDecorator(ZopeItemContainerDecorator):
+    # Both 'setObject' and '__delitem__' depend on the decorator having
+    # '__getitem__'
+    #
+    # A ZopeWriteContainerDecorator could be written to work with other
+    # means for getting objects from a container. However, in most cases,
+    # IZopeWriteContainer depends on IItemContainer.
+
+    implements(IZopeItemWriteContainer)
+
     def setObject(self, key, object):
         "See IZopeWriteContainer"
-
         if not isinstance(key, StringTypes):
             raise TypeError("Item name is not a string.")
 
-        container = self.context
+        container = getProxiedObject(self)
 
         if not key:
             if not (IOptionalNamesContainer.isImplementedBy(container)
@@ -108,28 +133,30 @@
         # 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.
-        object = ContextWrapper(container[key], container, name=key)
-        publish(container, ObjectAddedEvent(object))
+        #
+        # Dependency Note: This is a dependency on IItemContainer
+        object = self[key]
+        publish(self, ObjectAddedEvent(object))
 
         # Call the after add hook, if necessary
         adapter = queryAdapter(object, IAddNotifiable)
         if adapter is not None:
-            adapter.afterAddHook(object, container)
+            adapter.afterAddHook(object, self)
 
-        publish(container, ObjectModifiedEvent(container))
+        publish(self, ObjectModifiedEvent(self))
         return key
 
     def __delitem__(self, key):
         "See IZopeWriteContainer"
-        container = self.context
+        container = getProxiedObject(self)
 
-        object = container[key]
-        object = ContextWrapper(object, container, name=key)
+        # Dependency Note: This is a dependency on IItemContainer
+        object = ContextWrapper(container[key], self, name=key)
 
         # Call the before delete hook, if necessary
         adapter = queryAdapter(object, IDeleteNotifiable)
         if adapter is not None:
-            adapter.beforeDeleteHook(object, container)
+            adapter.beforeDeleteHook(object, self)
         elif hasattr(object, 'beforeDeleteHook'):
             # XXX: Ideally, only do this in debug mode.
             from warnings import warn
@@ -138,15 +165,20 @@
 
         del container[key]
 
-        publish(container, ObjectRemovedEvent(object))
-        publish(container, ObjectModifiedEvent(container))
+        publish(self, ObjectRemovedEvent(object))
+        publish(self, ObjectModifiedEvent(self))
 
         return key
 
-    def __iter__(self):
-        '''See interface IReadContainer'''
-        return iter(self.context)
 
+class ZopeContainerDecorator(ZopeItemWriteContainerDecorator,
+                             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.
 
@@ -170,14 +202,13 @@
 
         Then, an IObjectMovedEvent is published.
         """
-
         object = self.get(currentKey)
         if object is None:
-            raise NotFoundError(self.context, currentKey)
+            raise NotFoundError(self, currentKey)
         mover = getAdapter(object, IObjectMover)
-        target = self.context
+        target = self
 
-        if target.__contains__(newKey):
+        if newKey in target:
             raise DuplicationError("name, %s, is already in use" % newKey)
 
         if mover.moveable() and mover.moveableTo(target, newKey):