"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"