[Zope3-dev] Re: a new zcml directive?

Jean-Marc Orliaguet jmo at ita.chalmers.se
Thu Mar 16 07:37:35 EST 2006


Martijn Faassen wrote:

> Philipp von Weitershausen wrote:
>
>> Martijn Faassen wrote:
>>
>>> I stand by my conclusions on this approach sounding simple in theory,
>>> but still being a bit harder than it should be in practice. :)
>>
>>
>> I think this is pretty simple:
>>
>> def makeAnnotationAdapter(for_, factory, key):
>>   @zope.component.adapter(for_)
>>   @zope.interface.implementer(IAnnotations)
>>   def annotationAdapter(context):
>>       annotations = IAnnotations(context)
>>       try:
>>           return annotations[key]
>>       except KeyError:
>>           ob = factory()
>>           annotations[key] = ob
>>           # to please security...
>>           zope.app.container.contained.contained(
>>               ob, context, 'foobar-whatever')
>>           return ob
>>   return annotationAdapter
>>
>> getFoo = makeAnnotationAdapter(IFoo, Foo, FOO_KEY)
>>  
>> Perhaps I'm missing something?!?
>
>
> It's not as simple as your code actually doing to what it needs to do. :)
>
> It doesn't do what it needs to do as we're not aiming to implement 
> IAnnotations here, but whatever the factory is implementing. I also 
> would like to avoid having to specify for_, as the factory should 
> already specify this information.
>
> But it's definitely simpler, if, as you do, know the zope.interface 
> and zope.component APIs, and how various things can be used as 
> decorators. I hadn't used them yet.
>
> Yesterday I had something that worked if I specified both 'for' and 
> 'implements' in ZCML; it was pretty close to what you had without the 
> decorator bits. I modified it today using your decorator idea and it 
> appears to work now:
>
> def factory(factory, name, key):
>     @zope.component.adapter(
>         list(zope.component.adaptedBy(factory))[0])
>     @zope.interface.implementer(
>         list(zope.interface.implementedBy(factory))[0])
>     def getAnnotation(context):
>         annotations = IAnnotations(context)
>         try:
>             return annotations[key]
>         except KeyError:
>             result = factory()
>             annotations[key] = result
>             zope.app.container.contained.contained(
>                 result, context, name)
>             return result
>     # Convention to make adapter introspectable
>     # (XXX where is this used? is this necessary at all?)
>     getAnnotation.factory = factory
>     return getAnnotation
>
> You can use this with the following Python code and ZCML:
>
> class MyAnnotation(Persistent):
>     implements(interfaces.IFoo)
>     adapts(interfaces.IBaz)
>
> getMyAnnotation = annotation.factory(MyAnnotation, 'my_annotation',
>                                     'some_key')
>
> <adapter factory=".module.getMyAnnotation" trusted="yes" />
>
> I hope I can still make the requirement for name and key go away.
>
> In many ways this behaves very similarly to the adapter ZCML directive 
> (as I did peek at its implementation :).
>
> I realize I may be in the minority on this particular mailing list, 
> but to me the implementation of this code wasn't "pretty simple". If 
> this is the way we are going to encourage people to build higher level 
> abstractions for definition, we may lose some of them.
>
> Regards,
>
> Martijn


Hi,
excuse me, but can someone explain what problem the pattern / workaround 
is supposed to fix, does it create and return a default annotation value 
in case an annotation key does not exist? shouldn't the annotation 
machinery be "fixed" instead to provide getAnnotation(..., default=...) ?

/JM


More information about the Zope3-dev mailing list