[Zope-Checkins] SVN: Zope/branches/2.9/ Merged trunk r73498:73499
into 2.9 branch.
Stefan H. Holek
stefan at epy.co.at
Sat Mar 24 10:46:04 EDT 2007
Log message for revision 73501:
Merged trunk r73498:73499 into 2.9 branch.
Collector #2298: webdav.Resource.COPY and webdav.Resource.MOVE did
not send the expected copy/move events.
Changed:
U Zope/branches/2.9/doc/CHANGES.txt
A Zope/branches/2.9/lib/python/OFS/tests/events.zcml
A Zope/branches/2.9/lib/python/OFS/tests/testCopySupportEvents.py
U Zope/branches/2.9/lib/python/OFS/tests/testCopySupportHooks.py
U Zope/branches/2.9/lib/python/webdav/Resource.py
-=-
Modified: Zope/branches/2.9/doc/CHANGES.txt
===================================================================
--- Zope/branches/2.9/doc/CHANGES.txt 2007-03-24 14:24:57 UTC (rev 73500)
+++ Zope/branches/2.9/doc/CHANGES.txt 2007-03-24 14:46:00 UTC (rev 73501)
@@ -8,6 +8,9 @@
Bugs fixed
+ - Collector #2298: webdav.Resource.COPY and webdav.Resource.MOVE did
+ not send the expected copy/move events.
+
- Collector #2296: Fixed import of ZClass products, broken by removal
of BBB support for pasting objects whose meta_type info was
permission-free.
Copied: Zope/branches/2.9/lib/python/OFS/tests/events.zcml (from rev 73499, Zope/trunk/lib/python/OFS/tests/events.zcml)
===================================================================
--- Zope/trunk/lib/python/OFS/tests/events.zcml 2007-03-24 14:08:05 UTC (rev 73499)
+++ Zope/branches/2.9/lib/python/OFS/tests/events.zcml 2007-03-24 14:46:00 UTC (rev 73501)
@@ -0,0 +1,112 @@
+<configure
+ xmlns="http://namespaces.zope.org/zope"
+ i18n_domain="extfile">
+
+ <!-- Item -->
+
+ <subscriber
+ handler=".testCopySupportEvents.objectAddedEvent"
+ for=".testCopySupportEvents.ITestItem
+ zope.app.container.interfaces.IObjectAddedEvent"
+ />
+
+ <subscriber
+ handler=".testCopySupportEvents.objectCopiedEvent"
+ for=".testCopySupportEvents.ITestItem
+ zope.app.event.interfaces.IObjectCopiedEvent"
+ />
+
+ <subscriber
+ handler=".testCopySupportEvents.objectMovedEvent"
+ for=".testCopySupportEvents.ITestItem
+ zope.app.container.interfaces.IObjectMovedEvent"
+ />
+
+ <subscriber
+ handler=".testCopySupportEvents.objectRemovedEvent"
+ for=".testCopySupportEvents.ITestItem
+ zope.app.container.interfaces.IObjectRemovedEvent"
+ />
+
+ <subscriber
+ handler=".testCopySupportEvents.objectWillBeAddedEvent"
+ for=".testCopySupportEvents.ITestItem
+ OFS.interfaces.IObjectWillBeAddedEvent"
+ />
+
+ <subscriber
+ handler=".testCopySupportEvents.objectWillBeMovedEvent"
+ for=".testCopySupportEvents.ITestItem
+ OFS.interfaces.IObjectWillBeMovedEvent"
+ />
+
+ <subscriber
+ handler=".testCopySupportEvents.objectWillBeRemovedEvent"
+ for=".testCopySupportEvents.ITestItem
+ OFS.interfaces.IObjectWillBeRemovedEvent"
+ />
+
+ <subscriber
+ handler=".testCopySupportEvents.objectClonedEvent"
+ for=".testCopySupportEvents.ITestItem
+ OFS.interfaces.IObjectClonedEvent"
+ />
+
+ <!-- Folder -->
+
+ <subscriber
+ handler=".testCopySupportEvents.objectAddedEvent"
+ for=".testCopySupportEvents.ITestFolder
+ zope.app.container.interfaces.IObjectAddedEvent"
+ />
+
+ <subscriber
+ handler=".testCopySupportEvents.objectCopiedEvent"
+ for=".testCopySupportEvents.ITestFolder
+ zope.app.event.interfaces.IObjectCopiedEvent"
+ />
+
+ <subscriber
+ handler=".testCopySupportEvents.objectMovedEvent"
+ for=".testCopySupportEvents.ITestFolder
+ zope.app.container.interfaces.IObjectMovedEvent"
+ />
+
+ <subscriber
+ handler=".testCopySupportEvents.objectRemovedEvent"
+ for=".testCopySupportEvents.ITestFolder
+ zope.app.container.interfaces.IObjectRemovedEvent"
+ />
+
+ <subscriber
+ handler=".testCopySupportEvents.containerModifiedEvent"
+ for=".testCopySupportEvents.ITestFolder
+ zope.app.container.interfaces.IContainerModifiedEvent"
+ />
+
+ <subscriber
+ handler=".testCopySupportEvents.objectWillBeAddedEvent"
+ for=".testCopySupportEvents.ITestFolder
+ OFS.interfaces.IObjectWillBeAddedEvent"
+ />
+
+ <subscriber
+ handler=".testCopySupportEvents.objectWillBeMovedEvent"
+ for=".testCopySupportEvents.ITestFolder
+ OFS.interfaces.IObjectWillBeMovedEvent"
+ />
+
+ <subscriber
+ handler=".testCopySupportEvents.objectWillBeRemovedEvent"
+ for=".testCopySupportEvents.ITestFolder
+ OFS.interfaces.IObjectWillBeRemovedEvent"
+ />
+
+ <subscriber
+ handler=".testCopySupportEvents.objectClonedEvent"
+ for=".testCopySupportEvents.ITestFolder
+ OFS.interfaces.IObjectClonedEvent"
+ />
+
+</configure>
+
Copied: Zope/branches/2.9/lib/python/OFS/tests/testCopySupportEvents.py (from rev 73499, Zope/trunk/lib/python/OFS/tests/testCopySupportEvents.py)
Modified: Zope/branches/2.9/lib/python/OFS/tests/testCopySupportHooks.py
===================================================================
--- Zope/branches/2.9/lib/python/OFS/tests/testCopySupportHooks.py 2007-03-24 14:24:57 UTC (rev 73500)
+++ Zope/branches/2.9/lib/python/OFS/tests/testCopySupportHooks.py 2007-03-24 14:46:00 UTC (rev 73501)
@@ -14,70 +14,49 @@
from OFS.Folder import Folder
-class HookCounter:
- '''Logs calls to old-school hooks'''
-
+class EventLogger(object):
def __init__(self):
self.reset()
-
def reset(self):
- self.count = 0
- self.afterAdd = [0]
- self.afterClone = [0]
- self.beforeDelete = [0]
+ self._called = []
+ def trace(self, ob, event):
+ self._called.append((ob.getId(), event))
+ def called(self):
+ return self._called
- def manage_afterAdd(self, item, container):
- self.count = self.count + 1
- self.afterAdd.append(self.count)
+eventlog = EventLogger()
- def manage_afterClone(self, item):
- self.count = self.count + 1
- self.afterClone.append(self.count)
- def manage_beforeDelete(self, item, container):
- self.count = self.count + 1
- self.beforeDelete.append(self.count)
-
- def order(self):
- return self.afterAdd[-1], self.afterClone[-1], self.beforeDelete[-1]
-
-
-class TestItem(HookCounter, SimpleItem):
-
+class TestItem(SimpleItem):
def __init__(self, id):
- HookCounter.__init__(self)
self.id = id
+ def manage_afterAdd(self, item, container):
+ eventlog.trace(self, 'manage_afterAdd')
+ def manage_afterClone(self, item):
+ eventlog.trace(self, 'manage_afterClone')
+ def manage_beforeDelete(self, item, container):
+ eventlog.trace(self, 'manage_beforeDelete')
-class TestFolder(HookCounter, Folder):
-
+class TestFolder(Folder):
def __init__(self, id):
- HookCounter.__init__(self)
self.id = id
-
def _verifyObjectPaste(self, object, validate_src=1):
- # Don't verify pastes as our test objects don't have
- # factory methods registered.
- pass
-
+ pass # Always allow
def manage_afterAdd(self, item, container):
- HookCounter.manage_afterAdd(self, item, container)
+ eventlog.trace(self, 'manage_afterAdd')
Folder.manage_afterAdd(self, item, container)
-
def manage_afterClone(self, item):
- HookCounter.manage_afterClone(self, item)
+ eventlog.trace(self, 'manage_afterClone')
Folder.manage_afterClone(self, item)
-
def manage_beforeDelete(self, item, container):
- HookCounter.manage_beforeDelete(self, item, container)
+ eventlog.trace(self, 'manage_beforeDelete')
Folder.manage_beforeDelete(self, item, container)
-try:
- from Products.Five.eventconfigure import setDeprecatedManageAddDelete
- setDeprecatedManageAddDelete(HookCounter)
-except ImportError:
- pass
+from Products.Five.eventconfigure import setDeprecatedManageAddDelete
+setDeprecatedManageAddDelete(TestItem)
+setDeprecatedManageAddDelete(TestFolder)
class HookTest(unittest.TestCase):
@@ -100,44 +79,56 @@
class TestCopySupport(HookTest):
- '''Tests the order in which the add/clone/del hooks are called'''
+ '''Tests the order in which add/clone/del hooks are called'''
def setUp(self):
HookTest.setUp(self)
- # A folder
+ # A folder that does not verify pastes
self.app._setObject('folder', TestFolder('folder'))
- self.folder = self.app['folder']
- # A subfolder we are going to copy/move to
+ self.folder = getattr(self.app, 'folder')
+ # The subfolder we are going to copy/move to
self.folder._setObject('subfolder', TestFolder('subfolder'))
- self.subfolder = self.folder['subfolder']
- # A document we are going to copy/move
+ self.subfolder = getattr(self.folder, 'subfolder')
+ # The document we are going to copy/move
self.folder._setObject('mydoc', TestItem('mydoc'))
- # Must have _p_jars
+ # Need _p_jars
transaction.savepoint(1)
- # Reset counters
- self.folder.mydoc.reset()
+ # Reset event log
+ eventlog.reset()
def test_1_Clone(self):
# Test clone
- self.subfolder.manage_clone(self.folder.mydoc, 'yourdoc')
- self.assertEqual(self.subfolder.yourdoc.order(), (1, 2, 0)) # add, clone
+ self.subfolder.manage_clone(self.folder.mydoc, 'mydoc')
+ self.assertEqual(eventlog.called(),
+ [('mydoc', 'manage_afterAdd'),
+ ('mydoc', 'manage_afterClone')]
+ )
def test_2_CopyPaste(self):
# Test copy/paste
cb = self.folder.manage_copyObjects(['mydoc'])
self.subfolder.manage_pasteObjects(cb)
- self.assertEqual(self.subfolder.mydoc.order(), (1, 2, 0)) # add, clone
+ self.assertEqual(eventlog.called(),
+ [('mydoc', 'manage_afterAdd'),
+ ('mydoc', 'manage_afterClone')]
+ )
def test_3_CutPaste(self):
# Test cut/paste
cb = self.folder.manage_cutObjects(['mydoc'])
self.subfolder.manage_pasteObjects(cb)
- self.assertEqual(self.subfolder.mydoc.order(), (2, 0, 1)) # del, add
+ self.assertEqual(eventlog.called(),
+ [('mydoc', 'manage_beforeDelete'),
+ ('mydoc', 'manage_afterAdd')]
+ )
def test_4_Rename(self):
# Test rename
self.folder.manage_renameObject('mydoc', 'yourdoc')
- self.assertEqual(self.folder.yourdoc.order(), (2, 0, 1)) # del, add
+ self.assertEqual(eventlog.called(),
+ [('mydoc', 'manage_beforeDelete'),
+ ('yourdoc', 'manage_afterAdd')]
+ )
def test_5_COPY(self):
# Test webdav COPY
@@ -145,123 +136,136 @@
req.environ['HTTP_DEPTH'] = 'infinity'
req.environ['HTTP_DESTINATION'] = '%s/subfolder/mydoc' % self.folder.absolute_url()
self.folder.mydoc.COPY(req, req.RESPONSE)
- self.assertEqual(req.RESPONSE.getStatus(), 201)
- self.assertEqual(self.subfolder.mydoc.order(), (1, 2, 0)) # add, clone
+ self.assertEqual(eventlog.called(),
+ [('mydoc', 'manage_afterAdd'),
+ ('mydoc', 'manage_afterClone')]
+ )
def test_6_MOVE(self):
# Test webdav MOVE
req = self.app.REQUEST
req.environ['HTTP_DEPTH'] = 'infinity'
req.environ['HTTP_DESTINATION'] = '%s/subfolder/mydoc' % self.folder.absolute_url()
- old = self.folder.mydoc
self.folder.mydoc.MOVE(req, req.RESPONSE)
- self.assertEqual(req.RESPONSE.getStatus(), 201)
- self.assertEqual(old.order(), (0, 0, 1)) # del
- self.assertEqual(self.subfolder.mydoc.order(), (1, 0, 0)) # add
+ self.assertEqual(eventlog.called(),
+ [('mydoc', 'manage_beforeDelete'),
+ ('mydoc', 'manage_afterAdd')]
+ )
def test_7_DELETE(self):
# Test webdav DELETE
req = self.app.REQUEST
req['URL'] = '%s/mydoc' % self.folder.absolute_url()
- old = self.folder.mydoc
self.folder.mydoc.DELETE(req, req.RESPONSE)
- self.assertEqual(req.RESPONSE.getStatus(), 204)
- self.assertEqual(old.order(), (0, 0, 1)) # del
+ self.assertEqual(eventlog.called(),
+ [('mydoc', 'manage_beforeDelete')]
+ )
class TestCopySupportSublocation(HookTest):
- '''Tests the order in which the add/clone/del hooks are called'''
+ '''Tests the order in which add/clone/del hooks are called'''
def setUp(self):
HookTest.setUp(self)
- # A folder
+ # A folder that does not verify pastes
self.app._setObject('folder', TestFolder('folder'))
- self.folder = self.app['folder']
- # A subfolder we are going to copy/move to
+ self.folder = getattr(self.app, 'folder')
+ # The subfolder we are going to copy/move to
self.folder._setObject('subfolder', TestFolder('subfolder'))
- self.subfolder = self.folder['subfolder']
- # A folderish object we are going to copy/move
+ self.subfolder = getattr(self.folder, 'subfolder')
+ # The folder we are going to copy/move
self.folder._setObject('myfolder', TestFolder('myfolder'))
- self.myfolder = self.folder['myfolder']
- # A "sublocation" inside myfolder we are going to watch
+ self.myfolder = getattr(self.folder, 'myfolder')
+ # The "sublocation" inside our folder we are going to watch
self.myfolder._setObject('mydoc', TestItem('mydoc'))
- # Must have _p_jars
+ # Need _p_jars
transaction.savepoint(1)
- # Reset counters
- self.myfolder.reset()
- self.myfolder.mydoc.reset()
+ # Reset event log
+ eventlog.reset()
def test_1_Clone(self):
# Test clone
- self.subfolder.manage_clone(self.folder.myfolder, 'yourfolder')
- self.assertEqual(self.subfolder.yourfolder.order(), (1, 2, 0)) # add, clone
- self.assertEqual(self.subfolder.yourfolder.mydoc.order(), (1, 2, 0)) # add, clone
+ self.subfolder.manage_clone(self.folder.myfolder, 'myfolder')
+ self.assertEqual(eventlog.called(),
+ [('myfolder', 'manage_afterAdd'),
+ ('mydoc', 'manage_afterAdd'),
+ ('myfolder', 'manage_afterClone'),
+ ('mydoc', 'manage_afterClone')]
+ )
def test_2_CopyPaste(self):
# Test copy/paste
cb = self.folder.manage_copyObjects(['myfolder'])
self.subfolder.manage_pasteObjects(cb)
- self.assertEqual(self.subfolder.myfolder.order(), (1, 2, 0)) # add, clone
- self.assertEqual(self.subfolder.myfolder.mydoc.order(), (1, 2, 0)) # add, clone
+ self.assertEqual(eventlog.called(),
+ [('myfolder', 'manage_afterAdd'),
+ ('mydoc', 'manage_afterAdd'),
+ ('myfolder', 'manage_afterClone'),
+ ('mydoc', 'manage_afterClone')]
+ )
def test_3_CutPaste(self):
# Test cut/paste
cb = self.folder.manage_cutObjects(['myfolder'])
self.subfolder.manage_pasteObjects(cb)
- self.assertEqual(self.subfolder.myfolder.order(), (2, 0, 1)) # del, add
- self.assertEqual(self.subfolder.myfolder.mydoc.order(), (2, 0, 1)) # del, add
+ self.assertEqual(eventlog.called(),
+ [('mydoc', 'manage_beforeDelete'),
+ ('myfolder', 'manage_beforeDelete'),
+ ('myfolder', 'manage_afterAdd'),
+ ('mydoc', 'manage_afterAdd')]
+ )
def test_4_Rename(self):
# Test rename
self.folder.manage_renameObject('myfolder', 'yourfolder')
- self.assertEqual(self.folder.yourfolder.order(), (2, 0, 1)) # del, add
- self.assertEqual(self.folder.yourfolder.mydoc.order(), (2, 0, 1)) # del, add
+ self.assertEqual(eventlog.called(),
+ [('mydoc', 'manage_beforeDelete'),
+ ('myfolder', 'manage_beforeDelete'),
+ ('yourfolder', 'manage_afterAdd'),
+ ('mydoc', 'manage_afterAdd')]
+ )
def test_5_COPY(self):
# Test webdav COPY
- #
- # See http://www.zope.org/Collectors/Zope/2169
- #
req = self.app.REQUEST
req.environ['HTTP_DEPTH'] = 'infinity'
- req.environ['HTTP_DESTINATION'] = '%s/subfolder/yourfolder' % self.folder.absolute_url()
+ req.environ['HTTP_DESTINATION'] = '%s/subfolder/myfolder' % self.folder.absolute_url()
self.folder.myfolder.COPY(req, req.RESPONSE)
- self.assertEqual(req.RESPONSE.getStatus(), 201)
- self.assertEqual(self.subfolder.yourfolder.order(), (1, 2, 0)) # add, clone
- self.assertEqual(self.subfolder.yourfolder.mydoc.order(), (1, 2, 0)) # add, clone
+ self.assertEqual(eventlog.called(),
+ [('myfolder', 'manage_afterAdd'),
+ ('mydoc', 'manage_afterAdd'),
+ ('myfolder', 'manage_afterClone'),
+ ('mydoc', 'manage_afterClone')]
+ )
def test_6_MOVE(self):
# Test webdav MOVE
req = self.app.REQUEST
req.environ['HTTP_DEPTH'] = 'infinity'
- req.environ['HTTP_DESTINATION'] = '%s/subfolder/yourfolder' % self.folder.absolute_url()
- oldfolder = self.folder.myfolder
- olddoc = self.folder.myfolder.mydoc
+ req.environ['HTTP_DESTINATION'] = '%s/subfolder/myfolder' % self.folder.absolute_url()
self.folder.myfolder.MOVE(req, req.RESPONSE)
- self.assertEqual(req.RESPONSE.getStatus(), 201)
- self.assertEqual(oldfolder.order(), (0, 0, 1)) # del
- self.assertEqual(self.subfolder.yourfolder.order(), (1, 0, 0)) # add
- self.assertEqual(olddoc.order(), (0, 0, 1)) # del
- self.assertEqual(self.subfolder.yourfolder.mydoc.order(), (1, 0, 0)) # add
+ self.assertEqual(eventlog.called(),
+ [('mydoc', 'manage_beforeDelete'),
+ ('myfolder', 'manage_beforeDelete'),
+ ('myfolder', 'manage_afterAdd'),
+ ('mydoc', 'manage_afterAdd')]
+ )
def test_7_DELETE(self):
# Test webdav DELETE
req = self.app.REQUEST
req['URL'] = '%s/myfolder' % self.folder.absolute_url()
- oldfolder = self.folder.myfolder
- olddoc = self.folder.myfolder.mydoc
self.folder.myfolder.DELETE(req, req.RESPONSE)
- self.assertEqual(req.RESPONSE.getStatus(), 204)
- self.assertEqual(oldfolder.order(), (0, 0, 1)) # del
- self.assertEqual(olddoc.order(), (0, 0, 1)) # del
+ self.assertEqual(eventlog.called(),
+ [('mydoc', 'manage_beforeDelete'),
+ ('myfolder', 'manage_beforeDelete')]
+ )
def test_suite():
- suite = unittest.TestSuite()
- suite.addTest(unittest.makeSuite(TestCopySupport))
- suite.addTest(unittest.makeSuite(TestCopySupportSublocation))
+ from unittest import TestSuite, makeSuite
+ suite = TestSuite()
+ suite.addTest(makeSuite(TestCopySupport))
+ suite.addTest(makeSuite(TestCopySupportSublocation))
return suite
-if __name__ == '__main__':
- unittest.main(defaultTest='test_suite')
-
Modified: Zope/branches/2.9/lib/python/webdav/Resource.py
===================================================================
--- Zope/branches/2.9/lib/python/webdav/Resource.py 2007-03-24 14:24:57 UTC (rev 73500)
+++ Zope/branches/2.9/lib/python/webdav/Resource.py 2007-03-24 14:46:00 UTC (rev 73501)
@@ -17,12 +17,13 @@
import mimetypes
import sys
+import warnings
from urllib import unquote
import ExtensionClass
import Globals
from AccessControl import getSecurityManager
-from Acquisition import aq_base
+from Acquisition import aq_base, aq_inner, aq_parent
from zExceptions import BadRequest, MethodNotAllowed
from zExceptions import Unauthorized, Forbidden, NotFound
from zope.interface import implements
@@ -39,7 +40,11 @@
from WriteLockInterface import WriteLockInterface
from zope.event import notify
+from zope.app.event.objectevent import ObjectCopiedEvent
+from zope.app.container.contained import ObjectMovedEvent
+from zope.app.container.contained import notifyContainerModified
from OFS.event import ObjectClonedEvent
+from OFS.event import ObjectWillBeMovedEvent
import OFS.subscribers
@@ -229,7 +234,7 @@
ifhdr = REQUEST.get_header('If', '')
url = urlfix(REQUEST['URL'], 'DELETE')
name = unquote(filter(None, url.split( '/')[-1]))
- parent = self.aq_parent
+ parent = aq_parent(aq_inner(self))
# Lock checking
if Lockable.wl_isLocked(self):
if ifhdr:
@@ -393,10 +398,14 @@
if depth=='0' and isDavCollection(ob):
for id in ob.objectIds():
ob._delObject(id)
+
+ notify(ObjectCopiedEvent(ob, self))
+
if existing:
object=getattr(parent, name)
self.dav__validate(object, 'DELETE', REQUEST)
parent._delObject(name)
+
parent._setObject(name, ob)
ob = parent._getOb(name)
ob._postCopy(parent, op=0)
@@ -502,20 +511,52 @@
raise PreconditionFailed, 'Source is locked and no '\
'condition was passed in.'
+ orig_container = aq_parent(aq_inner(self))
+ orig_id = self.getId()
+
+ self._notifyOfCopyTo(parent, op=1)
+
+ notify(ObjectWillBeMovedEvent(self, orig_container, orig_id,
+ parent, name))
+
# try to make ownership explicit so that it gets carried
# along to the new location if needed.
self.manage_changeOwnershipType(explicit=1)
- self._notifyOfCopyTo(parent, op=1)
- ob = aq_base(self._getCopy(parent))
- self.aq_parent._delObject(absattr(self.id))
+ ob = self._getCopy(parent)
ob._setId(name)
+
+ try:
+ orig_container._delObject(orig_id, suppress_events=True)
+ except TypeError:
+ # BBB: removed in Zope 2.11
+ orig_container._delObject(orig_id)
+ warnings.warn(
+ "%s._delObject without suppress_events is deprecated "
+ "and will be removed in Zope 2.11." %
+ orig_container.__class__.__name__, DeprecationWarning)
+
if existing:
object=getattr(parent, name)
self.dav__validate(object, 'DELETE', REQUEST)
parent._delObject(name)
- parent._setObject(name, ob)
+
+ try:
+ parent._setObject(name, ob, set_owner=0, suppress_events=True)
+ except TypeError:
+ # BBB: removed in Zope 2.11
+ parent._setObject(name, ob, set_owner=0)
+ warnings.warn(
+ "%s._setObject without suppress_events is deprecated "
+ "and will be removed in Zope 2.11." %
+ parent.__class__.__name__, DeprecationWarning)
ob = parent._getOb(name)
+
+ notify(ObjectMovedEvent(ob, orig_container, orig_id, parent, name))
+ notifyContainerModified(orig_container)
+ if aq_base(orig_container) is not aq_base(parent):
+ notifyContainerModified(parent)
+
ob._postCopy(parent, op=1)
# try to make ownership implicit if possible
More information about the Zope-Checkins
mailing list