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