[Zope] ZCatalog (2.3.1) won't acquire method from parent fold er?

Casey Duncan cduncan@kaivo.com
Mon, 14 May 2001 09:29:48 -0600


sean.upton@uniontrib.com wrote:
> 
> A follow-up:  After upgrading to 2.3.2, and further investigation, I have
> found I have a problem, and I have found a workaround.  However, what I have
> discovered is that the problem is not one of acquisition; rather, it is an
> issue of ZCatalog not cooperating with my DTML methods, residing on disk as
> part of my Python product.
> 
> So, in a slightly different light, here is my problem: if I use one of these
> DTML methods as an index, it has problems evaluating code because it (the
> Catalog) runs the method, but it will not successfully obtain the namespace
> of either the object I am trying to catalog / add, or the namespace of the
> acquisition parent of the newly created - just about to be indexed - object.
> The implication of this, is that while evaluating the DTML, there is a
> NameError raised for ANY call to a method within an object of the class you
> are trying to index; I did not try accessing properties, but I assume that
> they would suffer the same fate: evaluation of the DTML, being run by the
> Catalog as an agent, would fail to resolve the namespace of the object for
> which it is trying to index, and this would mean that any calls to
> methods/properties of the object from within the DTML would fail with a
> NameError, raising an exception that breaks any Catalog Aware object
> attempting to use a DTML method as a text index.

Actually it is worse than this. The problem here lies in the calling API
of DTML Methods. The client context must be passed explicitly as the
first parameter of the DTML Method in order for it to know the object it
is being called for, even if it is an instance method of a ZClass.

When the index calls your method, no parameters are passed, and the DTML
Method is too dumb to resolve its parent through self.

Workaround: Do not index against DTML Methods. Use Python Scripts, as
they can through their container binding act like true instance methods
when called blind.

> 
> My iterateText method resides as a python method BOTH in the class for the
> object I just added, and the parent folder (a custom class subclassed from
> OFS.Folder) I am adding the object to.  My searchTextWeighted (the method I
> am indexing) was a DTML method on disk, referenced with
>         searchTextWeighted = Globals.HTMLFile('dtml/searchTextWeighted',
> globals())
> 
> ...I changed this to a python method within the class, and this fixed the
> problem, but not in the way I necessarily want. What I am hoping to be able
> to do is create templates that get indexed, so that modifying an existing
> indexed 'field' does not require directly modifying the class itself, only
> the DTML methods to which the class refers to.

Solution: write a wrapper method in your class that looks for a DTML
method to index against. If it finds one then call it or a default DTML
method passing self as the client like so:

defaultSearchTextWeighted = Globals.HTMLFile('dtml/searchTextWeighted',
globals())
def searchText(self):
	"""Look for a DTML Method to call"""
	if hasattr(self, 'searchTextWeighted'):
		stw = self.searchTextWeighted
	else:
		stw = self.defaultSearchTextWeighted

	return stw(self)
> 
> Why won't ZCatalog use the namespace of the object it is attempting to index
> to run these methods, which belong to the class of those objects?  It seems
> like if it did, there would be no problem doing what I originally set out to
> do.  Is this a bug, or am I going about doing this the wrong way?
> 
> Any thoughts would be greatly appreciated.  For now, I can live with my
> workaround...
> 
> Sean
> 

hth,
-- 
| Casey Duncan
| Kaivo, Inc.
| cduncan@kaivo.com
`------------------>