[Grok-dev] solving the grok.template() bug - part A of the solution

Jan-Wijbrand Kolman janwijbrand at gmail.com
Mon Jan 12 09:22:25 EST 2009

Brandon Craig Rhodes wrote:
> (snip) It looks to
> me like the rule is (or is supposed to be):
> * Grok first looks for a ``grok.context()`` right on the class.
> * Failing that, Grok does an *inheritance* search, looking through the
>   MRO of the class to see whether one of its parent classes declared a
>   ``grok.context()`` anywhere.
> * Failing that, Grok then tries to do a *lexically scoped* search,
>   looking at enclosing scopes - well, okay, it actually just looks at
>   the module, like old-fashioned Python without true lexical scoping,
>   skipping the levels in between - and seeing if a ``grok.context()``
>   directive exists up there.
> * Failing that, Grok looks in the enclosing module for one, and exactly
>   one, class that implements ``IContext``, and uses that if one is
>   found.

That's not the intended rule. The intended rule implemented by the
directive is (would be):

1) look for a grok.context on the class
2) look for a grok.context on the module of this class
3) look for a grok.context on the module of the baseclass of the class

Note 3) is enough since, if grok.context would have been used on the
baseclass, its information would've been available on the class already,
like any other inherited attribute.

> I don't want to trod on any toes, but it really looks to me like we are
> grasping for too much writer-convenience here, and not nearly enough
> reader-convenience.  We are trying, through all of these rules, to
> eliminate a few ``grok.context()`` calls that developers might have to
> make when first writing their app; but in return, readers of the code
> encountering a class without an explicit ``grok.context()`` have *three*
> places they need to look - and they have to remember the order! - in
> order to find what the context really is.  I think that this is an undue
> burden, and that we should have simpler rules that sometimes make people
> be more explicit, rather than this  complicated  stack of rules that
> sends readers hunting all over the place.

They do not need to remember any other order than normal python
inheritance order. That's the whole goal.

> Therefore I advocate that we either drop the inheritance-search, and
> have ``grok.context()`` searched for like the ``x`` in ``x.y``, or drop
> the module-level default, and have it searched for like the ``y``.  Our
> rules are already going to be more complicated because we have the
> fallback to looking for ``IContext``; I don't think we need to be adding
> a third layer.
> My vote would be removing the MRO search because (a) it sends the poor
> reader searching through module after module to read all the parent
> classes, which it's always hard to read in the right order if multiple
> inheritance is used; and (b) a module-level ``grok.context()`` kind of
> "looks like", and has a pleasant symmetry with, the search at the module
> level for an ``IContext`` class if one is present, so that if a class
> does not define ``grok.context()`` then the answer is somewhere out in
> the module one way or the other.
> Of course, this would leave in place the problem that Martijn and
> Jan-Wijbrand are working on; but since their question seemed to raise
> the larger issue, I wanted to go ahead and ask about it.  Remember... :-)
>     Explicit is better than implicit.
>     Simple is better than complex.
>     Complex is better than complicated.
>     Flat is better than nested.
>     Sparse is better than dense.
>     Readability counts.

I'm personally all for explicitly declaring the context of a component
and not falling back on implicitly found information. This however is
not the principal issue at hand here.

The principal issue is about not properly inheriting module level
information either set explicitly or implicitly. Let's keep implicit
versus explicit found information out of this discussion for now.

I could certainly live with removing CLASS_OR_MODULE level scoping (this
would affect grok.context, grok.layer and grok.viewletmanager as far as
I can see), but I do also think this is minority opinion.

I am however strongly against having to re-declare the context of a
component after I subclass from a basecomponent that has a context set
already, unless I want to override the context in the first place.


More information about the Grok-dev mailing list