pythonzopezcmlzope.component

How to make zope load my ZCML?


When I write some utility, register it and then query with getUtility it works ok:

class IOperation(Interface):
    def __call__(a, b):
        ''' performs operation on two operands '''

class Plus(object):
    implements(IOperation)
    def __call__(self, a, b):
        return a + b
plus = Plus()

class Minus(object):
    implements(IOperation)
    def __call__(self, a, b):
        return a - b
minus = Minus()


gsm = getGlobalSiteManager()

gsm.registerUtility(plus, IOperation, '+')
gsm.registerUtility(minus, IOperation, '-')

def calc(expr):
    a, op, b = expr.split()
    res = getUtility(IOperation, op)(eval(a), eval(b))
    return res

assert calc('2 + 2') == 4

Now, as I understand I could move registration of utilities to the configure.zcml, like this:

<configure xmlns="http://namespaces.zope.org/zope">

<utility
    component=".calc.plus"
    provides=".calc.IOperation"
    name="+"
    />

<utility
    component=".calc.minus"
    provides=".calc.IOperation"
    name="-"
    />

</configure>

But I don't know how to make globbal site manager read this zcml.


Solution

  • Actually, all that was needed to make this work - move parsing of zcml to another file. So, the solution now consists of three files:

    calc.py:

    from zope.interface import Interface, implements
    from zope.component import getUtility
    
    class IOperation(Interface):
        def __call__(a, b):
            ''' performs operation on two operands '''
    
    class Plus(object):
        implements(IOperation)
        def __call__(self, a, b):
            return a + b
    
    class Minus(object):
        implements(IOperation)
        def __call__(self, a, b):
            return a - b
    
    def eval(expr):
        a, op, b = expr.split()
        return getUtility(IOperation, op)(float(a), float(b))
    

    configure.zcml:

    <configure xmlns="http://namespaces.zope.org/zope">
    <include package="zope.component" file="meta.zcml" />
    
    <utility
        factory="calc.Plus"
        provides="calc.IOperation"
        name="+"
        />
    
    <utility
        factory="calc.Minus"
        provides="calc.IOperation"
        name="-"
        />
    </configure>
    

    And main.py:

    from zope.configuration import xmlconfig
    from calc import eval
    
    xmlconfig.file('configure.zcml')
    
    assert eval('2 + 2') == 4