diff --git a/product/ERP5Type/Core/Folder.py b/product/ERP5Type/Core/Folder.py index 803ee5c137a44971598420f4be87c65bf7a81fd8..6e9d77db02d15f50b90d36012dc3ee2de358b14e 100644 --- a/product/ERP5Type/Core/Folder.py +++ b/product/ERP5Type/Core/Folder.py @@ -1616,10 +1616,10 @@ for source_klass, destination_klass in \ # special meanings in Python or Zope, and lead to strange errors # when set to an unexpected value. In fact, __implemented__ should not # be set this way, otherwise Zope crashes. - method_id_list = [x for x in source_klass.__dict__.iterkeys() - if not x.startswith('__') and callable(getattr(source_klass, x))] - for method_id in method_id_list: - if not hasattr(destination_klass, method_id): + for method_id in source_klass.__dict__: + if (method_id[:2] != '__' and method_id[:7] != '_htree_' and + callable(getattr(source_klass, method_id)) and + not hasattr(destination_klass, method_id)): setattr(destination_klass, method_id, NotImplementedClass(method_id)) # Zope 2.7 required to have methodId__roles__ defined # to know the security ot the method diff --git a/product/HBTreeFolder2/HBTreeFolder2.py b/product/HBTreeFolder2/HBTreeFolder2.py index 5419a8ed53c8f60668b4fa292f86a15379d56c18..48d9781884d0ea26068e3826e0c8036f8d94fb8c 100644 --- a/product/HBTreeFolder2/HBTreeFolder2.py +++ b/product/HBTreeFolder2/HBTreeFolder2.py @@ -358,6 +358,40 @@ class HBTreeFolder2Base (Persistent): return 0 return 1 + def _htree_iteritems(self, min=None): + # BUG: Due to bad design of HBTreeFolder2, buckets other than the root + # one must not contain both buckets & leafs. Otherwise, this method + # fails. + h = self._htree + recurse_stack = [] + try: + for sub_id in min and self.hashId(min) or ('',): + if recurse_stack: + i.next() + if type(h) is not OOBTree: + break + id += H_SEPARATOR + sub_id + if type(h.itervalues().next()) is not OOBTree: + sub_id = id + else: + id = sub_id + i = h.iteritems(sub_id) + recurse_stack.append(i) + h = h[sub_id] + except (KeyError, StopIteration): + pass + while recurse_stack: + i = recurse_stack.pop() + try: + while 1: + id, h = i.next() + if type(h) is OOBTree: + recurse_stack.append(i) + i = h.iteritems() + else: + yield id, h + except StopIteration: + pass security.declareProtected(access_contents_information, 'treeIds') diff --git a/product/HBTreeFolder2/tests/testHBTreeFolder2.py b/product/HBTreeFolder2/tests/testHBTreeFolder2.py index 420b35f58fc44231114f25ff2295bd8ea19f58d0..1c87a886b8cfbff7139f193e870d6f0462f5583f 100644 --- a/product/HBTreeFolder2/tests/testHBTreeFolder2.py +++ b/product/HBTreeFolder2/tests/testHBTreeFolder2.py @@ -12,6 +12,7 @@ # ############################################################################## +import random import unittest import ZODB import Testing @@ -194,6 +195,34 @@ class HBTreeFolder2Tests(unittest.TestCase): key.value = 'a' self.f.manage_cleanup() + def testIterItems(self): + h = HBTreeFolder2() + id_list = ['a-b', 'a-cd', + 'b', + 'd-a-b', 'd-c-d', 'd-f-a', + 'e-cd', 'e-f', + 'f'] + for i in id_list: + h._setOb(i, tuple(i)) + while 1: + for min in (None, 'a', 'a-a', 'a-b', + 'a-b-a', 'a-c', 'a-cd', + 'a-cde', 'a-d', 'aa', 'b', + 'b-c-d', 'c', 'd'): + if min: + m = min.split('-') + for i, id in enumerate(id_list): + if m <= id.split('-'): + break + else: + i = 0 + expected = [(i, tuple(i)) for i in id_list[i:]] + self.assertEqual(expected, list(h._htree_iteritems(min))) + if not id_list: + break + i = random.choice(id_list) + id_list.remove(i) + h._delOb(i) class TrojanKey: """Pretends to be a consistent, immutable, humble citizen...