[Zope3-dev] Missing ObjectContentModifiedEvent
Jim Fulton
jim at zope.com
Thu May 26 12:05:11 EDT 2005
This proposal is way too unpythonic IMO.
Application code shouldn't have to go through this much
machinery just to make changes.
I don't mind if some application does something like this,
but I wouldn't want to make this a standard mode of operation
for Zope 3.
If a goal is to avoid reindexing values that haven't changed,
then I would say that indexes should remember old values and
only reindex if the value hasn't changed. This would be an
optimization and thus optional.
Jim
Uwe Oestermeier wrote:
> Dieter Maurer wrote:
> As soon as you index the content, you will be interested
> to distinguish between a modification in the primary
> content and some meta data (as it has big repercussions
> on the speed of the reindexing).
>
> I agree, but perhaps we can find a compromise that fits
> all needs. I propose to use pluggable modification utilities.
>
> The container related events are already fired by only two
> functions (setitem and uncontained). If we introduce a third
> one for object modification (e.g. update or modify and an
> additional annotate if needed), we can replace these
> functions with callable utilities, which are responsible for
> performing the changes and firing the events.
> It's then up these components which events are
> actually used.
>
> Direct calls of ObjectModifiedEvents can then be marked as
> deprecated to ensure that all applications will use
> these pluggable modifiers.
>
> Regards,
> Uwe
>
> The following code should make clear what I mean:
>
> #! python
>
> import doctest, unittest, zope
> from zope.app import zapi
> from zope.interface import Interface, implements
> from zope.app.event.objectevent import ObjectModifiedEvent
> from zope.app.event.interfaces import IObjectModifiedEvent
>
> class IPluggableModifier(Interface) :
> """
> A pluggable modifier can be used to replace the
> existing modification mechanism in Zope.
> It should be used in all places where other systems
> are notified about changes.
>
> The implementation must ensure that
> at least one IObjectModifiedEvent is fired
> if an object's state has been changed.
> """
>
> def __call__(self, obj, interface, **kw) :
> """
> Performs the update and fires an IObjectModifiedEvent.
>
> It's up to the plugin which specialization of
> IObjectModifiedEvent is actually used.
>
> Returns the modified object or None if the object
> could not be modified.
> """
>
> class DefaultModifier(object) :
> """
> Implements a default behavior that mimics Zope3's current
> modification event handling.
>
> Setup :
>
> >>> from zope.component import provideUtility
> >>> provideUtility(DefaultModifier(), IPluggableModifier)
> >>> events = []
> >>> zope.event.subscribers.append(events.append)
> >>> class Sample(object) : pass
>
> Usage :
>
> >>> modify = zapi.getUtility(IPluggableModifier)
> >>> sample = Sample()
> >>> result = modify(sample, None, title='Test',
> description='Example')
> >>> result == sample
> True
> >>> IObjectModifiedEvent.providedBy(events[0])
> True
> >>> sample.title
> 'Test'
> >>> sample.description
> 'Example'
>
>
> """
> implements(IPluggableModifier)
>
> def __call__(self, obj, interface, **kw) :
> """ Modifies an object and fires an IObjectModifiedEvent. """
>
> if interface is not None :
> obj = interface(obj)
> for key, value in kw.items() :
> setattr(obj, key, value)
> zope.event.notify(ObjectModifiedEvent(obj))
> return obj
>
>
> class ValueChangedEvent(object) :
> """
> A modification event that keeps additional information about
> the used interface, the old and new values.
> """
>
> def __init__(self, object, interface, key, old_value, new_value) :
> self.object = object
> self.interface = interface
> self.key = key
> self.old_value = old_value
> self.new_value = new_value
>
> class BetterModifier(object) :
> """
> Implements a modification behavior that fires more
> informative events for more efficient versioning
> and reindexing.
>
> Setup :
>
> >>> from zope.component import provideUtility
> >>> provideUtility(BetterModifier(), IPluggableModifier)
> >>> events = []
> >>> zope.event.subscribers.append(events.append)
> >>> class Sample(object) : pass
>
> Usage :
>
> >>> modify = zapi.getUtility(IPluggableModifier)
> >>> sample = Sample()
> >>> result = modify(sample, None, title='Test',
> description='Example')
> >>> result == sample
> True
> >>> sample.title
> 'Test'
> >>> sample.description
> 'Example'
> >>> for x in events : print x.__class__.__name__
> ValueChangedEvent
> ValueChangedEvent
> ObjectModifiedEvent
>
> """
> implements(IPluggableModifier)
>
> undefined = object()
>
> def __call__(self, obj, interface, **kw) :
> """ Modifies an object and fires an IObjectModifiedEvent. """
>
> if interface is not None :
> obj = interface(obj)
> for key, value in kw.items() :
> old = getattr(obj, key, self.undefined)
> if old != value :
> setattr(obj, key, value)
> event = ValueChangedEvent(obj, interface, key, old, value)
> zope.event.notify(event)
> zope.event.notify(ObjectModifiedEvent(obj))
> return obj
>
>
> from doctest import DocTestSuite
>
> def test_suite():
> return unittest.TestSuite((
> DocTestSuite(),
> ))
>
> if __name__ == '__main__':
> unittest.main(defaultTest='test_suite')
>
>
> ------------------------------------------------------------------------
>
> _______________________________________________
> Zope3-dev mailing list
> Zope3-dev at zope.org
> Unsub: http://mail.zope.org/mailman/options/zope3-dev/jim%40zope.com
>
--
Jim Fulton mailto:jim at zope.com Python Powered!
CTO (540) 361-1714 http://www.python.org
Zope Corporation http://www.zope.com http://www.zope.org
More information about the Zope3-dev
mailing list