Commit 8deb2017 authored by Jens Vagelpohl's avatar Jens Vagelpohl

- LP #142410: Do not index documents in a KeywordIndex if the document

  is missing the indexed attribute, if determining the value raises
  AttributeError, or of the indexed attribute is empty.
parent 9708c0bf
......@@ -162,6 +162,10 @@ Features Added
Bugs Fixed
++++++++++
- LP #142410: Do not index documents in a KeywordIndex if the document
is missing the indexed attribute, if determining the value raises
AttributeError, or of the indexed attribute is empty.
- LP #142590: The ``DTMLMethod`` and ``DTMLDocument`` ``manage_edit``
methods could not deal with ``TaintedString`` instances. Removed the
entirely redundant ``DTMLDocument.manage_edit`` method at the same time.
......
......@@ -70,6 +70,7 @@ class KeywordIndex(UnIndex):
try:
for kw in newKeywords:
self.insertForwardIndexEntry(kw, documentId)
if newKeywords:
self._unindex[documentId] = list(newKeywords)
except TypeError:
return 0
......@@ -83,7 +84,10 @@ class KeywordIndex(UnIndex):
rdiff = difference(newKeywords, oldKeywords)
if fdiff or rdiff:
# if we've got forward or reverse changes
if newKeywords:
self._unindex[documentId] = list(newKeywords)
else:
del self._unindex[documentId]
if fdiff:
self.unindex_objectKeywords(documentId, fdiff)
if rdiff:
......@@ -94,8 +98,13 @@ class KeywordIndex(UnIndex):
def _get_object_keywords(self, obj, attr):
newKeywords = getattr(obj, attr, ())
if safe_callable(newKeywords):
try:
newKeywords = newKeywords()
if isinstance(newKeywords, basestring): #Python 2.1 compat isinstance
except AttributeError:
return ()
if not newKeywords:
return ()
elif isinstance(newKeywords, basestring): #Python 2.1 compat isinstance
return (newKeywords,)
else:
unique = {}
......
......@@ -243,6 +243,31 @@ class TestKeywordIndex( unittest.TestCase ):
}
self._checkApply(record, values[5:7])
def test_noindexing_when_noattribute(self):
to_index = Dummy(['hello'])
self._index._index_object(10, to_index, attr='UNKNOWN')
self.failIf(self._index._unindex.get(10))
self.failIf(self._index.getEntryForObject(10))
def test_noindexing_when_raising_attribute(self):
class FauxObject:
def foo(self):
raise AttributeError
to_index = FauxObject()
self._index._index_object(10, to_index, attr='foo')
self.failIf(self._index._unindex.get(10))
self.failIf(self._index.getEntryForObject(10))
def test_value_removes(self):
to_index = Dummy(['hello'])
self._index._index_object(10, to_index, attr='foo')
self.failUnless(self._index._unindex.get(10))
to_index = Dummy('')
self._index._index_object(10, to_index, attr='foo')
self.failIf(self._index._unindex.get(10))
def test_suite():
suite = unittest.TestSuite()
......
......@@ -34,10 +34,22 @@ class IPluggableIndex(Interface):
def index_object(documentId, obj, threshold=None):
"""Index an object.
'documentId' is the integer ID of the document.
'obj' is the object to be indexed.
'threshold' is the number of words to process between committing
- ``documentId`` is the integer ID of the document.
- ``obj`` is the object to be indexed.
- ``threshold`` is the number of words to process between committing
subtransactions. If None, subtransactions are disabled.
For each name in ``getIndexSourceNames``, try to get the named
attribute from ``obj``.
- If the object does not have the attribute, do not add it to the
index for that name.
- If the attribute is a callable, call it to get the value. If
calling it raises an AttributeError, do not add it to the index.
for that name.
"""
def unindex_object(documentId):
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment