[Zope-Checkins] CVS: StandaloneZODB/ZODB - PersistentMapping.py:1.13.2.2

Jeremy Hylton jeremy@zope.com
Wed, 28 Nov 2001 14:21:16 -0500


Update of /cvs-repository/StandaloneZODB/ZODB
In directory cvs.zope.org:/tmp/cvs-serv7681

Modified Files:
      Tag: StandaloneZODB-1_0-branch
	PersistentMapping.py 
Log Message:
Make new PersistentMapping work with old pickles

The old PersistentMapping used _container to hold the data.  We need
to make the current code work with objects pickled using the old code.
Unfortunately, this forces us to expose the rep of UserDict, because
__init__() won't be called when a pickled object is being loaded.

Since arbitrary attributes could be assigned to a PersistentMapping,
there is still room for trouble.  If an _container attribute was
assigned to a new PersistentMapping, __setstate__() would be confused
about whether it was an old or new mapping.  This seems almost
entirely unlikely, so assert it doesn't happen.


=== StandaloneZODB/ZODB/PersistentMapping.py 1.13.2.1 => 1.13.2.2 ===
     __super_popitem = UserDict.popitem
 
+    def __setstate__(self, state):
+        # The old PersistentMapping used _container to hold the data.
+        # We need to make the current code work with objects pickled
+        # using the old code.  Unfortunately, this forces us to expose
+        # the rep of UserDict, because __init__() won't be called when
+        # a pickled object is being loaded.
+        if state.has_key('_container'):
+            assert not state.has_key('data'), \
+                   ("object state has _container and data attributes: %s"
+                    % repr(state))
+            self.data = state['_container']
+            del state['_container']
+        for k, v in state.items():
+            self.__dict__[k] = v
+
     def __delitem__(self, key):
         self.__super_delitem(key)
         self._p_changed = 1