[Checkins] SVN: Products.ZCatalog/trunk/ Handle `TypeErrors` in the KeywordIndex if an indexed attribute is a method with required arguments.

Hanno Schlichting hannosch at hannosch.eu
Thu Apr 21 14:07:09 EDT 2011


Log message for revision 121454:
  Handle `TypeErrors` in the KeywordIndex if an indexed attribute is a method with required arguments.
  
  Protect against implicitly acquiring attributes for indexes.
  

Changed:
  U   Products.ZCatalog/trunk/CHANGES.txt
  U   Products.ZCatalog/trunk/src/Products/PluginIndexes/KeywordIndex/KeywordIndex.py
  U   Products.ZCatalog/trunk/src/Products/PluginIndexes/KeywordIndex/tests/testKeywordIndex.py
  U   Products.ZCatalog/trunk/src/Products/PluginIndexes/common/UnIndex.py

-=-
Modified: Products.ZCatalog/trunk/CHANGES.txt
===================================================================
--- Products.ZCatalog/trunk/CHANGES.txt	2011-04-21 06:27:40 UTC (rev 121453)
+++ Products.ZCatalog/trunk/CHANGES.txt	2011-04-21 18:07:09 UTC (rev 121454)
@@ -14,6 +14,11 @@
 2.13.9 (2011-04-10)
 -------------------
 
+- Handle `TypeErrors` in the KeywordIndex if an indexed attribute is a method
+  with required arguments.
+
+- Protect against implicitly acquiring attributes for indexes.
+
 - Added a floor and ceiling value to the date range index. Values outside the
   specified range will be interpreted the same way as passing `None`, i.e.
   `since the beginning of time` and `until the end of it`. This allows the

Modified: Products.ZCatalog/trunk/src/Products/PluginIndexes/KeywordIndex/KeywordIndex.py
===================================================================
--- Products.ZCatalog/trunk/src/Products/PluginIndexes/KeywordIndex/KeywordIndex.py	2011-04-21 06:27:40 UTC (rev 121453)
+++ Products.ZCatalog/trunk/src/Products/PluginIndexes/KeywordIndex/KeywordIndex.py	2011-04-21 18:07:09 UTC (rev 121454)
@@ -15,13 +15,15 @@
 
 from logging import getLogger
 
+from Acquisition import aq_base
+from App.special_dtml import DTMLFile
 from BTrees.OOBTree import difference
 from BTrees.OOBTree import OOSet
-from App.special_dtml import DTMLFile
 
 from Products.PluginIndexes.common import safe_callable
 from Products.PluginIndexes.common.UnIndex import UnIndex
 
+_marker = []
 LOG = getLogger('Zope.KeywordIndex')
 
 
@@ -90,15 +92,18 @@
         return 1
 
     def _get_object_keywords(self, obj, attr):
+        has_attr = getattr(aq_base(obj), attr, _marker)
+        if has_attr is _marker:
+            return ()
         newKeywords = getattr(obj, attr, ())
         if safe_callable(newKeywords):
             try:
                 newKeywords = newKeywords()
-            except AttributeError:
+            except (AttributeError, TypeError):
                 return ()
         if not newKeywords:
             return ()
-        elif isinstance(newKeywords, basestring): #Python 2.1 compat isinstance
+        elif isinstance(newKeywords, basestring):
             return (newKeywords,)
         else:
             unique = {}

Modified: Products.ZCatalog/trunk/src/Products/PluginIndexes/KeywordIndex/tests/testKeywordIndex.py
===================================================================
--- Products.ZCatalog/trunk/src/Products/PluginIndexes/KeywordIndex/tests/testKeywordIndex.py	2011-04-21 06:27:40 UTC (rev 121453)
+++ Products.ZCatalog/trunk/src/Products/PluginIndexes/KeywordIndex/tests/testKeywordIndex.py	2011-04-21 18:07:09 UTC (rev 121454)
@@ -253,8 +253,16 @@
         self.assertFalse(self._index._unindex.get(10))
         self.assertFalse(self._index.getEntryForObject(10))
 
+    def test_noindexing_when_raising_typeeror(self):
+        class FauxObject:
+            def foo(self, name):
+                return 'foo'
+        to_index = FauxObject()
+        self._index._index_object(10, to_index, attr='foo')
+        self.assertFalse(self._index._unindex.get(10))
+        self.assertFalse(self._index.getEntryForObject(10))
+
     def test_value_removes(self):
-        
         to_index = Dummy(['hello'])
         self._index._index_object(10, to_index, attr='foo')
         self.assertTrue(self._index._unindex.get(10))

Modified: Products.ZCatalog/trunk/src/Products/PluginIndexes/common/UnIndex.py
===================================================================
--- Products.ZCatalog/trunk/src/Products/PluginIndexes/common/UnIndex.py	2011-04-21 06:27:40 UTC (rev 121453)
+++ Products.ZCatalog/trunk/src/Products/PluginIndexes/common/UnIndex.py	2011-04-21 18:07:09 UTC (rev 121454)
@@ -17,6 +17,7 @@
 from logging import getLogger
 import sys
 
+from Acquisition import aq_base
 from BTrees.IIBTree import intersection
 from BTrees.IIBTree import IITreeSet
 from BTrees.IIBTree import IISet
@@ -264,6 +265,9 @@
         # self.id is the name of the index, which is also the name of the
         # attribute we're interested in.  If the attribute is callable,
         # we'll do so.
+        has_attr = getattr(aq_base(obj), attr, _marker)
+        if has_attr is _marker:
+            return _marker
         try:
             datum = getattr(obj, attr)
             if safe_callable(datum):



More information about the checkins mailing list