[Zope3-dev] Re: annotations/dc and component definitions

R. David Murray rdmurray+dated+1052066695.af235f@bitdance.com
Tue, 29 Apr 2003 12:44:50 -0400


"Garrett Smith" <garrett@mojave-corp.com> wrote:

>I think my confusion comes from the fact that implementing
>IAttributesAnnotatable enables the metadata feature for content (an
>unexpected result, AFAIC).

Hmm.  I guess we have a documentation problem of some sort then.
That you find this to be a surprising result means that the
Component Architecture isn't well enough explained yet <grin>.
Forgive me if I get too basic here, but I want to try to give
the whole picture (and get corrected if *my* understanding is
wrong!)

The "metadata feature" you refer to is implemented using the
IAnnotations interface.  That is, it calls methods from the
IAnnotations interface to do its work.  When the system wants to
manipulate metadata, it gets an IAnnotations adapter for the object
it wants to annotate.  For this to succeed, either the object must
itself implement IAnnotations, or it there must be a registered
adapter that will adapt between IAnnotations and something the
object *does* implement.

Consider this snippet of zcml, from zope.app:

  <adapter 
      factory="zope.app.attributeannotations.AttributeAnnotations"
      provides="zope.app.interfaces.annotation.IAnnotations"
      for="zope.app.interfaces.annotation.IAttributeAnnotatable" />

This means that there is some code (in zope.app.attributeannotations)
that will implement the IAnnotations interface for any object that
itself implements IAttributeAnnotatable.

IAttributeAnnotatable is a very simple Interface:

  class IAttributeAnnotatable(IAnnotatable):
      """Marker indicating that annotations can be stored on an attribute

      This is a marker interface giving permission for an IAnnotations
      adapter to store data in an attribute named __annotations__.

      """

There's nothing an object actually has to *do* to implement this
Interface other than promise not to step on the attribute
'__annotations__'.  So pretty much any python object can
say that it implements this Interface (or we can say it
on behalf of some code that we've imported from third
party and don't want to modify....).

Once it does so, when the metadata system asks for an adapter
for the object to IAnnotatable, the adapter declaration
from zope.app above matches, and the object becomes enabled
for the metadata system.

So, hopefully it is no longer a surprise that implementing
IAttributeAnnotatable enables metadata.  Now, where should
this be documented?  Any thoughts on where you would have
expected to find it explained?

>I haven't fully dug into this, but from a cursory glance, it looks like
>DC metadata are stored using annotations with a namespace "key" in front
>of the metadata element name. E.g. <some DC key> + ".title" is used to
>store a component's title metadata as an object attribute.

All annotations are supposed to be stored with such a leading key,
which is normally the dotted name of the component, in order to
avoid name space collisions.  However, certain "well known" namespaces
use other identifiers, I believe.  But again, this is *not* an
"object attribute", it is an *annotation*, and how that is stored
depends on the particular IAnnotatable implementation.  In the case
of IAttributeAnnotatable, that means it is stored as a key/value
pair in a BTree stored in the __annotations__ object attribute.

>Btw, I don't mean collision in a literal/namespace-conflict sense, but
>in the sense of owndership. In some cases, I can see a component wanting
>to implement 'title' as a property. In another case, 'title' might be
>something that a user attaches to a component.

Yes, that is the problem that needs to be solved in a well defined
and easy to implement fashion.  Thanks for tackling it <grin>.

>I think schema authors are going to want to know when 'title' (this is
>just one example) should be a field and when it should be metadata.
>There are some cases in Zope 3 where I would have expected to see stuff
>like title or description as a field, but the developer decided to use
>metadata to handle it (e.g. see INewsItem).

And that may have happened because there is no good collaboration
mechanism yet.

--RDM