[Zope3-checkins] SVN: Zope3/trunk/ For containers, IObjectModifiedEvent has been specialized as

Florent Guillaume fg at nuxeo.com
Fri Nov 25 10:09:45 EST 2005


Log message for revision 40368:
  For containers, IObjectModifiedEvent has been specialized as
  IContainerModifiedEvent, to better isolate "containerness" changes
  (changes where subobjects are added, removed or reordered).
  
  Fixed OrderedContainer.updateOrder to send an IContainerModifiedEvent.
  

Changed:
  U   Zope3/trunk/doc/CHANGES.txt
  U   Zope3/trunk/src/zope/app/container/contained.py
  U   Zope3/trunk/src/zope/app/container/interfaces.py
  U   Zope3/trunk/src/zope/app/container/ordered.py
  U   Zope3/trunk/src/zope/app/container/tests/test_objectcopier.py
  U   Zope3/trunk/src/zope/app/container/tests/test_ordered.py

-=-
Modified: Zope3/trunk/doc/CHANGES.txt
===================================================================
--- Zope3/trunk/doc/CHANGES.txt	2005-11-25 13:32:29 UTC (rev 40367)
+++ Zope3/trunk/doc/CHANGES.txt	2005-11-25 15:09:45 UTC (rev 40368)
@@ -10,6 +10,11 @@
 
     New features
 
