[Grok-dev] Re: Global utilities registered too early?

Martijn Faassen faassen at startifact.com
Tue Jun 19 09:06:25 EDT 2007


I don't see my own reply on this list yet and now I see yours, I think 
you already figured it out before I wrote mine. :) Your analysis is correct.

 > I have no idea how to resolve this issue and it actually presents me
 > with a quite a nasty situation... I hope someone has an idea how to
 > overcome this problem: I'd be happy to help I just do not have a clear
 > idea where to start...

[JW and I have an IRC chat in which we figure this out, I'm summarizing 

Anyway, I wrote before we need to finish Martian integration, but it 
shouldn't really be necessary, so let's imagine we do this on the 
current Grok trunk. I think the work is fairly simple after we figure 
out the basics.

The trick is to study the use of zope.configuration first. Let's look at 
the implementation of a ZCML directive, for instance the one that 
creates a global utility. We find this one in zope.component.zcml. The 
directive implementation is like this:

def utility(_context, provides=None, component=None, factory=None,
             permission=None, name=''):
     ... check and prepare ...

         discriminator = ('utility', provides, name),
         callable = handler,
         args = ('registerUtility', component, provides, name),
         discriminator = None,
         callable = provideInterface,
         args = (provides.__module__ + '.' + provides.getName(), provides)

What this directive receives is a _context argument. This is the 
zope.configuration context, and this can receive actions using the 
'action()' method.

This suggests to use a modification of the grokking infrastructure so 
that the zope.configuration context gets passed in (from the grok 

Now what defines an action?

* discriminator: something unique to this action, typically a Python 
tuple. If another action occurs somewhere that has the same 
discriminator, either a conflict is reported by zope.configuration, or 
alternatively if the zcml is organized the right way, an override.

* callable: a function that will be called when the action is actually 
performed in the end

* args: arguments to pass to this function when it's called.

This suggests the following steps:

* look at our grokkers and compare them with ZCML directive implementations.

* refactor our grokkers so that they generate one or more actions, like 
the ZCML directive does.

* potentially we can reuse the handler implementation of ZCML. If this 
is not desirable or doable, instead we create our own handler functions. 
This is a fairly straightforward refactoring step.

* we also generate the appropriate discriminators, again based by 
examining the ZCML directive implementation.

All this is work, though fairly straightforward. Someone who doesn't 
want to do the implementation yet could help in doing some of the 
analysis - determining which ZCML directives and grokkers are 
equivalent, and what the actions and discriminators look like. We can 
also spread the work of converting directives among various people.

Any volunteers?



More information about the Grok-dev mailing list