[Zope-dev] External Method Missery
Steve Alexander
steve@cat-box.net
Wed, 12 Jul 2000 11:35:41 +0100
Chris Withers wrote:
>
> I think this is a bgu so I'll chuck it into the collector unless someone
> tells me otherwise...
>
> I have an external method called navTree (dtml-tree was too broken to
> fix in the time frame :( ) with a spec as follows:
>
> def navTree(self,start):
>
> It's called in some DTML as:
>
> <dtml-var "nav_tree(PARENTS[-2])">
>
> which is fine, unless I call it with the following:
>
> <dtml-var "nav_tree(start=PARENTS[-2])">
>
> in which case I get:
> TypeError: not enough arguments; expected 2, got 0
>
> which is not very helpful :(
>
> Any ideas?
Ok.
I debugged this by creating an external method to see what it is
actually receiving:
def navtree(*arg, **kw):
print 'navtree'
print 'arg= ', arg
print 'kw= ', kw
print
For <dtml-var "navtree(PARENTS[-1])"> we get:
navtree
arg= (<Application instance at 858ac40>,)
kw= {}
For <dtml-var "navtree(start=PARENTS[-1])"> we get:
navtree
arg= ()
kw= {'start': <Application instance at 858ac40>}
That is, no "self" argument is getting passed.
Now, I change the external method to have a "self" argument first:
def navtree(self, *arg, **kw):
print 'navtree'
print 'self=', self
print 'arg= ', arg
print 'kw= ', kw
print
For <dtml-var "navtree(PARENTS[-1])"> we get:
navtree
self= <Application instance at 858ac40>
arg= ()
kw= {}
For <dtml-var "navtree(start=PARENTS[-1])"> we get:
navtree
self= <Folder instance at 8589ea0>
arg= ()
kw= {'start': <Application instance at 858ac40>}
So, in the first case, you're not getting the current context passed in,
but you are getting it in the second case.
One more try:
def navtree(self, **kw):
print 'navtree'
print 'self=', self
print 'kw= ', kw
print
For <dtml-var "navtree(PARENTS[-1])"> we get:
navtree
self= <Application instance at 858ac40>
kw= {}
For <dtml-var "navtree(start=PARENTS[-1])"> we get:
navtree
self= <Folder instance at 8589ea0>
kw= {'start': <Application instance at 858ac40>}
Looks like it is assumed that the first non-keyword argument should be
passed as the client (ie "self").
So, you can fix your exception by giving "start" a default value:
def navTree(self,start=''):
However, you'll have to always use the keyword form of calling it:
<dtml-var "nav_tree(start=PARENTS[-2])">
Or otherwise, provide a client for it:
<dtml-var "nav_tree(this(), PARENTS[-2])">
As for why this is the case... I have other things to do this morning,
so I won't go rooting around in the DTML source just now. [ Although, it
sure is tempting :-) ]
--
Steve Alexander
Software Engineer
Cat-Box limited
http://www.cat-box.net