+      - For containers, IObjectModifiedEvent has been specialized as
+        IContainerModifiedEvent, to better isolate "containerness"
+        changes (changes where subobjects are added, removed or
+        reordered).
+
       - IObjectCopiedEvent now also carries the original from which the
         copy was made (http://www.zope.org/Collectors/Zope3-dev/478)
 
@@ -157,6 +162,8 @@
 
     Bug Fixes
 
+      - Made OrderedContainer.updateOrder send an IContainerModifiedEvent.
+
       - Fixed bug 451, http://www.zope.org/Collectors/Zope3-dev/451
         Invoke widget factories adequately. Deprecate 
         CustomSequenceWidgetFactory because it does not satisfy IViewFactory.

Modified: Zope3/trunk/src/zope/app/container/contained.py
===================================================================
--- Zope3/trunk/src/zope/app/container/contained.py	2005-11-25 13:32:29 UTC (rev 40367)
+++ Zope3/trunk/src/zope/app/container/contained.py	2005-11-25 15:09:45 UTC (rev 40368)
@@ -27,7 +27,8 @@
 
 from zope.app import zapi
 from zope.app.exception.interfaces import UserError
-from zope.app.event.objectevent import ObjectEvent, modified
+from zope.app.event.objectevent import ObjectEvent
+from zope.app.event.objectevent import ObjectModifiedEvent
 from zope.event import notify
 from zope.app.i18n import ZopeMessageFactory as _
 from zope.app.container.interfaces import IContained
@@ -35,6 +36,7 @@
 from zope.app.container.interfaces import IObjectAddedEvent
 from zope.app.container.interfaces import IObjectMovedEvent
 from zope.app.container.interfaces import IObjectRemovedEvent
+from zope.app.container.interfaces import IContainerModifiedEvent
 from zope.app.location.interfaces import ILocation, ISublocations
 from zope.app.container._zope_app_container_contained import ContainedProxyBase
 from zope.app.container._zope_app_container_contained import getProxiedObject
@@ -83,6 +85,12 @@
             oldName = object.__name__
         ObjectMovedEvent.__init__(self, object, oldParent, oldName, None, None)
 
+class ContainerModifiedEvent(ObjectModifiedEvent):
+    """The container has been modified."""
+
+    zope.interface.implements(IContainerModifiedEvent)
+
+
 def dispatchToSublocations(object, event):
     """Dispatch an event to sublocations of a given object
 
@@ -354,6 +362,10 @@
     """
     return containedEvent(object, container, name)[0]
 
+def notifyContainerModified(object, *descriptions):
+    """Notify that the container was modified."""
+    notify(ContainerModifiedEvent(object, *descriptions))
+
 def setitem(container, setitemf, name, object):
     """Helper function to set an item and generate needed events
 
@@ -581,7 +593,7 @@
     setitemf(name, object)
     if event:
         notify(event)
-        modified(container)
+        notifyContainerModified(container)
 
 fixing_up = False
 def uncontained(object, container, name=None):
@@ -678,7 +690,7 @@
 
     if oldparent is not container or oldname != name:
         if oldparent is not None or oldname is not None:
-            modified(container)
+            notifyContainerModified(container)
         return
 
     event = ObjectRemovedEvent(object, oldparent, oldname)
@@ -687,7 +699,7 @@
     if not IBroken.providedBy(object):
         object.__parent__ = None
         object.__name__ = None
-    modified(container)
+    notifyContainerModified(container)
 
 class NameChooser(object):
 

Modified: Zope3/trunk/src/zope/app/container/interfaces.py
===================================================================
--- Zope3/trunk/src/zope/app/container/interfaces.py	2005-11-25 13:32:29 UTC (rev 40367)
+++ Zope3/trunk/src/zope/app/container/interfaces.py	2005-11-25 15:09:45 UTC (rev 40368)
@@ -25,6 +25,7 @@
 from zope.interface.common.mapping import IReadMapping, IEnumerableMapping
 from zope.app.location.interfaces import ILocation
 from zope.app.event.interfaces import IObjectEvent
+from zope.app.event.interfaces import IObjectModifiedEvent
 
 deprecated('IContentContainer',
            'This interface has been deprecated. '
@@ -90,7 +91,7 @@
 
         If the old parent was ``None``, then an `IObjectAddedEvent` is
         generated, otherwise, an `IObjectMovedEvent` is generated.  An
-        `IObjectModifiedEvent` is generated for the container.
+        `IContainerModifiedEvent` is generated for the container.
 
         If the object replaces another object, then the old object is
         deleted before the new object is added, unless the container
@@ -115,7 +116,7 @@
         `moveNotify` method is called with the event.
 
         Unless the object's `__parent__` and `__name__` attributes were
-        initially ``None``, generate an `IObjectModifiedEvent` for the
+        initially ``None``, generate an `IContainerModifiedEvent` for the
         container.
 
         If the object's `__parent__` and `__name__` were already set to
@@ -263,6 +264,18 @@
 
 
 ##############################################################################
+# Modifying containers
+
+
+class IContainerModifiedEvent(IObjectModifiedEvent):
+    """The container has been modified.
+
+    This event is specific to "containerness" modifications, which means
+    addition, removal or reordering of sub-objects.
+    """
+
+
+##############################################################################
 # Finding objects
 
 class IFind(Interface):

Modified: Zope3/trunk/src/zope/app/container/ordered.py
===================================================================
--- Zope3/trunk/src/zope/app/container/ordered.py	2005-11-25 13:32:29 UTC (rev 40367)
+++ Zope3/trunk/src/zope/app/container/ordered.py	2005-11-25 15:09:45 UTC (rev 40368)
@@ -24,6 +24,7 @@
 from persistent.list import PersistentList
 from types import StringTypes, TupleType, ListType
 from zope.app.container.contained import Contained, setitem, uncontained
+from zope.app.container.contained import notifyContainerModified
 
 class OrderedContainer(Persistent, Contained):
     """ `OrderedContainer` maintains entries' order as added and moved.
@@ -295,4 +296,4 @@
             raise ValueError("Incompatible key set.")
 
         self._order = new_order
-
+        notifyContainerModified(self)

Modified: Zope3/trunk/src/zope/app/container/tests/test_objectcopier.py
===================================================================
--- Zope3/trunk/src/zope/app/container/tests/test_objectcopier.py	2005-11-25 13:32:29 UTC (rev 40367)
+++ Zope3/trunk/src/zope/app/container/tests/test_objectcopier.py	2005-11-25 15:09:45 UTC (rev 40368)
@@ -63,7 +63,7 @@
 
       >>> events = getEvents()
       >>> [event.__class__.__name__ for event in events]
-      ['ObjectCopiedEvent', 'ObjectAddedEvent', 'ObjectModifiedEvent']
+      ['ObjectCopiedEvent', 'ObjectAddedEvent', 'ContainerModifiedEvent']
 
     Check that the ObjectCopiedEvent includes the correct data::
 

Modified: Zope3/trunk/src/zope/app/container/tests/test_ordered.py
===================================================================
--- Zope3/trunk/src/zope/app/container/tests/test_ordered.py	2005-11-25 13:32:29 UTC (rev 40367)
+++ Zope3/trunk/src/zope/app/container/tests/test_ordered.py	2005-11-25 15:09:45 UTC (rev 40368)
@@ -19,13 +19,56 @@
 
 from zope.testing.doctestunit import DocTestSuite
 from zope.app.testing import placelesssetup
+from zope.app.testing import setup
+from zope.app.event.tests.placelesssetup import getEvents
+from zope.app.event.tests.placelesssetup import clearEvents
 
+def test_order_events():
+    """
+    Prepare the setup::
+
+        >>> root = setup.placefulSetUp(site=True)
+
+    Prepare some objects::
+
+        >>> from zope.app.container.ordered import OrderedContainer
+        >>> oc = OrderedContainer()
+        >>> oc['foo'] = 'bar'
+        >>> oc['baz'] = 'quux'
+        >>> oc['zork'] = 'grue'
+        >>> oc.keys()
+        ['foo', 'baz', 'zork']
+
+    Now change the order::
+
+        >>> clearEvents()
+        >>> oc.updateOrder(['baz', 'foo', 'zork'])
+        >>> oc.keys()
+        ['baz', 'foo', 'zork']
+
+    Check what events have been sent::
+
+        >>> events = getEvents()
+        >>> [event.__class__.__name__ for event in events]
+        ['ContainerModifiedEvent']
+
+    This is in fact a specialized modification event::
+
+        >>> from zope.app.event.interfaces import IObjectModifiedEvent
+        >>> IObjectModifiedEvent.providedBy(events[0])
+        True
+
+    Finally, tear down::
+
+        >>> setup.placefulTearDown()
+    """
+
 def test_suite():
     suite = unittest.TestSuite()
     suite.addTest(DocTestSuite("zope.app.container.ordered",
                                setUp=placelesssetup.setUp,
                                tearDown=placelesssetup.tearDown))
-
+    suite.addTest(DocTestSuite())
     return suite
 
 if __name__ == '__main__':



More information about the Zope3-Checkins mailing list