[Checkins] SVN: zope.app.container/branches/3.5/ backport from the trunk:

Christophe Combelles ccomb at free.fr
Mon Jun 16 12:50:32 EDT 2008


Log message for revision 87428:
  backport from the trunk:
  Fixed bug #175388 (bad btree length calculation)
  

Changed:
  U   zope.app.container/branches/3.5/CHANGES.txt
  U   zope.app.container/branches/3.5/src/zope/app/container/btree.py
  U   zope.app.container/branches/3.5/src/zope/app/container/tests/test_btree.py

-=-
Modified: zope.app.container/branches/3.5/CHANGES.txt
===================================================================
--- zope.app.container/branches/3.5/CHANGES.txt	2008-06-16 16:48:41 UTC (rev 87427)
+++ zope.app.container/branches/3.5/CHANGES.txt	2008-06-16 16:50:30 UTC (rev 87428)
@@ -12,6 +12,11 @@
     - prevent the namechooser from failing on '+', '@' and '/'
     - added tests in the namechooser
     - be sure the name chooser returns unicode
+- fixed #175388 : the setitem's size modification is now done in setitemf:
+  setting an existing item does not change the size,
+  and the event subscribers should see the new size instead of the old size.
+  Reimplemented the BTreeContainer so that it directly accesses the btree
+  methods (removed an old #TODO)
 
 3.5.3 (2007-11-09)
 ------------------

Modified: zope.app.container/branches/3.5/src/zope/app/container/btree.py
===================================================================
--- zope.app.container/branches/3.5/src/zope/app/container/btree.py	2008-06-16 16:48:41 UTC (rev 87427)
+++ zope.app.container/branches/3.5/src/zope/app/container/btree.py	2008-06-16 16:50:30 UTC (rev 87428)
@@ -11,13 +11,8 @@
 # FOR A PARTICULAR PURPOSE.
 #
 ##############################################################################
-"""This module provides a sample container implementation.
+"""This module provides a sample btree container implementation.
 
-This is primarily for testing purposes.
-
-It might be useful as a mix-in for some classes, but many classes will
-need a very different implementation.
-
 $Id$
 """
 __docformat__ = 'restructuredtext'
@@ -25,22 +20,19 @@
 from persistent import Persistent
 from BTrees.OOBTree import OOBTree
 from BTrees.Length import Length
-
-from zope.app.container.sample import SampleContainer
+from zope.interface import implements
+from zope.app.container.contained import Contained, setitem, uncontained
+from zope.app.container.interfaces import IContainer
 from zope.cachedescriptors.property import Lazy
 
-class BTreeContainer(SampleContainer, Persistent):
+class BTreeContainer(Contained, Persistent):
 
-    # implements(what my base classes implement)
+    implements(IContainer)
 
-    # TODO: It appears that BTreeContainer uses SampleContainer only to
-    # get the implementation of __setitem__().  All the other methods
-    # provided by that base class are just slower replacements for
-    # operations on the BTree itself.  It would probably be clearer to
-    # just delegate those methods directly to the btree.
-
     def __init__(self):
-        super(BTreeContainer, self).__init__()
+        # We keep the previous attribute to store the data
+        # for backward compatibility
+        self._SampleContainer__data = self._newContainerData()
         self.__len = Length()
 
     def _newContainerData(self):
@@ -50,15 +42,13 @@
 
         The value returned is a mapping object that also has get,
         has_key, keys, items, and values methods.
+        The default implementation uses an OOBTree.
         """
         return OOBTree()
 
     def __contains__(self, key):
         '''See interface IReadContainer
 
-        Reimplement this method, since has_key() returns the key if available,
-        while we expect True or False.
-
         >>> c = BTreeContainer()
         >>> "a" in c
         False
@@ -72,29 +62,53 @@
 
     @Lazy
     def _BTreeContainer__len(self):
-        import logging
-        log = logging.getLogger('zope.app.container.btree')
         l=Length()
-        ol = super(BTreeContainer, self).__len__()
+        ol = len(self._SampleContainer__data)
         if ol>0:
             l.change(ol)
         self._p_changed=True
-        log.info("Storing length of %r" % self)
         return l
 
     def __len__(self):
         return self.__len()
 
-    def __setitem__(self, key, value):
+    def _setitemf(self, key, value):
         # make sure our lazy property gets set
         l = self.__len
-        super(BTreeContainer, self).__setitem__(key, value)
+        self._SampleContainer__data[key] = value
         l.change(1)
 
+    def __iter__(self):
+        return iter(self._SampleContainer__data)
+
+    def __getitem__(self, key):
+        '''See interface `IReadContainer`'''
+        return self._SampleContainer__data[key]
+
+    def get(self, key, default=None):
+        '''See interface `IReadContainer`'''
+        return self._SampleContainer__data.get(key, default)
+        
+    def __setitem__(self, key, value):
+        setitem(self, self._setitemf, key, value)
+
     def __delitem__(self, key):
         # make sure our lazy property gets set
         l = self.__len
-        super(BTreeContainer, self).__delitem__(key)
+        uncontained(self._SampleContainer__data[key], self, key)
+        del self._SampleContainer__data[key]
         l.change(-1)
 
     has_key = __contains__
+
+    def items(self):
+        '''See interface `IReadContainer`'''
+        return self._SampleContainer__data.items()
+
+    def keys(self):
+        '''See interface `IReadContainer`'''
+        return self._SampleContainer__data.keys()
+
+    def values(self):
+        '''See interface `IReadContainer`'''
+        return self._SampleContainer__data.values()

Modified: zope.app.container/branches/3.5/src/zope/app/container/tests/test_btree.py
===================================================================
--- zope.app.container/branches/3.5/src/zope/app/container/tests/test_btree.py	2008-06-16 16:48:41 UTC (rev 87427)
+++ zope.app.container/branches/3.5/src/zope/app/container/tests/test_btree.py	2008-06-16 16:50:30 UTC (rev 87428)
@@ -40,7 +40,18 @@
         self.assertEqual(len(bc), 1)
         self.assertEqual(bc.__dict__['_BTreeContainer__len'](), 1)
 
+    def testCorrectLengthWhenAddingExistingItem(self):
+        """
+        for bug #175388
+        """
+        bc = BTreeContainer()
+        bc[u'x'] = object()
+        self.assertEqual(len(bc), 1)
+        bc[u'x'] = bc[u'x']
+        self.assertEqual(len(bc), 1)
+        self.assertEqual(list(bc), [u'x'])
 
+
 def test_suite():
     return TestSuite((
         makeSuite(TestBTreeContainer),



More information about the Checkins mailing list