Commit bd276aa8 authored by Florent Guillaume's avatar Florent Guillaume

To be used with Five efge-1.3-event-work branch.

Changed deprecation strategy a bit, for maximum compatibility.

This fixes a bug, seen in the expanded tests in Five/tests/event.txt,
about "compatibility" recursion for old classes.
parent 26992b40
......@@ -222,7 +222,7 @@ class CopyContainer(ExtensionClass.Base):
ob._postCopy(self, op=0)
OFS.subscribers.maybeCallDeprecated('manage_afterClone', ob)
OFS.subscribers.compatibilityCall('manage_afterClone', ob, ob)
notify(ObjectClonedEvent(ob))
......@@ -388,7 +388,7 @@ class CopyContainer(ExtensionClass.Base):
ob._postCopy(self, op=0)
OFS.subscribers.maybeCallDeprecated('manage_afterClone', ob)
OFS.subscribers.compatibilityCall('manage_afterClone', ob, ob)
notify(ObjectClonedEvent(ob))
......
......@@ -50,7 +50,6 @@ from OFS.event import ObjectWillBeAddedEvent
from OFS.event import ObjectWillBeRemovedEvent
import OFS.subscribers
# the name BadRequestException is relied upon by 3rd-party code
BadRequestException = BadRequest
......@@ -315,35 +314,23 @@ class ObjectManager(
if not suppress_events:
notify(ObjectAddedEvent(ob, self, id))
OFS.subscribers.maybeCallDeprecated('manage_afterAdd', ob, self)
OFS.subscribers.compatibilityCall('manage_afterAdd', ob, ob, self)
return id
def manage_afterAdd(self, item, container):
# Don't do recursion anymore, a subscriber does that.
warnings.warn(
"%s.manage_afterAdd is deprecated and will be removed in "
"Zope 2.11, you should use an IObjectAddedEvent "
"subscriber instead." % self.__class__.__name__,
DeprecationWarning, stacklevel=2)
pass
manage_afterAdd.__five_method__ = True
def manage_afterClone(self, item):
# Don't do recursion anymore, a subscriber does that.
warnings.warn(
"%s.manage_afterClone is deprecated and will be removed in "
"Zope 2.11, you should use an IObjectClonedEvent "
"subscriber instead." % self.__class__.__name__,
DeprecationWarning, stacklevel=2)
pass
manage_afterClone.__five_method__ = True
def manage_beforeDelete(self, item, container):
# Don't do recursion anymore, a subscriber does that.
warnings.warn(
"%s.manage_beforeDelete is deprecated and will be removed in "
"Zope 2.11, you should use an IObjectWillBeRemovedEvent "
"subscriber instead." % self.__class__.__name__,
DeprecationWarning, stacklevel=2)
pass
manage_beforeDelete.__five_method__ = True
def _delObject(self, id, dp=1, suppress_events=False):
......@@ -353,7 +340,7 @@ class ObjectManager(
"""
ob = self._getOb(id)
OFS.subscribers.maybeCallDeprecated('manage_beforeDelete', ob, self)
OFS.subscribers.compatibilityCall('manage_beforeDelete', ob, ob, self)
if not suppress_events:
notify(ObjectWillBeRemovedEvent(ob, self, id))
......
......@@ -61,27 +61,15 @@ class Item(Base, Resource, CopySource, App.Management.Tabs, Traversable,
isTopLevelPrincipiaApplicationObject=0
def manage_afterAdd(self, item, container):
warnings.warn(
"%s.manage_afterAdd is deprecated and will be removed in "
"Zope 2.11, you should use an IObjectAddedEvent "
"subscriber instead." % self.__class__.__name__,
DeprecationWarning, stacklevel=2)
pass
manage_afterAdd.__five_method__ = True
def manage_beforeDelete(self, item, container):
warnings.warn(
"%s.manage_beforeDelete is deprecated and will be removed in "
"Zope 2.11, you should use an IObjectWillBeRemovedEvent "
"subscriber instead." % self.__class__.__name__,
DeprecationWarning, stacklevel=2)
pass
manage_beforeDelete.__five_method__ = True
def manage_afterClone(self, item):
warnings.warn(
"%s.manage_afterClone is deprecated and will be removed in "
"Zope 2.11, you should use an IObjectClonedEvent "
"subscriber instead." % self.__class__.__name__,
DeprecationWarning, stacklevel=2)
pass
manage_afterClone.__five_method__ = True
# Direct use of the 'id' attribute is deprecated - use getId()
......
......@@ -21,6 +21,7 @@ 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
......@@ -35,36 +36,42 @@ from zope.app.location.interfaces import ISublocations
deprecatedManageAddDeleteClasses = []
def hasDeprecatedMethods(ob):
"""Do we need to call the deprecated methods?
"""
for class_ in deprecatedManageAddDeleteClasses:
if isinstance(ob, class_):
return True
return False
def compatibilityCall(method_name, *args):
"""Call a method if events have not been setup yet.
def maybeCallDeprecated(method_name, ob, *args):
"""Call a deprecated method, if the framework doesn't call it already.
This is the case for some unit tests that have not been converted to
use the component architecture.
"""
if hasDeprecatedMethods(ob):
# Already deprecated through zcml
if deprecatedManageAddDeleteClasses:
# Events initialized, don't do compatibility call
return
method = getattr(ob, method_name)
if getattr(method, '__five_method__', False):
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
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)
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)
##################################################
......@@ -98,16 +105,13 @@ def dispatchObjectWillBeMovedEvent(ob, event):
if OFS.interfaces.IObjectManager.providedBy(ob):
dispatchToSublocations(ob, event)
# Next, do the manage_beforeDelete dance
#import pdb; pdb.set_trace()
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 OFS.interfaces.IObjectManager.providedBy(ob):
dispatchToSublocations(ob, event)
......@@ -116,32 +120,33 @@ def dispatchObjectClonedEvent(ob, event):
"""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 OFS.interfaces.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.
"""
import OFS.ObjectManager # avoid circular imports
container = event.oldParent
if getattr(aq_base(ob), 'manage_beforeDelete', None) is None:
return
if container is None:
# this is an add
return
import OFS.ObjectManager # avoid circular imports
maybeWarnDeprecated(ob, 'manage_beforeDelete')
try:
ob.manage_beforeDelete(event.object, container)
ob.manage_beforeDelete(item, container)
except OFS.ObjectManager.BeforeDeleteException:
raise
except ConflictError:
......@@ -153,7 +158,10 @@ def callManageBeforeDelete(ob, event):
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)
......@@ -444,7 +444,7 @@ class BTreeFolder2Base (Persistent):
if not suppress_events:
notify(ObjectAddedEvent(ob, self, id))
OFS.subscribers.maybeCallDeprecated('manage_afterAdd', ob, self)
OFS.subscribers.compatibilityCall('manage_afterAdd', ob, ob, self)
return id
......@@ -452,7 +452,7 @@ class BTreeFolder2Base (Persistent):
def _delObject(self, id, dp=1, suppress_events=False):
ob = self._getOb(id)
OFS.subscribers.maybeCallDeprecated('manage_beforeDelete', ob, self)
OFS.subscribers.compatibilityCall('manage_beforeDelete', ob, ob, self)
if not suppress_events:
notify(ObjectWillBeRemovedEvent(ob, self, id))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment