[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