Skip to content

The plugin architecture bashout: Grok!

December 19, 2008

André Roberge made a small specification of a program to demonstrate plugin architectures, and made a set of demonstrations of different ways of making plugins. Of course, I think that the best way is to use the Zope Component Architecture. One way would be to use it directly, and register the components in python. I demonstrated that (for a simpler, but similar case) a year ago. Direct configuration does have it’s drawbacks, though as it’s done on import time, and hence may depend on import order, for example.

So, the component architecture has a configuration langauge called ZCML to counter this. Chris McDonough made an example of the calculator used by André with the component architecture and ZCML. This clearly demonstrated the drawback with ZCML. You configure the conde away from the code. Also, most people don’t like XML. So I decided to redo the example with Grok, or more specifically, grokcore.component, which is the part of Grok that handles the basic component architecture stuff.

One surprising thing is that grokcore.component uses less modules than Chris’s example does. We don’t need zope.publisher, zope.location and zope.i18n for example. This is surprising, because grokcore.component does actually use a little ZCML-stub to get started. So, how does the Grok code look? Well, the tokenizer function looks just like Chris’ of course, except that I use an adapter to look up the literal token for ints as well. I had some idea there to extend the program with support for floats, but I dodn’t get that far.

def tokenize(program):
    for number, operator in re.findall("\s*(?:(\d+)|(\*\*|.))", program):
        if number:
            yield ILiteral(int(number))
                yield component.getUtility(IOperator, operator)
            except LookupError:
                raise SyntaxError("unknown operator: %r" % operator)
    yield end_token()

I’m guessing my file looks just like Chris’ too, I haven’t actually looked at it. But instead of registering the components in ZCML, I do it in the python code. The add token originally looks like this:

class operator_add_token(object):
    """ plugin """
    lbp = 10
    def nud(self, context):
        return context.expression(100)
     def led(self, context, left):
        return left + context.expression(10)

I changed it to:

class operator_add_token(grok.GlobalUtility):
    lbp = 10
    def nud(self):
        return expression(100)
    def led(self, left):
        return left + expression(10)

Note that I’ve added the same information as the ZCML has. I say that this is an IOperator, and I name it ‘+’, and i subclass it from GlobalUtility, to tell Grok that this should be registered as a utility. So this does exactly the same as Chris ZCML based code, but without all the XML, and for some reason with less useless dependecies installed.

Grok rules! Work on 1.0 is going strong now, expect it out in the beginning of next year!


From → grok, plone, python, zope

  1. It should be mentioned here that in order to make this work, you won’t need Grok-the-web-framework, you’ll only need grokcore.component. It’s one of the building blocks of Grok and as demonstrated here, independently usable outside of Grok or Zope. See

  2. Never mind, I just realized you did mention it :). Still, it can’t hurt to say it’s independently usable and installable as an egg from PyPI.

  3. Martijn Faassen permalink

    Great! Thanks for doing this!

    I didn’t see a way for people to download this example, did I miss it? Is it going to be in the repository André Roberge so that people can find it and compare and contrast?

  4. Martijn Faassen permalink

    I’m also surprised to see that Chris needed so many dependencies for zope.configuration. Perhaps his is a setup that pulls in the extras as well or something?

    grokcore.component still pulls in quite a few libraries but most are pretty sensible to have. The only one I can’t really guess quickly what it’s needed for is zope.proxy.

    (I do think by the way we should focus on reducing dependencies needed for tests as well; I think it’s a symptom of too many inter-package dependencies as well).

Leave a Reply

Please log in using one of these methods to post your comment: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s

%d bloggers like this: