[Zope] zope3, browser:addMenuItem, ZCML factory => ForbiddenAttribute: ('__call__', <...>)

KLEIN Stéphane stephane at harobed.org
Fri Sep 19 19:30:21 EDT 2008


Hi,

I had some difficulty to use "browser:addMenuItem" ZCML directive :

    <browser:addMenuItem
        factory="myproject.MyContent"
        title="MyContent"
        permission="zope.ManageContent"
    />

with my Factory :

    <utility
        factory=".mycontent.MyContentFactory"
        name="myproject.MyContent"
        permission="zope.Public"
    />

mycontent.py file :

    from zope.component.interfaces import IFactory

    ...

    class MyContentFactory(object):
        implements(IFactory)

        title = u"Create a new MyContent"
        description = u"This factory instantiates new MyContent"

        def __call__(self):
            return MyContent()

        def getInterfaces(self):
            return implementedBy(MyContent)


Now, if I try to append a MyContent object through ZMI I've this error :

  File "/home/harobed/buildout-eggs/zope.app.container-3.6.0-py2.4-linux-
i686.egg/zope/app/container/browser/adding.py", line 145, in action
    content = factory()
  File "/home/harobed/buildout-eggs/zope.security-3.5.2-py2.4-linux-
i686.egg/zope/security/checker.py", line 463, in check
    self._checker2.check(object, name)
ForbiddenAttribute: ('__call__', <myproject.mycontent.MyContentFactory 
object at 0x93f5b0c>)

Well, if I look in zope/app/container/browser/adding.py, in Adding.action 
method I see this comment :

        # TODO: If the factory wrapped by LocationProxy is already a 
Proxy,
        #       then ProxyFactory does not do the right thing and the
        #       original's checker info gets lost. No factory that was
        #       registered via ZCML and was used via addMenuItem worked
        #       here. (SR)

I think "No factory that was registered via ZCML and was used via 
addMenuItem worked here" speak about my issue ?

I've looked in zope.app.container browser test and I found this tip :

mycontent.py file fixed with the tip :

    from zope.component.interfaces import IFactory
    import zope.security.checker

    ...

    class MyContentFactory(object):
        implements(IFactory)

        title = u"Create a new MyContent"
        description = u"This factory instantiates new MyContent"

        def __init__(self):
            self.__Security_checker__ = zope.security.checker.NamesChecker
(['__call__'])

        def __call__(self):
            return MyContent()

        def getInterfaces(self):
            return implementedBy(MyContent)

With this __Security_checker__ property my issue is fixed, now I can add 
a MyContent object through ZMI.

Now, I've some comment and question about it :

* I think this tip isn't "developer friendly", what is the good method ?

* Philipp von Weitershausen's book (Web Component Development with Zope 
3) give first version of my example (without __Security_checker__ tip) 
and its example didn't working with zope 3.4 (zopeproject use). Why this 
compatibility breaking ?

Regards,
Stephane



More information about the Zope mailing list