RE: [Zope] ZCatalog (2.3.1) won't acquire method from parent fold er?
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. 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. 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 -----Original Message----- From: sean.upton@uniontrib.com [mailto:sean.upton@uniontrib.com] Sent: Friday, May 11, 2001 4:44 PM To: zope@zope.org Subject: [Zope] ZCatalog (2.3.1) won't acquire method from parent folder? Running Zope 2.3.1; A ZCatalog instance that I have won't acquire a method from the parent folder it resides in; I get a NameError on the method. This is very strange. The method is called from another method whose results are supposed to be indexed. +Zope Root +Classifieds (Container, Subclassed from Folder, contains a method called iterateText(self, text, times)) Catalog (ZCatalog) I have a text index set up for a method called searchTextWeighted, which is a DTML template file on disk within a python product. Inside searchTextWeighted, I have the following DTML: <dtml-var expr="iterateText(getTitleExpanded(), 5)"> iterateText is a method of a python class that is subclassed from ZCatalog.CatalogAware and OFS.Folder.Folder: def iterateText(self, text, times): """Repeats output of text times # of lines for # of times""" result='' times=int(times) for item in range(times): result=result+text+'\n' return result I get a name error for iterateText upon trying to add a catalog-Aware class, when index_objects() is run (I just made this class Catalog-aware). This is weird, since, in terms of namespaces, iterateText is in a folder above the Catalog, and also above the item I am trying to ad, so no matter how you look at it, iterateText should be acquired, and not generate a Name Error. In testing this out, I am able to traverse to iterateText via URL in a browser with no problems. I assume that this is not related to the ZCatalog bug in 2.3.1 where the Catalog won't run a method requiring arguments. The method in the index, searchTextWeighted, passes all the arguments needed by iterateText in the DTML. So I am a bit confused here. Traceback is below. ------------------------ Traceback (innermost last): File /usr/lib/zope/lib/python/ZPublisher/Publish.py, line 223, in publish_module File /usr/lib/zope/lib/python/ZPublisher/Publish.py, line 187, in publish File /usr/lib/zope/lib/python/Zope/__init__.py, line 221, in zpublisher_exception_hook File /usr/lib/zope/lib/python/ZPublisher/Publish.py, line 171, in publish File /usr/lib/zope/lib/python/ZPublisher/mapply.py, line 160, in mapply (Object: manage_addAdItem) File /usr/lib/zope/lib/python/ZPublisher/Publish.py, line 112, in call_object (Object: manage_addAdItem) File /usr/lib/zope/lib/python/Products/DailyClassifieds/item.py, line 251, in manage_addAdItem File /usr/lib/zope/lib/python/OFS/ObjectManager.py, line 302, in _setObject (Object: Traversable) File /usr/lib/zope/lib/python/Products/ZCatalog/CatalogAwareness.py, line 114, in manage_afterAdd (Object: CatalogAware) File /usr/lib/zope/lib/python/Products/ZCatalog/CatalogAwareness.py, line 184, in index_object (Object: CatalogAware) File /usr/lib/zope/lib/python/Products/ZCatalog/ZCatalog.py, line 429, in catalog_object (Object: Traversable) File /usr/lib/zope/lib/python/Products/ZCatalog/Catalog.py, line 448, in catalogObject File /usr/lib/zope/lib/python/SearchIndex/UnTextIndex.py, line 323, in index_object File /usr/lib/zope/lib/python/App/special_dtml.py, line 127, in __call__ (Object: searchTextWeighted) File /usr/lib/zope/lib/python/DocumentTemplate/DT_String.py, line 538, in __call__ (Object: searchTextWeighted) File /usr/lib/zope/lib/python/DocumentTemplate/DT_Util.py, line 334, in eval (Object: iterateText(getTitleExpanded(), 5)) (Info: iterateText) File <string>, line 0, in ? NameError: (see above) ---------------------- Sean ========================= Sean Upton Senior Programmer/Analyst SignOnSanDiego.com The San Diego Union-Tribune 619.718.5241 sean.upton@uniontrib.com ========================= _______________________________________________ Zope maillist - Zope@zope.org http://lists.zope.org/mailman/listinfo/zope ** No cross posts or HTML encoding! ** (Related lists - http://lists.zope.org/mailman/listinfo/zope-announce http://lists.zope.org/mailman/listinfo/zope-dev )
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 `------------------>
participants (2)
-
Casey Duncan -
sean.upton@uniontrib.com