[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