[Zope] dtml-var weirdness

Joseph A Knapka jknapka@earthlink.net
Mon, 18 Feb 2002 10:39:24 +0000


"Thomas B. Passin" wrote:
> 
> [Joseph A Knapka]>
> > Stupid question of the day:
> >
> > Why might the following code result in a KeyError? It does
> > in some contexts under Zope 2.5.0.
> >
> > <dtml-if expr="REQUEST.has_key('xyz')">
> > <dtml-else>
> >   <dtml-call expr="REQUEST.set('xyz','Hello world')">
> > </dtml-if>
> >
> > Sometimes the next line results in a KeyError, value 'xyz':
> >
> > <dtml-var name="xyz">
> >
> > In such cases, this works fine:
> >
> > <dtml-with REQUEST only>
> >   <dtml-var name="xyz">
> > </dtml-with>
> >
> 
> You set the property named "xyz" in the REQUEST, and you can be sure of
> referring to it if you say "REQUEST['xyz'] or "REQUEST.xyz", as in
> 
> <dtml-var "REQUEST['xyz']">

Yes, but why can I *not* be sure of referring to it by
<dtml-var xyz>? (I forgot to mention, this code appears
with a DTML document, not a method.)
 
> Note that using "expr=" is redundant - you can always omit it.

Though the Zope docs recommend against doing so, and I can
see why: <dtml-var "xyz"> vs <dtml-var xyz> have different
semantics, and are visually not easy to differentiate.

>  So your
> example could be written:
> 
>  <dtml-if "REQUEST.has_key('xyz')">
>    <dtml-else>
>        <dtml-call "REQUEST.set('xyz','Hello world')">
>  </dtml-if>
> 
> or, a bit simpler and more readable,
> 
> <dtml-if "not REQUEST.has_key('xyz')">
>    <dtml-call "REQUEST.set('xyz','Hello world')">
>  </dtml-if>
> 
> Referring to "REQUEST['xyz']"  always works.  But as long as no other
> namespace has been inserted into the mix, you can also get the value in any
> of these ways:
> 
> 1) <dtml-var "xyz">
> 2) <dtml-var xyz>
> 3) <dtml-var "_['xyz']>
> 
> That's because REQUEST properties are specially made available to its
> owner's namespace for convenience.
> 
> These last three versions all really ask for the same thing, just in
> slightly different ways:
> 
> 1) asks for a Python variable named "xyz".  Python looks for this variable
> in the namespace stack, which normally starts with the namepace of the dtml
> document containing the code (if it is in a dtml document, otherwise
> different rules apply).
>
> 2) asks Zope for a variable named "xyz".  Zope looks in its namespace stack
> to find it.  It's normally the same namespace stack that Python would be
> using, so this is equivalent to 1) in most cases.
> 
> 3) is an alternative way to ask for the same thing as 2).  It's advantage is
> that the name of the variable does not have to be known when you write the
> code - any string will do.
> 
> If the code is in a dtml method, the method does not have its own namespace.
> What namespace it uses, and therefore whether it can find the right
> variable,  depends on how it is called, thus the results can vary.  There
> have been many threads in the list about this.

Yes, I understand all that. My question, to put it very
explicitly, is this:

Since I'm checking to see whether REQUEST has a
key 'xyz', and setting it if not, then by the time we get
to the <dtml-var xyz> line, REQUEST definitely *does* have
an 'xyz' key; and since REQUEST is undoubtedly in the
namespace (right?), how can <dtml-var xyz> possibly result
in a KeyError?

Thanks,

-- Joe
"I should like to close this book by sticking out any part of my neck
 which is not yet exposed, and making a few predictions about how the
 problem of quantum gravity will in the end be solved."
 --- Physicist Lee Smolin, "Three Roads to Quantum Gravity"