[Grok-dev] Re: Global utilities registered too early?
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,
... 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
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.
More information about the Grok-dev