[Zope3-checkins] CVS: Zope3/src/zope/app/container - btree.py:1.4.24.1 configure.zcml:1.18.2.3 contained.py:1.1.2.2 ordered.py:1.5.10.2 sample.py:1.7.24.2 add.py:NONE copypastemove.py:NONE remove.py:NONE

Jim Fulton jim at zope.com
Fri Sep 12 15:15:51 EDT 2003


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

Modified Files:
      Tag: parentgeddon-branch
	btree.py configure.zcml contained.py ordered.py sample.py 
Removed Files:
      Tag: parentgeddon-branch
	add.py copypastemove.py remove.py 
Log Message:
Can't have the tests passing, can we?

=== Zope3/src/zope/app/container/btree.py 1.4 => 1.4.24.1 ===
--- Zope3/src/zope/app/container/btree.py:1.4	Tue Jun  3 10:16:05 2003
+++ Zope3/src/zope/app/container/btree.py	Fri Sep 12 15:15:20 2003
@@ -32,7 +32,7 @@
     # implements(what my base classes implement)
 
     # XXX It appears that BTreeContainer uses SampleContainer only to
-    # get the implementation of setObject().  All the other methods
+    # get the implementation of __setitem__().  All the other methods
     # provided by that base class are just slower replacements for
     # operations on the BTree itself.  It would probably be clearer to
     # just delegate those methods directly to the btree.


=== Zope3/src/zope/app/container/configure.zcml 1.18.2.2 => 1.18.2.3 ===
--- Zope3/src/zope/app/container/configure.zcml:1.18.2.2	Mon Sep  8 18:36:52 2003
+++ Zope3/src/zope/app/container/configure.zcml	Fri Sep 12 15:15:20 2003
@@ -39,20 +39,14 @@
       />
 
   <adapter
-      provides="zope.app.interfaces.container.IAddTarget"
+      provides="zope.app.interfaces.container.INameChooser"
       for="zope.app.interfaces.container.IWriteContainer"
-      factory=".add.AddTarget"
-      />
-
-  <adapter
-      provides="zope.app.interfaces.container.IRemoveSource"
-      for="zope.app.interfaces.container.IWriteContainer"
-      factory=".remove.RemoveSource"
+      factory=".contained.NameChooser"
       />
 
   <event:subscribe
       subscriber=".dependency.CheckDependency"
-      event_types="zope.app.interfaces.event.IObjectRemovedEvent"
+      event_types="zope.app.interfaces.container.IObjectRemovedEvent"
       />
 
 </configure>


=== Zope3/src/zope/app/container/contained.py 1.1.2.1 => 1.1.2.2 ===
--- Zope3/src/zope/app/container/contained.py:1.1.2.1	Mon Sep  8 14:21:19 2003
+++ Zope3/src/zope/app/container/contained.py	Fri Sep 12 15:15:20 2003
@@ -16,12 +16,22 @@
 $Id$
 """
 
-import zope.interface
+from zope.app.decorator import DecoratedSecurityCheckerDescriptor
+from zope.app.decorator import DecoratorSpecificationDescriptor
+from zope.app.event import objectevent
+from zope.app.event import publish
+from zope.app.i18n import ZopeMessageIDFactory as _
+from zope.app import zapi
+from zope.app.interfaces.container import IAddNotifiable, IMoveNotifiable
 from zope.app.interfaces.container import IContained
+from zope.app.interfaces.container import INameChooser
+from zope.app.interfaces.container import IObjectAddedEvent
+from zope.app.interfaces.container import IObjectMovedEvent
+from zope.app.interfaces.container import IObjectRemovedEvent
+from zope.app.interfaces.container import IRemoveNotifiable
 from zope.app.interfaces.location import ILocation
 from zope.proxy import ProxyBase, getProxiedObject
-from zope.app.decorator import DecoratorSpecificationDescriptor
-from zope.app.decorator import DecoratedSecurityCheckerDescriptor
+import zope.interface
 
 class Contained(object):
     """Stupid mix-in that defines __parent__ and __name__ attributes
@@ -31,6 +41,43 @@
 
     __parent__ = __name__ = None
 
+class ObjectMovedEvent(objectevent.ObjectEvent):
+    """An object has been moved"""
+
+    zope.interface.implements(IObjectMovedEvent)
+
+    def __init__(self, object, oldParent, oldName, newParent, newName):
+        objectevent.ObjectEvent.__init__(self, object)
+        self.oldParent = oldParent
+        self.oldName = oldName
+        self.newParent = newParent
+        self.newName = newName
+
+class ObjectAddedEvent(ObjectMovedEvent):
+    """An object has been added to a container"""
+
+    zope.interface.implements(IObjectAddedEvent)
+
+    def __init__(self, object, newParent=None, newName=None):
+        if newParent is None:
+            newParent = object.__parent__
+        if newName is None:
+            newName = object.__name__        
+        ObjectMovedEvent.__init__(self, object, None, None, newParent, newName)
+
+class ObjectRemovedEvent(ObjectMovedEvent):
+    """An object has been removed from a container"""
+
+    zope.interface.implements(IObjectRemovedEvent)
+
+    def __init__(self, object, oldParent=None, oldName=None):
+        if oldParent is None:
+            oldParent = object.__parent__
+        if oldName is None:
+            oldName = object.__name__        
+        ObjectMovedEvent.__init__(self, object, oldParent, oldName, None, None)
+
+
 def contained(object, container, name=None):
     """Establish the containment of the object in the container
 
@@ -85,12 +132,33 @@
         else:
             object = ContainedProxy(object)
 
-    object.__parent__ = container
-    object.__name__ = name
+    oldparent = object.__parent__
+    oldname = object.__name__
+    
+    if oldparent is not container or oldname != name:
+        object.__parent__ = container
+        object.__name__ = name
+
+        if oldparent is None:
+            event = ObjectAddedEvent(object, container, name)
+            a = zapi.queryAdapter(object, IAddNotifiable)
+            if a is not None:
+                a.addNotify(event)
+        else:
+            event = ObjectMovedEvent(
+                object, oldparent, oldname, container, name)
+
+        a = zapi.queryAdapter(object, IMoveNotifiable)
+        if a is not None:
+            a.moveNotify(event)
+        publish(container, event)
+
+    event = objectevent.ObjectModifiedEvent(container)
+    publish(container, event)
 
     return object
 
-def uncontained(object):
+def uncontained(object, container):
     """Clear the containment relationship between the object amd the container
 
     >>> container = {}
@@ -103,14 +171,29 @@
     >>> item.__name__
     'foo'
 
-    >>> x = uncontained(item)
+    >>> x = uncontained(item, container)
     >>> item.__parent__ is container
     False
     >>> item.__name__    
     
     """
+    oldparent = object.__parent__
+    if oldparent is container:
+        event = ObjectRemovedEvent(
+            object, oldparent, object.__name__)
+        a = zapi.queryAdapter(object, IRemoveNotifiable)
+        if a is not None:
+            a.removeNotify(event)
+        a = zapi.queryAdapter(object, IMoveNotifiable)
+        if a is not None:
+            a.moveNotify(event)
+        publish(container, event)
+
+        object.__parent__ = None
+        object.__name__ = None
 
-    object.__parent__ = object.__name__ = None
+    event = objectevent.ObjectModifiedEvent(container)
+    publish(container, event)
 
 class ContainedProxy(ProxyBase):
     """Contained-object proxy
@@ -169,3 +252,64 @@
         raise AttributeError, '_p_oid'
 
     _p_oid = property(_p_oid)
+
+
+class NameChooser:
+
+    zope.interface.implements(INameChooser)
+
+    def __init__(self, context):
+        self.context = context
+
+    def checkName(self, name, object):
+        "See zope.app.interfaces.container.INameChooser"
+
+        if not name:
+            raise zapi.UserError(
+                _("An empty name was provided. Names cannot be empty.")
+                )
+
+        if isinstance(name, str):
+            name = unicode(name)
+        elif not isinstance(name, unicode):
+            raise TypeError("Invalid name type", type(name))
+        
+        if name[:1] in '+@' or '/' in name:
+            raise zapi.UserError(
+                _("Names cannot begin with '+' or '@' or contain '/'")
+                )
+
+        if name in self.context:
+            raise zapi.UserError(
+                _("The given name is already being used")
+                )
+            
+        return True
+
+
+    def chooseName(self, name, object):
+        "See zope.app.interfaces.container.INameChooser"
+
+        container = self.context
+        
+        if not name:
+            name = object.__class__.__name__
+
+        dot = name.rfind('.')
+        if dot:
+            suffix = name[dot:]
+            name = name[:dot]
+        else:
+            suffix = ''
+            
+            
+        n = name + suffix
+        i = 1
+        while n in container:
+            i += 1
+            n = name + u'-' + unicode(i) + suffix
+
+        # Make sure tha name is valid.  We may have started with something bad.
+        self.checkName(n, object)
+                
+        return name


=== Zope3/src/zope/app/container/ordered.py 1.5.10.1 => 1.5.10.2 ===
--- Zope3/src/zope/app/container/ordered.py:1.5.10.1	Mon Sep  8 14:21:19 2003
+++ Zope3/src/zope/app/container/ordered.py	Fri Sep 12 15:15:20 2003
@@ -48,10 +48,10 @@
         >>> oc = OrderedContainer()
         >>> oc.keys()
         []
-        >>> key = oc.setObject('foo', 'bar')
+        >>> oc['foo'] = 'bar'
         >>> oc.keys()
         ['foo']
-        >>> key = oc.setObject('baz', 'quux')
+        >>> oc['baz'] = 'quux'
         >>> oc.keys()
         ['foo', 'baz']
         >>> int(len(oc._order) == len(oc._data))
@@ -66,8 +66,8 @@
         >>> oc = OrderedContainer()
         >>> oc.keys()
         []
-        >>> key = oc.setObject('foo', 'bar')
-        >>> key = oc.setObject('baz', 'quux')
+        >>> oc['foo'] = 'bar'
+        >>> oc['baz'] = 'quux'
         >>> [i for i in oc]
         ['foo', 'baz']
         >>> int(len(oc._order) == len(oc._data))
@@ -80,7 +80,7 @@
         """ See IOrderedContainer
 
         >>> oc = OrderedContainer()
-        >>> key = oc.setObject('foo', 'bar')
+        >>> oc['foo'] = 'bar'
         >>> oc['foo']
         'bar'
         """
@@ -91,7 +91,7 @@
         """ See IOrderedContainer
 
         >>> oc = OrderedContainer()
-        >>> key = oc.setObject('foo', 'bar')
+        >>> oc['foo'] = 'bar'
         >>> oc.get('foo')
         'bar'
         >>> oc.get('funky', 'No chance, dude.')
@@ -106,10 +106,10 @@
         >>> oc = OrderedContainer()
         >>> oc.keys()
         []
-        >>> key = oc.setObject('foo', 'bar')
+        >>> oc['foo'] = 'bar'
         >>> oc.values()
         ['bar']
-        >>> key = oc.setObject('baz', 'quux')
+        >>> oc['baz'] = 'quux'
         >>> oc.values()
         ['bar', 'quux']
         >>> int(len(oc._order) == len(oc._data))
@@ -124,7 +124,7 @@
         >>> oc = OrderedContainer()
         >>> int(len(oc) == 0)
         1
-        >>> key = oc.setObject('foo', 'bar')
+        >>> oc['foo'] = 'bar'
         >>> int(len(oc) == 1)
         1
         """
