[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