[Chandler-dev] afterChange replaced by @schema.observer (was Re: onValueChanged() replaced by 'afterChange' attribute aspect)

Phillip J. Eby pje at telecommunity.com
Thu Aug 17 12:23:56 PDT 2006


At 03:51 AM 8/17/2006 -0700, Andi Vajda wrote:
>  - I added a kludge to the schema API to update existing (usually inherited)
>    attributes with an 'afterChange' aspect value:
>       schema.afterChange(attrName=['method', 'names'])
>    until Phillip replaces this with a new decorator or somesuch.

FYI, I've just checked in the basic implementation of a new decorator, 
@schema.observer(), that replaces the use of 'afterChange'.

Instead of setting afterChange on an attribute, or calling afterChange in 
the class body, you will use @schema.observer(attr,...) to designate an 
observer method.  For example:

class PhotoMixin(pim.ContentItem):

     # ...

     photoBody = schema.One(schema.Lob)

     @schema.observer(photoBody)
     def onPhotoBodyChanged(self, attribute):
         self.processEXIF()

You can list more than one attribute in the observer() call, and you can 
refer to inherited attributes by getting them from the base class, e.g.:

class CalendarEventMixin(ContentItem):

     # ...

     @schema.observer(
         ContentItem.displayName, ContentItem.body, ContentItem.lastModified,
         startTime, duration, location, allDay, rruleset
     )
     def onEventChanged(self, name):
         """
         Maintain coherence of the various recurring items associated with self
         after an attribute has been changed.
         """
         # ...


You can of course define multiple observers in the same class, for either 
the same or different attributes.  The order in which observers will be 
called is not guaranteed.

At this point, there are some potential problems with observing base class 
attributes, due to the fact that e.g. different subclasses of ContentItem 
could define a generic method name like "onChange" and end up being called 
for the wrong attributes.  So it's probably best to use "private" method 
names (e.g. __onEventChanged) for observers, in order to minimize the 
chance that an unintended method will be called.  I'll be working with Andi 
to see if there's a way we can make collisions impossible -- and perhaps 
lower the overhead of monitoring e.g. ContentItem attributes (since every 
subclass that introduces observers on ContentItem attributes currently adds 
overhead to *every* ContentItem, not just items of that subclass).

Finally, observers on annotations aren't supported as of this 
check-in.  Support for them will come later.




More information about the chandler-dev mailing list