[Zope3-dev] Nasty bugs
Guido van Rossum
guido@python.org
Wed, 20 Mar 2002 02:52:17 -0500
I wondered, "why does the z3 root view display a broken image for
Folders?"
There's no single answer. I found several bugs. I don't know how to
fix them.
(1) The page template used,
Zope3/lib/python/Zope/App/OFS/Folder/main.pt
contains this text:
<img alt="Folder" src="../../ZMI/www/folder_icon.gif"
tal:condition="info/url"
tal:attributes="src info/url" />
which I believe is a cut-and-paste error, and should really be
<img alt="Folder" src="../../ZMI/www/folder_icon.gif"
tal:condition="info/icon"
tal:attributes="src info/icon" />
(2) When I fixed that in my copy, I got a traceback, ending in
"TypeError: len() of unsized object" in method evaluateBoolean()
in class Context in module TALES, file
Zope3/lib/python/Zope/PageTemplate/TALES.py (sorry, lost the lineno).
Casual printing of the evaluation outcome showed that it was doing
"not not None", which shouldn't trigger this error.
Printing of its type showed that it's really a wrapper for None,
and that using it in a Boolean context causes this error.
Two questions come up:
(2a) Why would None need to be wrapped?
(2b) Why can't I use a wrapped None in a Boolean context?
I can't answer (2a), but I understand (2b): the wrapper code
supports sequence and mapping methods, but not numeric methods.
Thus, when the wrapper is passed to PyObject_IsTrue(), its mapping
or sequence length method is called, which calls PyObject_Length()
on the wrapped object, which fails.
I'm not sure how to fix this, short of adding an as_number
structure to the wrapper type and only filling in the nb_nonzero
slot. I'm mailing Fred because AFAIK he wrote this code.
(I did a quick hack which catches the error in wrap_length() and
returns 0 instead, but that's obviously not right.)
It's also possible that the answer to (2a) provides the fix,
i.e. that None shouldn't have been wrapped. I didn't pursue this.
(A workaround in Python is to change evaluateBoolean() to first
compare the outcome of evaluate() to None using "==", and if so,
return 0. But that seems fixing the symptom rather than the
cause.)
(3) Looking carefully at the traceback, I noticed a strange warning
inserted, in bold, under the pt_render entry:
Warning: Macro expansion failed
Warning: exceptions.TypeError: pt_render() takes at least 2
non-keyword arguments (1 given)
Tracking this down led me to the pt_errors() method in class
PageTemplate in file
Zope3/lib/python/Zope/PageTemplate/PageTemplate.py
This is invoked during the traceback printing (via the
PageTemplateTracebackSupplement class at the end of that file, an
instance of which is stored in __traceback_supplement__ in
pt_render(), as a special magic cookie for the traceback printing
code).
Note that the warning above complains about the call to
pt_render() rather than (as it is supposed to do) showing the
template source. It looks like the signature for pt_render() has
changed; cvs log shows this entry:
----------------------------
revision 1.1.2.10
date: 2002/02/01 22:09:21; author: fdrake; state: Exp; lines: +36 -60
Simplify the PageTemplate base class, restoring the ability to
use it outside of the Zope application server.
Added some information on how to subclass to the class docstring.
Moved some of the helper classes to other modules, where they
are actually needed (for Zope-specific behavior.
----------------------------
(This is why Fred gets two copies of this mail. :-) It seems that
the pt_render() call in pt_error() is no longer valid, because it
doesn't pass the positional namespace argument.
There's one other call to pt_render() in the same file with the
same problem; the function read() also tries to expand the macro
source without supplying a namespace. I tried various ways of
supplying a default namespace but everything I tried immediately
caused an evaluation error because something was missing from the
namespace.
I could fix the bug in (1), but then the cure would be worse than
the problem (you'd get a traceback from the front page instead of a
broken image icon).
Please advise.
--Guido van Rossum (home page: http://www.python.org/~guido/)