[Zodb-checkins] SVN: ZODB/branches/3.10/src/ZODB/ Fixed the last fix and fixed the test that failed to show the need for

Jim Fulton jim at zope.com
Thu Nov 17 21:22:03 UTC 2011


Log message for revision 123413:
  Fixed the last fix and fixed the test that failed to show the need for
  the fix fix.
  

Changed:
  U   ZODB/branches/3.10/src/ZODB/ConflictResolution.py
  U   ZODB/branches/3.10/src/ZODB/tests/testconflictresolution.py

-=-
Modified: ZODB/branches/3.10/src/ZODB/ConflictResolution.py
===================================================================
--- ZODB/branches/3.10/src/ZODB/ConflictResolution.py	2011-11-17 14:06:40 UTC (rev 123412)
+++ ZODB/branches/3.10/src/ZODB/ConflictResolution.py	2011-11-17 21:22:02 UTC (rev 123413)
@@ -29,7 +29,7 @@
 class BadClassName(Exception):
     pass
 
-class BadClass:
+class BadClass(object):
 
     def __init__(self, *args):
         self.args = args
@@ -123,13 +123,13 @@
         self.data = data
         # see serialize.py, ObjectReader._persistent_load
         if isinstance(data, tuple):
-            self.oid, self.klass = data
-            if isinstance(self.klass, BadClass):
+            self.oid, klass = data
+            if isinstance(klass, BadClass):
                 # We can't use the BadClass directly because, if
                 # resolution succeeds, there's no good way to pickle
                 # it.  Fortunately, a class reference in a persistent
                 # reference is allowed to be a module+name tuple.
-                self.klass = self.klass.args
+                self.data = self.oid, klass.args
         elif isinstance(data, str):
             self.oid = data
         else: # a list
@@ -140,7 +140,7 @@
             #    or persistent weakref: (oid, database_name)
             # else it is a weakref: reference_type
             if reference_type == 'm':
-                self.database_name, self.oid, self.klass = data[1]
+                self.database_name, self.oid, _ = data[1]
             elif reference_type == 'n':
                 self.database_name, self.oid = data[1]
             elif reference_type == 'w':
@@ -173,6 +173,16 @@
     def __getstate__(self):
         raise PicklingError("Can't pickle PersistentReference")
 
+
+    @property
+    def klass(self):
+        # for tests
+        data = self.data
+        if isinstance(data, tuple):
+            return data[1]
+        elif isinstance(data, list) and data[0] == 'm':
+            return data[1][2]
+
 class PersistentReferenceFactory:
 
     data = None

Modified: ZODB/branches/3.10/src/ZODB/tests/testconflictresolution.py
===================================================================
--- ZODB/branches/3.10/src/ZODB/tests/testconflictresolution.py	2011-11-17 14:06:40 UTC (rev 123412)
+++ ZODB/branches/3.10/src/ZODB/tests/testconflictresolution.py	2011-11-17 21:22:02 UTC (rev 123413)
@@ -158,6 +158,9 @@
 We often want to be able to resolve even when there are pesistent
 references to classes that can't be imported.
 
+    >>> class P(persistent.Persistent):
+    ...     pass
+
     >>> db = ZODB.DB('t.fs') # FileStorage!
     >>> storage = db.storage
     >>> conn = db.open()
@@ -166,20 +169,19 @@
     >>> oid = conn.root.x._p_oid
     >>> serial = conn.root.x._p_serial
 
-    >>> class P(persistent.Persistent):
-    ...     pass
-
-    >>> conn.root.x.a = a = P()
+    >>> conn.root.x.a = P()
     >>> transaction.commit()
+    >>> aid = conn.root.x.a._p_oid
     >>> serial1 = conn.root.x._p_serial
 
     >>> del conn.root.x.a
-    >>> conn.root.x.b = b = P()
+    >>> conn.root.x.b = P()
     >>> transaction.commit()
     >>> serial2 = conn.root.x._p_serial
 
 Bwahaha:
 
+    >>> P_aside = P
     >>> del P
 
 Now, even though we can't import P, we can still resolve the conflict:
@@ -187,10 +189,18 @@
     >>> p = storage.tryToResolveConflict(
     ...         oid, serial1, serial, storage.loadSerial(oid, serial2))
 
-    >>> p = conn._reader.getState(p)
-    >>> sorted(p), p['a'] is a, p['b'] is b
+And load the pickle:
+
+    >>> conn2 = db.open()
+    >>> P = P_aside
+    >>> p = conn2._reader.getState(p)
+    >>> sorted(p), p['a'] is conn2.get(aid), p['b'] is conn2.root.x.b
     (['a', 'b'], True, True)
 
+    >>> isinstance(p['a'], P) and isinstance(p['b'], P)
+    True
+
+
 Oooooof course, this won't work if the subobjects aren't persistent:
 
     >>> class NP:



More information about the Zodb-checkins mailing list