Commit 387b26ac 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 e2f04340
...@@ -11,6 +11,10 @@ http://docs.zope.org/zope2/releases/. ...@@ -11,6 +11,10 @@ http://docs.zope.org/zope2/releases/.
Bugs Fixed 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`` - LP #142590: The ``DTMLMethod`` and ``DTMLDocument`` ``manage_edit``
methods could not deal with ``TaintedString`` instances. Removed the methods could not deal with ``TaintedString`` instances. Removed the
entirely redundant ``DTMLDocument.manage_edit`` method at the same time. entirely redundant ``DTMLDocument.manage_edit`` method at the same time.
......
...@@ -70,7 +70,8 @@ class KeywordIndex(UnIndex): ...@@ -70,7 +70,8 @@ class KeywordIndex(UnIndex):
try: try:
for kw in newKeywords: for kw in newKeywords:
self.insertForwardIndexEntry(kw, documentId) self.insertForwardIndexEntry(kw, documentId)
self._unindex[documentId] = list(newKeywords) if newKeywords:
self._unindex[documentId] = list(newKeywords)
except TypeError: except TypeError:
return 0 return 0
else: else:
...@@ -83,7 +84,10 @@ class KeywordIndex(UnIndex): ...@@ -83,7 +84,10 @@ class KeywordIndex(UnIndex):
rdiff = difference(newKeywords, oldKeywords) rdiff = difference(newKeywords, oldKeywords)
if fdiff or rdiff: if fdiff or rdiff:
# if we've got forward or reverse changes # if we've got forward or reverse changes
self._unindex[documentId] = list(newKeywords) if newKeywords:
self._unindex[documentId] = list(newKeywords)
else:
del self._unindex[documentId]
if fdiff: if fdiff:
self.unindex_objectKeywords(documentId, fdiff) self.unindex_objectKeywords(documentId, fdiff)
if rdiff: if rdiff:
...@@ -94,8 +98,13 @@ class KeywordIndex(UnIndex): ...@@ -94,8 +98,13 @@ class KeywordIndex(UnIndex):
def _get_object_keywords(self, obj, attr): def _get_object_keywords(self, obj, attr):
newKeywords = getattr(obj, attr, ()) newKeywords = getattr(obj, attr, ())
if safe_callable(newKeywords): if safe_callable(newKeywords):
newKeywords = newKeywords() try:
if isinstance(newKeywords, basestring): #Python 2.1 compat isinstance newKeywords = newKeywords()
except AttributeError:
return ()
if not newKeywords:
return ()
elif isinstance(newKeywords, basestring): #Python 2.1 compat isinstance
return (newKeywords,) return (newKeywords,)
else: else:
unique = {} unique = {}
......
...@@ -243,6 +243,31 @@ class TestKeywordIndex( unittest.TestCase ): ...@@ -243,6 +243,31 @@ class TestKeywordIndex( unittest.TestCase ):
} }
self._checkApply(record, values[5:7]) 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(): def test_suite():
suite = unittest.TestSuite() suite = unittest.TestSuite()
......
...@@ -34,10 +34,22 @@ class IPluggableIndex(Interface): ...@@ -34,10 +34,22 @@ class IPluggableIndex(Interface):
def index_object(documentId, obj, threshold=None): def index_object(documentId, obj, threshold=None):
"""Index an object. """Index an object.
'documentId' is the integer ID of the document. - ``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 - ``obj`` is the object to be indexed.
subtransactions. If None, subtransactions are disabled.
- ``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): 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