Phillip J. Eby wrote:
I don't think zope.interface will actually buy us anything for stamping, unless I misunderstand what stamping is used for. Here's what I suggested to Katie that our stamp implementation might look like... first, there's an abstract base class for all stamps:

Fair enough - mostly I personally wanted to make sure that either someone took a hard look at zope.interface or someone who knew enough about zope.interface took a hard look at our stamping model.

I think the next two things to worry about w.r.t. stamping are n-directional relationships and collection membership.

Our current model of stamping makes it really easy to deal with the the combined event-ness, the task-ness and the mail-ness of the same item item.. i.e. if I have the event-ness of an item (i.e. I'm using the startTime attribute) then it is really easy to get to the mail-ness just by accessing the toAddress attribute.

If we move to an attribute-based relationship, then getting from event -> task -> mail, or mail -> event -> task or whatever gets more complex.. What you describe in the code you presented has this notion that there is one primary object that has a bunch of stamps associated with it. But what if you've got one of those stamps (i.e. the sort of 'sub-object') and you need to get to one of the other stamps?

Further, if I stamp some Event as a mail message, and later REMOVE the event-ness of it.. what happens to the stamps and the relationships? How does the mail item stick around?

This comes up in thinking about collection membership i.e. if you've stamped a mail message as an event and a task, then how does the event show up in the calendar? is there a 'primary' object (that might be a mail message) that shows up, and the calendar has to look through the stamps looking for event stamps? Or can we simulate the idea that the 'event' stamp is in the current collection.

Say we want to check if an item is in a given collection. When we do a kind query for Events, we'll get a stamp, but how to we check if one of the associated stamps is in that given collection? Anyway, my point is that we should figure out how that is going to look from an API perspective, because it seems frustrating that we'll have to think about this kind of thing all over the codebase.

I think this is one of the reasons I was thinking about zope.interface and adapters - at least on some level it abstracts away the concept of a master event and sub-events - if you can just say to any e-mail message "adapt yourself into an event" and it doesn't matter who is a sub-object of what, and we can figure it out under the hood, then that seems good. (And yes we can certainly just make our own API to abstract that away, but at least that part looks an awfully lot like zope.interface!)

On the flip side I don't know enough about zope.interface to know if there is some way to deal with multiple stamps of a given kind. i.e. if I have a mail message and I want to say "give me all the Events that this item is stamped with" (as opposed to just one) or "add a new Event stamp" - if we couldn't do that, we'd be missing out on one of the key reasons we wanted to move away from identity-based stamping...

Alec


class Stamp(schema.Annotation):
    schema.kindInfo(annotates=pim.Item)

    # collection of stamp classes for each instance
    stamp_types = schema.Many(schema.Class)

    @property
    def stamps(self):
        for t in self.stamp_types:
            yield t(self)

    def add(self):
        self.stamp_types.add(self.__class__)

    def remove(self):
        self.stamp_types.remove(self.__class__)


Now you can make stamp classes like:

    class EventStamp(Stamp):
        schema.kindInfo(annotates=pim.Item)

        # event attributes here

        # event methods here


And then do things like:

     EventStamp(anItem).add()

or:
     for stamp in Stamp(anItem).stamps:
         # inspect and do stuff to the stamp object,
         # or maybe remove it

This can all be done now, without any interface registration or anything like that. Annotation classes work similarly to adaptation - if you ask for EventStamp(ob) and ob is already an EventStamp, you get an equivalent object. If it's an item or any annotation of the item, and it's a compatible type, you get an EventStamp adapter object. In any case, you then have an object with event attributes and methods (and only those attributes and methods).

To answer Grant's question, this does not actually keep Kind composition "under the covers" - it's based purely on the annotation system. Annotation attributes are normal attributes, so they should be as indexable as anything else. However, if performance considerations show that storing stamp types as a set (e.g. as shown above) is detrimental then some other way of tracking active stamps is needed.


_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

Open Source Applications Foundation "chandler-dev" mailing list
http://lists.osafoundation.org/mailman/listinfo/chandler-dev

Reply via email to