[Zope3-checkins] CVS: ZODB4/src/persistence/tests - test_persistence.py:1.10

Jeremy Hylton jeremy@zope.com
Tue, 20 May 2003 15:02:09 -0400


Update of /cvs-repository/ZODB4/src/persistence/tests
In directory cvs.zope.org:/tmp/cvs-serv18494/persistence/tests

Modified Files:
	test_persistence.py 
Log Message:
Refactor persistence api to use _p_changed only to mark an object as changed.

Use _p_deactivate() to turn an object into a ghost, and use the
keyword argument force=1 if you want to turn a modified object into a
ghost.  Several occurrences of the old interface have been updated.

This refactoring uncovered a number of subtle bugs in the persistence
C API.  The two chief problems were that the load function in the C
API struct did not set the state and that the functions return 0 for
error and 1 for success.  Regardless of whether these APIs are doing
the right thing, fix the code to use them correctly.

One downside of the new API is the C objects (BTrees) that override
_p_deactivate() have to deal with all the cruft for keyword
arguments.  Since BTrees only add a single line of extra code to
_p_deactivate(), it seems useful to provide a hook in the persistence
framework for this purpose.

Also:

If an object is in the changed state, don't call register() on its
data manager a second time.

Ignore state changes that result from setstate() being called.

Don't load an object's state to call __setstate__().

In BTrees check module, if an object has an oid, print that along with
its id().



=== ZODB4/src/persistence/tests/test_persistence.py 1.9 => 1.10 ===
--- ZODB4/src/persistence/tests/test_persistence.py:1.9	Wed May  7 09:10:55 2003
+++ ZODB4/src/persistence/tests/test_persistence.py	Tue May 20 15:01:38 2003
@@ -33,13 +33,13 @@
         p.inc()
         self.assertEqual(p._p_changed, 1)
         self.assertEqual(dm.called, 1)
-        p._p_changed = None
+        p._p_deactivate()
         self.assertEqual(p._p_changed, 1)
         self.assertEqual(dm.called, 1)
         p._p_deactivate()
         self.assertEqual(p._p_changed, 1)
         self.assertEqual(dm.called, 1)
-        del p._p_changed
+        p._p_deactivate(force=True)
         # XXX deal with current cPersistence implementation
         if p._p_changed != 3:
             self.assertEqual(p._p_changed, None)
@@ -72,9 +72,9 @@
         self.assertEqual(p._p_changed, 0)
         p._p_changed = 1
         self.assertEqual(p._p_changed, 0)
-        p._p_changed = None
+        p._p_deactivate()
         self.assertEqual(p._p_changed, 0)
-        del p._p_changed
+        p._p_deactivate(force=True)
         self.assertEqual(p._p_changed, 0)
         if self.has_dict:
             self.failUnless(p.__dict__)
@@ -245,6 +245,27 @@
         self.assert_(P.__weakrefoffset__)
         self.assert_(P.__dictoffset__ < P.__weakrefoffset__)
         self.assert_(P.__basicsize__ > Persistent.__basicsize__)
+
+    def testDeactivateErrors(self):
+        p = self.klass()
+        p._p_oid = '\0\0\0\0\0\0hi'
+        dm = DM()
+        p._p_jar = dm
+        
+        def typeerr(*args, **kwargs):
+            self.assertRaises(TypeError, p, *args, **kwargs)
+
+        typeerr(1)
+        typeerr(1, 2)
+        typeerr(spam=1)
+        typeerr(spam=1, force=1)
+
+        p._p_changed = True
+        class Err(object):
+            def __nonzero__(self):
+                raise RuntimeError
+
+        typeerr(force=Err())
 
 class P(Persistent):
     def __init__(self):