[Grok-dev] Re: Global utilities registered too early?
tseaver at palladion.com
Wed Jun 20 09:59:27 EDT 2007
-----BEGIN PGP SIGNED MESSAGE-----
Jan-Wijbrand Kolman wrote:
> 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
The "eager" interface creation is due to ZCML's silly "eager" check of
dotted names. I originally had userschema create a "dummy" interface
during the parse phase, which I then replaced with the "real" interface
later, during the "execute" phase; that broke because ZCML foolishly
created bindings against the resolved-dotted-name-to-interface objects
in some cases. I therefore modified the code to *mutate* the dummy
interface during the execute phase.
However, nothing should be using the utilities during parse-time, as
they aren't yet available. I don't know how this can work for grok
until grok is modified to split "action creation" (analogous to ZCML
parsing) from "action execution".
Note that I have a "skunkworks" project which tries to integrate
userschema with grok, such that the same "static" HTML form used to
define the schema can be used to edit it. I got stuck with trying to
make it reusable, and need to find a spare couple of hours (likely
overlapping with time that Phillip or Martijn are awake ;) to get
something demo-able out the door.
Tres Seaver +1 540-429-0999 tseaver at palladion.com
Palladion Software "Excellence by Design" http://palladion.com
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org
-----END PGP SIGNATURE-----
More information about the Grok-dev