[z3-checkins] r19705 - in z3/Five/branch/Five-1.2: . bbb tests
efge at codespeak.net
efge at codespeak.net
Thu Nov 10 15:00:28 CET 2005
Author: efge
Date: Thu Nov 10 15:00:27 2005
New Revision: 19705
Modified:
z3/Five/branch/Five-1.2/bbb/OFS_subscribers.py
z3/Five/branch/Five-1.2/event.py
z3/Five/branch/Five-1.2/tests/event.txt
z3/Five/branch/Five-1.2/tests/test_event.py
Log:
Updates to compatibility mode to make recursion work better.
Keep in sync with what will be in Five 1.3 in a few minutes.
Modified: z3/Five/branch/Five-1.2/bbb/OFS_subscribers.py
==============================================================================
--- z3/Five/branch/Five-1.2/bbb/OFS_subscribers.py (original)
+++ z3/Five/branch/Five-1.2/bbb/OFS_subscribers.py Thu Nov 10 15:00:27 2005
@@ -17,15 +17,15 @@
$Id$
"""
-##################################################
-
+import warnings
import sys
+
from zLOG import LOG, ERROR
+from Acquisition import aq_base
from App.config import getConfiguration
from AccessControl import getSecurityManager
from ZODB.POSException import ConflictError
from OFS.ObjectManager import BeforeDeleteException
-from Products.Five.fiveconfigure import isFiveMethod
from zope.app.container.contained import dispatchToSublocations
from OFS_interfaces import IObjectManager
@@ -33,36 +33,42 @@
deprecatedManageAddDeleteClasses = []
-def hasDeprecatedMethods(ob):
- """Do we need to call the deprecated methods?
+def compatibilityCall(method_name, *args):
+ """Call a method if events have not been setup yet.
+
+ This is the case for some unit tests that have not been converted to
+ use the component architecture.
"""
- for class_ in deprecatedManageAddDeleteClasses:
- if isinstance(ob, class_):
- return True
- return False
-
-def maybeCallDeprecated(method_name, ob, *args):
- """Call a deprecated method, if the framework doesn't call it already.
- """
- if hasDeprecatedMethods(ob):
- # Already deprecated through zcml
- return
- method = getattr(ob, method_name)
- if isFiveMethod(method):
- # Monkey-patched method
- return
if deprecatedManageAddDeleteClasses:
- # Not deprecated through zcml and directives fully loaded
- class_ = ob.__class__
- warnings.warn(
- "Calling %s.%s.%s is deprecated when using Five, "
- "instead use event subscribers or "
- "mark the class with <five:deprecatedManageAddDelete/>"
- % (class_.__module__, class_.__name__, method_name),
- DeprecationWarning)
- # Note that calling the method can lead to incorrect behavior
- # but in the most common case that's better than not calling it.
- method(ob, *args)
+ # Events initialized, don't do compatibility call
+ return
+ if method_name == 'manage_afterAdd':
+ callManageAfterAdd(*args)
+ elif method_name == 'manage_beforeDelete':
+ callManageBeforeDelete(*args)
+ else:
+ callManageAfterClone(*args)
+
+def maybeWarnDeprecated(ob, method_name):
+ """Send a warning if a method is deprecated.
+ """
+ if not deprecatedManageAddDeleteClasses:
+ # Directives not fully loaded
+ return
+ for cls in deprecatedManageAddDeleteClasses:
+ if isinstance(ob, cls):
+ # Already deprecated through zcml
+ return
+ if getattr(getattr(ob, method_name), '__five_method__', False):
+ # Method knows it's deprecated
+ return
+ class_ = ob.__class__
+ warnings.warn(
+ "%s.%s.%s is deprecated and will be removed in Zope 2.11, "
+ "you should use event subscribers instead, and meanwhile "
+ "mark the class with <five:deprecatedManageAddDelete/>"
+ % (class_.__module__, class_.__name__, method_name),
+ DeprecationWarning)
##################################################
@@ -95,15 +101,13 @@
if IObjectManager.providedBy(ob):
dispatchToSublocations(ob, event)
# Next, do the manage_beforeDelete dance
- if hasDeprecatedMethods(ob):
- callManageBeforeDelete(ob, event)
+ callManageBeforeDelete(ob, event.object, event.oldParent)
def dispatchObjectMovedEvent(ob, event):
"""Multi-subscriber for IItem + IObjectMovedEvent.
"""
# First, do the manage_afterAdd dance
- if hasDeprecatedMethods(ob):
- callManageAfterAdd(ob, event)
+ callManageAfterAdd(ob, event.object, event.newParent)
# Next, dispatch to sublocations
if IObjectManager.providedBy(ob):
dispatchToSublocations(ob, event)
@@ -112,31 +116,32 @@
"""Multi-subscriber for IItem + IObjectClonedEvent.
"""
# First, do the manage_afterClone dance
- if hasDeprecatedMethods(ob):
- callManageAfterClone(ob, event)
+ callManageAfterClone(ob, event.object)
# Next, dispatch to sublocations
if IObjectManager.providedBy(ob):
dispatchToSublocations(ob, event)
-def callManageAfterAdd(ob, event):
+def callManageAfterAdd(ob, item, container):
"""Compatibility subscriber for manage_afterAdd.
"""
- container = event.newParent
if container is None:
- # this is a remove
return
- ob.manage_afterAdd(event.object, container)
+ if getattr(aq_base(ob), 'manage_afterAdd', None) is None:
+ return
+ maybeWarnDeprecated(ob, 'manage_afterAdd')
+ ob.manage_afterAdd(item, container)
-def callManageBeforeDelete(ob, event):
+def callManageBeforeDelete(ob, item, container):
"""Compatibility subscriber for manage_beforeDelete.
"""
- container = event.oldParent
if container is None:
- # this is an add
return
+ if getattr(aq_base(ob), 'manage_beforeDelete', None) is None:
+ return
+ maybeWarnDeprecated(ob, 'manage_beforeDelete')
try:
- ob.manage_beforeDelete(event.object, container)
+ ob.manage_beforeDelete(item, container)
except BeforeDeleteException:
raise
except ConflictError:
@@ -148,7 +153,10 @@
if not getSecurityManager().getUser().has_role('Manager'):
raise
-def callManageAfterClone(ob, event):
+def callManageAfterClone(ob, item):
"""Compatibility subscriber for manage_afterClone.
"""
- ob.manage_afterClone(event.object)
+ if getattr(aq_base(ob), 'manage_afterClone', None) is None:
+ return
+ maybeWarnDeprecated(ob, 'manage_afterClone')
+ ob.manage_afterClone(item)
Modified: z3/Five/branch/Five-1.2/event.py
==============================================================================
--- z3/Five/branch/Five-1.2/event.py (original)
+++ z3/Five/branch/Five-1.2/event.py Thu Nov 10 15:00:27 2005
@@ -40,8 +40,7 @@
from OFS.event import ObjectWillBeRemovedEvent
from OFS.event import ObjectClonedEvent
from OFS.subscribers import deprecatedManageAddDeleteClasses
-from OFS.subscribers import hasDeprecatedMethods
-from OFS.subscribers import maybeCallDeprecated
+from OFS.subscribers import compatibilityCall
from Products.Five.fiveconfigure import isFiveMethod
@@ -130,7 +129,7 @@
if not suppress_events:
notify(ObjectAddedEvent(ob, self, id))
- maybeCallDeprecated('manage_afterAdd', ob, self)
+ compatibilityCall('manage_afterAdd', ob, ob, self)
return id
@@ -171,7 +170,7 @@
if not suppress_events:
notify(ObjectAddedEvent(ob, self, id))
- maybeCallDeprecated('manage_afterAdd', ob, self)
+ compatibilityCall('manage_afterAdd', ob, ob, self)
return id
@@ -184,7 +183,7 @@
"""
ob = self._getOb(id)
- maybeCallDeprecated('manage_beforeDelete', ob, self)
+ compatibilityCall('manage_beforeDelete', ob, ob, self)
if not suppress_events:
notify(ObjectWillBeRemovedEvent(ob, self, id))
@@ -211,7 +210,7 @@
def BT_delObject(self, id, dp=1, suppress_events=False):
ob = self._getOb(id)
- maybeCallDeprecated('manage_beforeDelete', ob, self)
+ compatibilityCall('manage_beforeDelete', ob, ob, self)
if not suppress_events:
notify(ObjectWillBeRemovedEvent(ob, self, id))
@@ -340,7 +339,7 @@
ob._postCopy(self, op=0)
- maybeCallDeprecated('manage_afterClone', ob)
+ compatibilityCall('manage_afterClone', ob, ob)
notify(ObjectClonedEvent(ob))
@@ -440,7 +439,7 @@
ob._postCopy(self, op=0)
- maybeCallDeprecated('manage_afterClone', ob)
+ compatibilityCall('manage_afterClone', ob, ob)
notify(ObjectClonedEvent(ob))
Modified: z3/Five/branch/Five-1.2/tests/event.txt
==============================================================================
--- z3/Five/branch/Five-1.2/tests/event.txt (original)
+++ z3/Five/branch/Five-1.2/tests/event.txt Thu Nov 10 15:00:27 2005
@@ -47,12 +47,12 @@
>>> app = MyApp('')
>>> root['app'] = app
>>> folder = MyFolder('folder')
- >>> app._setObject('folder', folder)
+ >>> app._setObject('folder', folder) # doctest: +NORMALIZE_WHITESPACE
old manage_afterAdd folder folder
'folder'
>>> folder = app.folder
>>> btfolder = MyBTreeFolder('btfolder')
- >>> app._setObject('btfolder', btfolder)
+ >>> app._setObject('btfolder', btfolder) # doctest: +NORMALIZE_WHITESPACE
old manage_afterAdd btfolder btfolder
'btfolder'
@@ -187,31 +187,63 @@
>>> from Products.Five.event import doMonkies, undoMonkies
>>> doMonkies()
+We need at least one fake deprecated method to tell the compatibility
+framework that component architecture is initialized::
+
+ >>> from Products.Five.eventconfigure import setDeprecatedManageAddDelete
+ >>> class C(object): pass
+ >>> setDeprecatedManageAddDelete(C)
+
Old class
---------
If we use an instance of an old class for which we haven't specified
anything, events are sent and the manage_afterAdd & co methods are
-called but in a "compatibility" way.
-
-Because the bases classes of Zope have been changed to not recurse
-except through the event framework, unexpected behavior may happen
-(however a warning will be sent)::
+called, but with a deprecation warning::
+ >>> sub = MyFolder('sub')
+ >>> folder._setObject('sub', sub)
+ ObjectWillBeAddedEvent sub
+ ObjectAddedEvent sub
+ old manage_afterAdd sub sub folder
+ 'sub'
+ >>> sub = folder.sub
>>> ob = MyContent('dog')
- >>> folder._setObject('dog', ob)
+ >>> sub._setObject('dog', ob)
ObjectWillBeAddedEvent dog
ObjectAddedEvent dog
- old manage_afterAdd dog dog folder
+ old manage_afterAdd dog dog sub
'dog'
-And when we delete the object, manage_beforeDelete is also called and
-events are sent::
+And when we rename the subfolder, manage_beforeDelete is also called
+bottom-up and events are sent::
- >>> folder.manage_delObjects('dog')
- old manage_beforeDelete dog dog folder
- ObjectWillBeRemovedEvent dog
- ObjectRemovedEvent dog
+ >>> folder.manage_renameObject('sub', 'marine')
+ ObjectWillBeMovedEvent sub
+ ObjectWillBeMovedEvent dog
+ old manage_beforeDelete dog sub folder
+ old manage_beforeDelete sub sub folder
+ ObjectMovedEvent marine
+ old manage_afterAdd marine marine folder
+ ObjectMovedEvent dog
+ old manage_afterAdd dog marine folder
+
+Same thing for clone::
+
+ >>> res = folder.manage_clone(folder.marine, 'tank')
+ ObjectCopiedEvent tank
+ ObjectWillBeAddedEvent tank
+ ObjectWillBeAddedEvent dog
+ ObjectAddedEvent tank
+ old manage_afterAdd tank tank folder
+ ObjectAddedEvent dog
+ old manage_afterAdd dog tank folder
+ ObjectClonedEvent tank
+ old manage_afterClone tank tank
+ ObjectClonedEvent dog
+ old manage_afterClone dog tank
+ >>> res.getId()
+ 'tank'
Old class with deprecatedManageAddDelete
----------------------------------------
@@ -466,7 +498,7 @@
OrderedFolder has the same renaming behavior than before::
>>> ofolder = MyOrderedFolder('ofolder')
- >>> app._setObject('ofolder', ofolder)
+ >>> app._setObject('ofolder', ofolder) # doctest: +NORMALIZE_WHITESPACE
ObjectWillBeAddedEvent ofolder
ObjectAddedEvent ofolder
old manage_afterAdd ofolder ofolder
Modified: z3/Five/branch/Five-1.2/tests/test_event.py
==============================================================================
--- z3/Five/branch/Five-1.2/tests/test_event.py (original)
+++ z3/Five/branch/Five-1.2/tests/test_event.py Thu Nov 10 15:00:27 2005
@@ -41,13 +41,16 @@
print 'old manage_afterAdd %s %s %s' % (self.getId(), item.getId(),
container.getId())
super(NotifyBase, self).manage_afterAdd(item, container)
+ manage_afterAdd.__five_method__ = True # Shut up deprecation warnings
def manage_beforeDelete(self, item, container):
super(NotifyBase, self).manage_beforeDelete(item, container)
print 'old manage_beforeDelete %s %s %s' % (self.getId(), item.getId(),
container.getId())
+ manage_beforeDelete.__five_method__ = True # Shut up deprecation warnings
def manage_afterClone(self, item):
print 'old manage_afterClone %s %s' % (self.getId(), item.getId())
super(NotifyBase, self).manage_afterClone(item)
+ manage_afterClone.__five_method__ = True # Shut up deprecation warnings
class MyApp(Folder):
def getPhysicalRoot(self):
@@ -78,8 +81,8 @@
def test_suite():
- from Testing.ZopeTestCase import ZopeDocFileSuite
- return ZopeDocFileSuite('event.txt', package="Products.Five.tests")
+ from zope.testing.doctest import DocFileSuite
+ return DocFileSuite('event.txt', package="Products.Five.tests")
if __name__ == '__main__':
framework()
More information about the z3-checkins
mailing list