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

Jan-Wijbrand Kolman janwijbrand at gmail.com
Wed Jun 20 04:04:35 EDT 2007


On 6/19/07, Philipp von Weitershausen <philipp at weitershausen.de> wrote:
> Jan-Wijbrand Kolman wrote:
> > I'm trying to create/register a global utility by subclassing
> > grok.GlobalUtility. If I understand correctly, exactly one instance of
> > this utility class is created at registration time, right? It is this
> > instance that is returned when calling getUtility, right?
>
> Right; Right.
>
> > Now, in my case the __init__ of my utility class makes use of other
> > global utilities that are registered by a "third party" package
> > (called userschema). However, when creating the instance for my
> > utility class, the "third party" utilities are not registered (yet)
> > and thus cannot be found.
> >
> > I'm not sure I fully understand why this is the case (and thus I do
> > not see a way around it yet). I also tried to <include
> > package="userschema" ?> just before the <grok:grok package="."/>
> > directive in my package's configure.zcml, but to no avail; My global
> > utility seems always to be registered before the utilities from
> > userschema are registered.
> >
> > Maybe somebody can nudge me in the right direction with this?
>
> In general I would say you're doing it wrong. As I asserted above,
> utility's __init__ is called during registration time at which time the
> state of the component registry cannot be known. I don't think you
> should make any assumptions at that point. In particular, you shouldn't
> make any assumptions for the rest of the Python process.
>
> One of the key features of the Component Architecture is
> overrideability. We can have it by simply registering a new utility
> "over" an old one, we can do it elegantly with ZCML overrides and we can
> do it locally using local sites. Point is, to ensure this
> overrideability, there are certain sacrifices to make which can be, I
> think, summed up in two simple rules of thumb:
>
> * don't register during import time
>
> * don't look up during registration time
>
> In particular, you only want to do look-ups during request time because
> the way components are acquired may be different in each individual
> requests, thanks to local sites.
>
> "I don't have local components, they're all global utilities" you might
> say. Well, getUtility() isn't aware of that and I think you should never
> code in a way that it implicitly has to make that assumption. So,
> whenever you need those secondary utilities in your utility, get them by
> doing getUtility() each time. Might not be particularly elegant from a
> Python perspective, but it's the price to pay for flexibility.

Thanks for these insights! They certainly make sense.

I'm wondering now though how this relates to Tres' userschema package
(that I'm reusing at the moment). This package creates interfaces
(schemas) by parsing (amongst other formats) XML files. In this
process userschema-specific utilities are looked up for constructing
schema fields. I can imagine that you would not want to construct
interfaces at request time each time.

But well, I need to think about this some more (Tres, did you run into
this situation or something similar at some point when working with
userschema?).


Kind regards,
jw
-- 
Jan-Wijbrand Kolman


More information about the Grok-dev mailing list