@@ -137,10 +137,10 @@
         >>> oc = OrderedContainer()
         >>> oc.keys()
         []
-        >>> key = oc.setObject('foo', 'bar')
+        >>> oc['foo'] = 'bar'
         >>> oc.items()
         [('foo', 'bar')]
-        >>> key = oc.setObject('baz', 'quux')
+        >>> oc['baz'] = 'quux'
         >>> oc.items()
         [('foo', 'bar'), ('baz', 'quux')]
         >>> int(len(oc._order) == len(oc._data))
@@ -153,7 +153,7 @@
         """ See IOrderedContainer.
 
         >>> oc = OrderedContainer()
-        >>> key = oc.setObject('foo', 'bar')
+        >>> oc['foo'] = 'bar'
         >>> int('foo' in oc)
         1
         >>> int('quux' in oc)
@@ -164,16 +164,16 @@
 
     has_key = __contains__
 
-    def setObject(self, key, object):
+    def __setitem__(self, key, object):
         """ See IOrderedContainer.
 
         >>> oc = OrderedContainer()
         >>> oc.keys()
         []
-        >>> key = oc.setObject('foo', 'bar')
+        >>> oc['foo'] = 'bar'
         >>> oc._order
         ['foo']
-        >>> key = oc.setObject('baz', 'quux')
+        >>> oc['baz'] = 'quux'
         >>> oc._order
         ['foo', 'baz']
         >>> int(len(oc._order) == len(oc._data))
@@ -209,9 +209,9 @@
         >>> oc = OrderedContainer()
         >>> oc.keys()
         []
-        >>> key = oc.setObject('foo', 'bar')
-        >>> key = oc.setObject('baz', 'quux')
-        >>> key = oc.setObject('zork', 'grue')
+        >>> oc['foo'] = 'bar'
+        >>> oc['baz'] = 'quux'
+        >>> oc['zork'] = 'grue'
         >>> oc.items()
         [('foo', 'bar'), ('baz', 'quux'), ('zork', 'grue')]
         >>> int(len(oc._order) == len(oc._data))
@@ -223,7 +223,7 @@
         1
         """
 
-        uncontained(self._data[key])
+        uncontained(self._data[key], self)
         del self._data[key]
         self._order.remove(key)
 
@@ -231,9 +231,9 @@
         """ See IOrderedContainer
 
         >>> oc = OrderedContainer()
-        >>> key = oc.setObject('foo', 'bar')
-        >>> key = oc.setObject('baz', 'quux')
-        >>> key = oc.setObject('zork', 'grue')
+        >>> oc['foo'] = 'bar'
+        >>> oc['baz'] = 'quux'
+        >>> oc['zork'] = 'grue'
         >>> oc.keys()
         ['foo', 'baz', 'zork']
         >>> oc.updateOrder(['baz', 'foo', 'zork'])


=== Zope3/src/zope/app/container/sample.py 1.7.24.1 => 1.7.24.2 ===
--- Zope3/src/zope/app/container/sample.py:1.7.24.1	Mon Sep  8 14:21:19 2003
+++ Zope3/src/zope/app/container/sample.py	Fri Sep 12 15:15:20 2003
@@ -83,7 +83,7 @@
 
     has_key = __contains__
 
-    def setObject(self, key, object):
+    def __setitem__(self, key, object):
         '''See interface IWriteContainer'''
         bad = False
         if isinstance(key, StringTypes):
@@ -104,5 +104,5 @@
 
     def __delitem__(self, key):
         '''See interface IWriteContainer'''
-        uncontained(self.__data[key])
+        uncontained(self.__data[key], self)
         del self.__data[key]

=== Removed File Zope3/src/zope/app/container/add.py ===

=== Removed File Zope3/src/zope/app/container/copypastemove.py ===

=== Removed File Zope3/src/zope/app/container/remove.py ===




More information about the Zope3-Checkins mailing list