[Checkins] SVN: persistent/trunk/ Match behavior of C Persistent: tests pass both ways.

Tres Seaver tseaver at palladion.com
Tue Feb 22 19:33:44 EST 2011


Log message for revision 120525:
  Match behavior of C Persistent:  tests pass both ways.

Changed:
  U   persistent/trunk/buildout.cfg
  U   persistent/trunk/persistent/pyPersistence.py
  U   persistent/trunk/persistent/tests/test_pyPersistence.py
  U   persistent/trunk/setup.py

-=-
Modified: persistent/trunk/buildout.cfg
===================================================================
--- persistent/trunk/buildout.cfg	2011-02-23 00:32:20 UTC (rev 120524)
+++ persistent/trunk/buildout.cfg	2011-02-23 00:33:43 UTC (rev 120525)
@@ -2,8 +2,14 @@
 develop = . 
 parts =
     test
+    scripts
 
 [test]
 recipe = zc.recipe.testrunner
 eggs =
     persistent
+
+[scripts]
+recipe = zc.recipe.egg
+eggs = persistent [test]
+interpreter = py

Modified: persistent/trunk/persistent/pyPersistence.py
===================================================================
--- persistent/trunk/persistent/pyPersistence.py	2011-02-23 00:32:20 UTC (rev 120524)
+++ persistent/trunk/persistent/pyPersistence.py	2011-02-23 00:33:43 UTC (rev 120525)
@@ -94,13 +94,14 @@
         return self.__jar
 
     def _set_jar(self, value):
-        if value is self.__jar:
-            return
         if self.__jar is not None:
-            raise ValueError('Already assigned a data manager')
-        if not IPersistentDataManager.providedBy(value):
-            raise ValueError('Not a data manager: %s' % value)
-        self.__jar = value
+            if self.__jar != value:
+                raise ValueError('Already assigned a data manager')
+        else:
+            if not IPersistentDataManager.providedBy(value):
+                raise ValueError('Not a data manager: %s' % value)
+            self.__jar = value
+            self.__flags = 0
 
     _p_jar = property(_get_jar, _set_jar)
 
@@ -132,11 +133,10 @@
         return _INITIAL_SERIAL
 
     def _set_serial(self, value):
-        if value is not None:
-            if not isinstance(value, SERIAL_TYPE):
-                raise ValueError('Invalid SERIAL type: %s' % value)
-            if len(value) != 8:
-                raise ValueError('SERIAL must be 8 octets')
+        if not isinstance(value, SERIAL_TYPE):
+            raise ValueError('Invalid SERIAL type: %s' % value)
+        if len(value) != 8:
+            raise ValueError('SERIAL must be 8 octets')
         self.__serial = value
 
     def _del_serial(self):
@@ -154,7 +154,7 @@
 
     def _set_changed(self, value):
         if self.__flags is None:
-            if value is not None:
+            if value:
                 self._p_activate()
                 self._p_set_changed_flag(value)
         else:
@@ -209,7 +209,7 @@
     def _get_sticky(self):
         if self.__flags is None:
             return False
-        return self.__flags & _STICKY
+        return bool(self.__flags & _STICKY)
     def _set_sticky(self, value):
         if self.__flags is None:
             raise ValueError('Ghost')
@@ -226,13 +226,11 @@
             return 'unsaved'
         if self.__flags is None:
             return 'ghost'
-        if self.__flags & _CHANGED:
-            result = 'changed'
-        else:
-            result = 'saved'
         if self.__flags & _STICKY:
-            return '%s (sticky)' % result
-        return result
+            return 'sticky'
+        if self.__flags & _CHANGED:
+            return 'changed'
+        return 'saved'
 
     _p_status = property(_get_status)
 
@@ -275,8 +273,6 @@
             if _OGA(self, '_Persistent__flags') is None:
                 _OGA(self, '_p_activate')()
             _OGA(self, '_p_accessed')()
-        object.__delattr__(self, name)
-        if not special_name:
             before = _OGA(self, '_Persistent__flags')
             after = before | _CHANGED
             if before != after:
@@ -284,6 +280,7 @@
                 if (_OGA(self, '_Persistent__jar') is not None and
                     _OGA(self, '_Persistent__oid') is not None):
                     _OGA(self, '_p_register')()
+        object.__delattr__(self, name)
 
     def __getstate__(self):
         """ See IPersistent.
@@ -293,7 +290,7 @@
             return dict([x for x in idict.items()
                             if not x[0].startswith('_p_') and
                                not x[0].startswith('_v_')])
-        return ()
+        return None
 
     def __setstate__(self, state):
         """ See IPersistent.
@@ -303,7 +300,7 @@
             idict.clear()
             idict.update(state)
         else:
-            if state != ():
+            if state != None:
                 raise ValueError('No state allowed on base Persistent class')
 
     def __reduce__(self):
@@ -323,16 +320,15 @@
     def _p_deactivate(self):
         """ See IPersistent.
         """
-        if self.__flags is not None and not self.__flags & _CHANGED:
+        if self.__flags is not None and not self.__flags:
             self._p_invalidate()
 
     def _p_invalidate(self):
         """ See IPersistent.
         """
         if self.__jar is not None:
-            if self.__flags is not None and self.__flags & _STICKY:
-                raise ValueError('Sticky')
-            self.__flags = None
+            if self.__flags is not None:
+                self.__flags = None
             idict = getattr(self, '__dict__', None)
             if idict is not None:
                 idict.clear()

Modified: persistent/trunk/persistent/tests/test_pyPersistence.py
===================================================================
--- persistent/trunk/persistent/tests/test_pyPersistence.py	2011-02-23 00:32:20 UTC (rev 120524)
+++ persistent/trunk/persistent/tests/test_pyPersistence.py	2011-02-23 00:33:43 UTC (rev 120525)
@@ -13,12 +13,8 @@
 ##############################################################################
 import unittest
 
-class PersistentTests(unittest.TestCase):
+class _Persistent_Base(object):
 
-    def _getTargetClass(self):
-        from persistent.pyPersistence import Persistent
-        return Persistent
-
     def _makeOne(self, *args, **kw):
         return self._getTargetClass()(*args, **kw)
 
@@ -26,24 +22,19 @@
         from zope.interface import implements
         from persistent.interfaces import IPersistentDataManager
 
-        class _Cache(object):
-            def __init__(self):
-                self._mru = []
-            def mru(self, oid):
-                self._mru.append(oid)
-
         class _Jar(object):
             implements(IPersistentDataManager)
             def __init__(self):
                 self._loaded = []
                 self._registered = []
-                self._cache = _Cache()
             def setstate(self, obj):
                 self._loaded.append(obj._p_oid)
             def register(self, obj):
                 self._registered.append(obj._p_oid)
 
-        return _Jar()
+        jar = _Jar()
+        jar._cache = self._makeCache(jar)
+        return jar
 
     def _makeOneWithJar(self, klass=None):
         from persistent.pyPersistence import _makeOctets
@@ -53,8 +44,7 @@
         else:
             inst = self._makeOne()
         jar = self._makeJar()
-        inst._p_jar = jar
-        inst._p_oid = OID
+        jar._cache.new_ghost(OID, inst) # assigns _p_jar, _p_oid
         return inst, jar, OID
 
     def test_class_conforms_to_IPersistent(self):
@@ -77,29 +67,23 @@
         self.assertEqual(inst._p_sticky, False)
         self.assertEqual(inst._p_status, 'unsaved')
 
-    def test_assign_p_jar_w_invalid_jar(self):
-        inst = self._makeOne()
-        def _test():
-            inst._p_jar = object()
-        self.assertRaises(ValueError, _test)
-
     def test_assign_p_jar_w_new_jar(self):
-        inst = self._makeOne()
-        inst._p_jar = self._makeJar()
-        jar = self._makeJar()
+        inst, jar, OID = self._makeOneWithJar()
+        new_jar = self._makeJar()
         def _test():
-            inst._p_jar = jar
+            inst._p_jar = new_jar
         self.assertRaises(ValueError, _test)
 
     def test_assign_p_jar_w_valid_jar(self):
         jar = self._makeJar()
         inst = self._makeOne()
         inst._p_jar = jar
+        self.assertEqual(inst._p_status, 'saved')
         self.failUnless(inst._p_jar is jar)
         inst._p_jar = jar # reassign only to same DM
 
     def test_assign_p_oid_w_invalid_oid(self):
-        inst = self._makeOne()
+        inst, jar, OID = self._makeOneWithJar()
         def _test():
             inst._p_oid = object()
         self.assertRaises(ValueError, _test)
@@ -123,13 +107,10 @@
 
     def test_assign_p_oid_w_new_oid_w_jar(self):
         from persistent.pyPersistence import _makeOctets
-        OID1 = _makeOctets('\x01' * 8)
-        OID2 = _makeOctets('\x02' * 8)
-        inst = self._makeOne()
-        inst._p_oid = OID1
-        inst._p_jar = self._makeJar()
+        inst, jar, OID = self._makeOneWithJar()
+        new_OID = _makeOctets('\x02' * 8)
         def _test():
-            inst._p_oid = OID2
+            inst._p_oid = new_OID
         self.assertRaises(ValueError, _test)
 
     def test_delete_p_oid_wo_jar(self):
@@ -141,11 +122,7 @@
         self.assertEqual(inst._p_oid, None)
 
     def test_delete_p_oid_w_jar(self):
-        from persistent.pyPersistence import _makeOctets
-        OID = _makeOctets('\x01' * 8)
-        inst = self._makeOne()
-        inst._p_oid = OID
-        inst._p_jar = self._makeJar()
+        inst, jar, OID = self._makeOneWithJar()
         def _test():
             del inst._p_oid
         self.assertRaises(ValueError, _test)
@@ -156,6 +133,12 @@
             inst._p_serial = object()
         self.assertRaises(ValueError, _test)
 
+    def test_assign_p_serial_w_None(self):
+        inst = self._makeOne()
+        def _test():
+            inst._p_serial = None
+        self.assertRaises(ValueError, _test)
+
     def test_assign_p_serial_too_short(self):
         inst = self._makeOne()
         def _test():
@@ -170,13 +153,10 @@
 
     def test_assign_p_serial_w_valid_serial(self):
         from persistent.pyPersistence import _makeOctets
-        from persistent.pyPersistence import _INITIAL_SERIAL
         SERIAL = _makeOctets('\x01' * 8)
         inst = self._makeOne()
         inst._p_serial = SERIAL 
         self.assertEqual(inst._p_serial, SERIAL)
-        inst._p_serial = None
-        self.assertEqual(inst._p_serial, _INITIAL_SERIAL)
 
     def test_delete_p_serial(self):
         from persistent.pyPersistence import _makeOctets
@@ -194,6 +174,7 @@
 
     def test_query_p_changed_ghost(self):
         inst, jar, OID = self._makeOneWithJar()
+        inst._p_deactivate()
         self.assertEqual(inst._p_changed, None)
 
     def test_query_p_changed_saved(self):
@@ -224,6 +205,7 @@
 
     def test_assign_p_changed_none_from_ghost(self):
         inst, jar, OID = self._makeOneWithJar()
+        inst._p_deactivate()
         inst._p_changed = None
         self.assertEqual(inst._p_status, 'ghost')
         self.assertEqual(list(jar._loaded), [])
@@ -231,6 +213,7 @@
 
     def test_assign_p_changed_true_from_ghost(self):
         inst, jar, OID = self._makeOneWithJar()
+        inst._p_deactivate()
         inst._p_changed = True
         self.assertEqual(inst._p_status, 'changed')
         self.assertEqual(list(jar._loaded), [OID])
@@ -238,9 +221,10 @@
 
     def test_assign_p_changed_false_from_ghost(self):
         inst, jar, OID = self._makeOneWithJar()
+        inst._p_deactivate()
         inst._p_changed = False
-        self.assertEqual(inst._p_status, 'saved')
-        self.assertEqual(list(jar._loaded), [OID])
+        self.assertEqual(inst._p_status, 'ghost') # ??? this is what C does
+        self.assertEqual(list(jar._loaded), [])
         self.assertEqual(list(jar._registered), [])
 
     def test_assign_p_changed_none_from_saved(self):
@@ -254,10 +238,11 @@
 
     def test_assign_p_changed_true_from_saved(self):
         inst, jar, OID = self._makeOneWithJar()
-        inst._p_activate()
+        inst._p_activate() # XXX
+        jar._loaded[:] = []
         inst._p_changed = True
         self.assertEqual(inst._p_status, 'changed')
-        self.assertEqual(list(jar._loaded), [OID])
+        self.assertEqual(list(jar._loaded), [])
         self.assertEqual(list(jar._registered), [OID])
 
     def test_assign_p_changed_false_from_saved(self):
@@ -305,11 +290,13 @@
 
     def test_assign_p_changed_none_when_sticky(self):
         inst, jar, OID = self._makeOneWithJar()
+        inst._p_activate() # XXX
         inst._p_changed = False
         inst._p_sticky = True
-        def _test():
-            inst._p_changed = None
-        self.assertRaises(ValueError, _test)
+        inst._p_changed = None
+        self.assertEqual(inst._p_status, 'sticky')
+        self.assertEqual(inst._p_changed, False)
+        self.assertEqual(inst._p_sticky, True)
 
     def test_delete_p_changed_from_unsaved(self):
         inst = self._makeOne()
@@ -327,6 +314,7 @@
 
     def test_delete_p_changed_from_ghost(self):
         inst, jar, OID = self._makeOneWithJar()
+        inst._p_deactivate()
         del inst._p_changed
         self.assertEqual(inst._p_status, 'ghost')
         self.assertEqual(list(jar._loaded), [])
@@ -355,32 +343,38 @@
 
     def test_delete_p_changed_when_sticky(self):
         inst, jar, OID = self._makeOneWithJar()
+        inst._p_activate() # XXX
         inst._p_changed = False
         inst._p_sticky = True
-        def _test():
-            del inst._p_changed
-        self.assertRaises(ValueError, _test)
+        del inst._p_changed
+        self.assertEqual(inst._p_status, 'ghost')
+        self.assertEqual(inst._p_changed, None)
+        self.assertEqual(inst._p_sticky, False)
 
     def test_assign_p_sticky_true_when_ghost(self):
-        inst = self._makeOne()
+        inst, jar, OID = self._makeOneWithJar()
+        inst._p_deactivate() # XXX
         def _test():
             inst._p_sticky = True
         self.assertRaises(ValueError, _test)
 
     def test_assign_p_sticky_false_when_ghost(self):
-        inst = self._makeOne()
+        inst, jar, OID = self._makeOneWithJar()
+        inst._p_deactivate() # XXX
         def _test():
             inst._p_sticky = False
         self.assertRaises(ValueError, _test)
 
     def test_assign_p_sticky_true_non_ghost(self):
         inst, jar, OID = self._makeOneWithJar()
+        inst._p_activate() # XXX
         inst._p_changed = False
         inst._p_sticky = True
         self.failUnless(inst._p_sticky)
 
     def test_assign_p_sticky_false_non_ghost(self):
         inst, jar, OID = self._makeOneWithJar()
+        inst._p_activate() # XXX
         inst._p_changed = False
         inst._p_sticky = False
         self.failIf(inst._p_sticky)
@@ -391,6 +385,7 @@
 
     def test__p_status_ghost(self):
         inst, jar, OID = self._makeOneWithJar()
+        inst._p_deactivate()
         self.assertEqual(inst._p_status, 'ghost')
 
     def test__p_status_changed(self):
@@ -401,21 +396,24 @@
     def test__p_status_changed_sticky(self):
         # 'sticky' is not a state, but a separate flag.
         inst, jar, OID = self._makeOneWithJar()
+        inst._p_activate()
         inst._p_changed = True
         inst._p_sticky = True
-        self.assertEqual(inst._p_status, 'changed (sticky)')
+        self.assertEqual(inst._p_status, 'sticky')
 
     def test__p_status_saved(self):
         inst, jar, OID = self._makeOneWithJar()
+        inst._p_activate() # XXX
         inst._p_changed = False
         self.assertEqual(inst._p_status, 'saved')
 
     def test__p_status_saved_sticky(self):
         # 'sticky' is not a state, but a separate flag.
         inst, jar, OID = self._makeOneWithJar()
+        inst._p_activate()
         inst._p_changed = False
         inst._p_sticky = True
-        self.assertEqual(inst._p_status, 'saved (sticky)')
+        self.assertEqual(inst._p_status, 'sticky')
 
     def test__p_mtime_no_serial(self):
         inst = self._makeOne()
@@ -436,6 +434,7 @@
 
     def test__p_state_ghost(self):
         inst, jar, OID = self._makeOneWithJar()
+        inst._p_deactivate()
         self.assertEqual(inst._p_state, -1)
 
     def test__p_state_changed(self):
@@ -446,18 +445,21 @@
     def test__p_state_changed_sticky(self):
         # 'sticky' is not a state, but a separate flag.
         inst, jar, OID = self._makeOneWithJar()
+        inst._p_activate()
         inst._p_changed = True
         inst._p_sticky = True
         self.assertEqual(inst._p_state, 2)
 
     def test__p_state_saved(self):
         inst, jar, OID = self._makeOneWithJar()
+        inst._p_activate() # XXX
         inst._p_changed = False
         self.assertEqual(inst._p_state, 0)
 
     def test__p_state_saved_sticky(self):
         # 'sticky' is not a state, but a separate flag.
         inst, jar, OID = self._makeOneWithJar()
+        inst._p_activate()
         inst._p_changed = False
         inst._p_sticky = True
         self.assertEqual(inst._p_state, 2)
@@ -489,18 +491,18 @@
                  '_p_status',
                 ]
         inst, jar, OID = self._makeOneWithJar()
-        jar._cache._mru = []
+        self._clearMRU(jar)
         for name in NAMES:
             getattr(inst, name)
-        self.assertEqual(jar._cache._mru, [])
+        self._checkMRU(jar, [])
 
     def test___getattribute__special_name(self):
         from persistent.pyPersistence import SPECIAL_NAMES
         inst, jar, OID = self._makeOneWithJar()
-        jar._cache._mru = []
+        self._clearMRU(jar)
         for name in SPECIAL_NAMES:
             getattr(inst, name, None)
-        self.assertEqual(jar._cache._mru, [])
+        self._checkMRU(jar, [])
 
     def test___getattribute__normal_name_from_unsaved(self):
         class Derived(self._getTargetClass()):
@@ -512,32 +514,34 @@
         class Derived(self._getTargetClass()):
             normal = 'value'
         inst, jar, OID = self._makeOneWithJar(Derived)
-        jar._cache._mru = []
+        inst._p_deactivate()
+        self._clearMRU(jar)
         self.assertEqual(getattr(inst, 'normal', None), 'value')
-        self.assertEqual(jar._cache._mru, [OID])
+        self._checkMRU(jar, [OID])
 
     def test___getattribute__normal_name_from_saved(self):
         class Derived(self._getTargetClass()):
             normal = 'value'
         inst, jar, OID = self._makeOneWithJar(Derived)
         inst._p_changed = False
-        jar._cache._mru = []
+        self._clearMRU(jar)
         self.assertEqual(getattr(inst, 'normal', None), 'value')
-        self.assertEqual(jar._cache._mru, [OID])
+        self._checkMRU(jar, [OID])
 
     def test___getattribute__normal_name_from_changed(self):
         class Derived(self._getTargetClass()):
             normal = 'value'
         inst, jar, OID = self._makeOneWithJar(Derived)
         inst._p_changed = True
-        jar._cache._mru = []
+        self._clearMRU(jar)
         self.assertEqual(getattr(inst, 'normal', None), 'value')
-        self.assertEqual(jar._cache._mru, [OID])
+        self._checkMRU(jar, [OID])
 
     def test___setattr___p__names(self):
         from persistent.pyPersistence import _makeOctets
         SERIAL = _makeOctets('\x01' * 8)
         inst, jar, OID = self._makeOneWithJar()
+        inst._p_activate()
         NAMES = [('_p_jar', jar),
                  ('_p_oid', OID),
                  ('_p_changed', False),
@@ -545,19 +549,19 @@
                  ('_p_estimated_size', 0),
                  ('_p_sticky', False),
                 ]
-        jar._cache._mru = []
+        self._clearMRU(jar)
         for name, value in NAMES:
             setattr(inst, name, value)
-        self.assertEqual(jar._cache._mru, [])
+        self._checkMRU(jar, [])
 
     def test___setattr___v__name(self):
         class Derived(self._getTargetClass()):
             pass
         inst, jar, OID = self._makeOneWithJar(Derived)
-        jar._cache._mru = []
+        self._clearMRU(jar)
         inst._v_foo = 'bar'
         self.assertEqual(inst._p_status, 'saved')
-        self.assertEqual(jar._cache._mru, [])
+        self._checkMRU(jar, [])
 
     def test___setattr__normal_name_from_unsaved(self):
         class Derived(self._getTargetClass()):
@@ -571,9 +575,10 @@
         class Derived(self._getTargetClass()):
             normal = 'before'
         inst, jar, OID = self._makeOneWithJar(Derived)
-        jar._cache._mru = []
+        inst._p_deactivate()
+        self._clearMRU(jar)
         setattr(inst, 'normal', 'after')
-        self.assertEqual(jar._cache._mru, [OID])
+        self._checkMRU(jar, [OID])
         self.assertEqual(jar._registered, [OID])
         self.assertEqual(getattr(inst, 'normal', None), 'after')
         self.assertEqual(inst._p_status, 'changed')
@@ -583,9 +588,9 @@
             normal = 'before'
         inst, jar, OID = self._makeOneWithJar(Derived)
         inst._p_changed = False
-        jar._cache._mru = []
+        self._clearMRU(jar)
         setattr(inst, 'normal', 'after')
-        self.assertEqual(jar._cache._mru, [OID])
+        self._checkMRU(jar, [OID])
         self.assertEqual(jar._registered, [OID])
         self.assertEqual(getattr(inst, 'normal', None), 'after')
         self.assertEqual(inst._p_status, 'changed')
@@ -595,10 +600,10 @@
             normal = 'before'
         inst, jar, OID = self._makeOneWithJar(Derived)
         inst._p_changed = True
-        jar._cache._mru = []
+        self._clearMRU(jar)
         jar._registered = []
         setattr(inst, 'normal', 'after')
-        self.assertEqual(jar._cache._mru, [OID])
+        self._checkMRU(jar, [OID])
         self.assertEqual(jar._registered, [])
         self.assertEqual(getattr(inst, 'normal', None), 'after')
         self.assertEqual(inst._p_status, 'changed')
@@ -608,11 +613,11 @@
                  '_p_serial',
                 ]
         inst, jar, OID = self._makeOneWithJar()
-        jar._cache._mru = []
+        self._clearMRU(jar)
         jar._registered = []
         for name in NAMES:
             delattr(inst, name)
-        self.assertEqual(jar._cache._mru, [])
+        self._checkMRU(jar, [])
         self.assertEqual(jar._registered, [])
 
     def test___delattr__normal_name_from_unsaved(self):
@@ -627,13 +632,15 @@
     def test___delattr__normal_name_from_ghost(self):
         class Derived(self._getTargetClass()):
             normal = 'before'
-            def __init__(self):
-                self.__dict__['normal'] = 'after'
         inst, jar, OID = self._makeOneWithJar(Derived)
-        jar._cache._mru = []
+        inst._p_deactivate()
+        self._clearMRU(jar)
         jar._registered = []
-        delattr(inst, 'normal')
-        self.assertEqual(jar._cache._mru, [OID])
+        def _test():
+            delattr(inst, 'normal')
+        self.assertRaises(AttributeError, _test)
+        self.assertEqual(inst._p_status, 'changed') # ??? this is what C does
+        self._checkMRU(jar, [OID])
         self.assertEqual(jar._registered, [OID])
         self.assertEqual(getattr(inst, 'normal', None), 'before')
 
@@ -644,10 +651,10 @@
                 self.__dict__['normal'] = 'after'
         inst, jar, OID = self._makeOneWithJar(Derived)
         inst._p_changed = False
-        jar._cache._mru = []
+        self._clearMRU(jar)
         jar._registered = []
         delattr(inst, 'normal')
-        self.assertEqual(jar._cache._mru, [OID])
+        self._checkMRU(jar, [OID])
         self.assertEqual(jar._registered, [OID])
         self.assertEqual(getattr(inst, 'normal', None), 'before')
 
@@ -658,16 +665,16 @@
                 self.__dict__['normal'] = 'after'
         inst, jar, OID = self._makeOneWithJar(Derived)
         inst._p_changed = True
-        jar._cache._mru = []
+        self._clearMRU(jar)
         jar._registered = []
         delattr(inst, 'normal')
-        self.assertEqual(jar._cache._mru, [OID])
+        self._checkMRU(jar, [OID])
         self.assertEqual(jar._registered, [])
         self.assertEqual(getattr(inst, 'normal', None), 'before')
 
     def test___getstate__(self):
         inst = self._makeOne()
-        self.assertEqual(inst.__getstate__(), ())
+        self.assertEqual(inst.__getstate__(), None)
 
     def test___getstate___derived_w_dict(self):
         class Derived(self._getTargetClass()):
@@ -680,12 +687,13 @@
 
     def test___setstate___empty(self):
         inst = self._makeOne()
-        inst.__setstate__(()) # doesn't raise, but doesn't change anything
+        inst.__setstate__(None) # doesn't raise, but doesn't change anything
 
     def test___setstate___nonempty(self):
         from persistent.pyPersistence import _INITIAL_SERIAL
         inst = self._makeOne()
-        self.assertRaises(ValueError, inst.__setstate__, {'bogus': 1})
+        self.assertRaises((ValueError, TypeError),
+                           inst.__setstate__, {'bogus': 1})
         self.assertEqual(inst._p_jar, None)
         self.assertEqual(inst._p_oid, None)
         self.assertEqual(inst._p_serial, _INITIAL_SERIAL)
@@ -706,7 +714,7 @@
         first, second, third = inst.__reduce__()
         self.failUnless(first is __newobj__)
         self.assertEqual(second, (self._getTargetClass(),))
-        self.assertEqual(third, ())
+        self.assertEqual(third, None)
 
     def test___reduce__w_subclass_having_getstate(self):
         from copy_reg import __newobj__
@@ -739,6 +747,7 @@
 
     def test__p_activate_from_ghost(self):
         inst, jar, OID = self._makeOneWithJar()
+        inst._p_deactivate()
         inst._p_activate() 
         self.assertEqual(inst._p_status, 'saved')
 
@@ -822,9 +831,13 @@
 
     def test__p_deactivate_when_sticky(self):
         inst, jar, OID = self._makeOneWithJar()
+        inst._p_activate() # XXX
         inst._p_changed = False
         inst._p_sticky = True
-        self.assertRaises(ValueError, inst._p_deactivate)
+        inst._p_deactivate()
+        self.assertEqual(inst._p_status, 'sticky')
+        self.assertEqual(inst._p_changed, False)
+        self.assertEqual(inst._p_sticky, True)
 
     def test__p_invalidate_from_unsaved(self):
         inst = self._makeOne()
@@ -843,6 +856,7 @@
 
     def test__p_invalidate_from_ghost(self):
         inst, jar, OID = self._makeOneWithJar()
+        inst._p_deactivate()
         inst._p_invalidate()
         self.assertEqual(inst._p_status, 'ghost')
         self.assertEqual(list(jar._loaded), [])
@@ -900,12 +914,31 @@
         self.assertEqual(list(jar._loaded), [])
         self.assertEqual(list(jar._registered), [])
 
-    def test__p_invalidate_when_sticky(self):
+    def test__p_invalidate_from_sticky(self):
         inst, jar, OID = self._makeOneWithJar()
+        inst._p_activate() # XXX
         inst._p_changed = False
         inst._p_sticky = True
-        self.assertRaises(ValueError, inst._p_invalidate)
+        self.assertEqual(inst._p_status, 'sticky')
+        inst._p_invalidate()
+        self.assertEqual(inst._p_status, 'ghost')
+        self.assertEqual(inst._p_changed, None)
+        self.assertEqual(inst._p_sticky, False)
 
+    def test__p_invalidate_from_sticky_w_dict(self):
+        class Derived(self._getTargetClass()):
+            def __init__(self):
+                self.normal = 'value'
+        inst, jar, OID = self._makeOneWithJar(Derived)
+        inst._p_activate() # XXX
+        inst._p_changed = False
+        inst._p_sticky = True
+        inst._p_invalidate()
+        self.assertEqual(inst._p_status, 'ghost')
+        self.assertEqual(inst._p_changed, None)
+        self.assertEqual(inst._p_sticky, False)
+        self.assertEqual(inst.__dict__, {})
+
     def test__p_getattr_w__p__names(self):
         NAMES = ['_p_jar',
                  '_p_oid',
@@ -918,45 +951,50 @@
                  '_p_status',
                 ]
         inst, jar, OID = self._makeOneWithJar()
+        inst._p_deactivate()
         for name in NAMES:
             self.failUnless(inst._p_getattr(name))
         self.assertEqual(inst._p_status, 'ghost')
         self.assertEqual(list(jar._loaded), [])
-        self.assertEqual(list(jar._cache._mru), [])
+        self._checkMRU(jar, [])
 
     def test__p_getattr_w_special_names(self):
         from persistent.pyPersistence import SPECIAL_NAMES
         inst, jar, OID = self._makeOneWithJar()
+        inst._p_deactivate()
         for name in SPECIAL_NAMES:
             self.failUnless(inst._p_getattr(name))
             self.assertEqual(inst._p_status, 'ghost')
         self.assertEqual(list(jar._loaded), [])
-        self.assertEqual(list(jar._cache._mru), [])
+        self._checkMRU(jar, [])
 
     def test__p_getattr_w_normal_name(self):
         inst, jar, OID = self._makeOneWithJar()
+        inst._p_deactivate()
         self.failIf(inst._p_getattr('normal'))
         self.assertEqual(inst._p_status, 'saved')
         self.assertEqual(list(jar._loaded), [OID])
-        self.assertEqual(list(jar._cache._mru), [OID])
+        self._checkMRU(jar, [OID])
 
     def test__p_setattr_w__p__name(self):
         from persistent.pyPersistence import _makeOctets
         SERIAL = _makeOctets('\x01' * 8)
         inst, jar, OID = self._makeOneWithJar()
+        inst._p_deactivate()
         self.failUnless(inst._p_setattr('_p_serial', SERIAL))
         self.assertEqual(inst._p_status, 'ghost')
         self.assertEqual(inst._p_serial, SERIAL)
         self.assertEqual(list(jar._loaded), [])
-        self.assertEqual(list(jar._cache._mru), [])
+        self._checkMRU(jar, [])
 
     def test__p_setattr_w_normal_name(self):
         inst, jar, OID = self._makeOneWithJar()
+        inst._p_deactivate()
         self.failIf(inst._p_setattr('normal', 'value'))
         # _p_setattr doesn't do the actual write for normal names
         self.assertEqual(inst._p_status, 'saved')
         self.assertEqual(list(jar._loaded), [OID])
-        self.assertEqual(list(jar._cache._mru), [OID])
+        self._checkMRU(jar, [OID])
 
     def test__p_delattr_w__p__names(self):
         NAMES = ['_p_changed',
@@ -970,16 +1008,60 @@
         self.assertEqual(inst._p_status, 'ghost')
         self.assertEqual(inst._p_changed, None)
         self.assertEqual(list(jar._loaded), [])
-        self.assertEqual(list(jar._cache._mru), [])
+        self._checkMRU(jar, [])
 
     def test__p_delattr_w_normal_name(self):
         class Derived(self._getTargetClass()):
-            normal = 'before'
-            def __init__(self):
-                self.__dict__['normal'] = 'after'
+            normal = 'value'
         inst, jar, OID = self._makeOneWithJar(Derived)
+        inst._p_deactivate()
         self.failIf(inst._p_delattr('normal'))
         # _p_delattr doesn't do the actual delete for normal names
         self.assertEqual(inst._p_status, 'saved')
         self.assertEqual(list(jar._loaded), [OID])
-        self.assertEqual(list(jar._cache._mru), [OID])
+        self._checkMRU(jar, [OID])
+
+class PyPersistentTests(unittest.TestCase, _Persistent_Base):
+
+    def _getTargetClass(self):
+        from persistent.pyPersistence import Persistent
+        return Persistent
+
+    def _makeCache(self, jar):
+
+        class _Cache(object):
+            def __init__(self, jar):
+                self._jar = jar
+                self._mru = []
+            def mru(self, oid):
+                self._mru.append(oid)
+            def new_ghost(self, oid, obj):
+                obj._p_jar = self._jar
+                obj._p_oid = oid
+
+        return _Cache(jar)
+
+    def _checkMRU(self, jar, value):
+        self.assertEqual(list(jar._cache._mru), value)
+
+    def _clearMRU(self, jar):
+        jar._cache._mru[:] = []
+        
+
+import os
+if os.environ.get('run_C_tests'):
+    class CPersistentTests(unittest.TestCase, _Persistent_Base):
+
+        def _getTargetClass(self):
+            from persistent.cPersistence import Persistent
+            return Persistent
+
+        def _checkMRU(self, jar, value):
+            pass # Figure this out later
+    
+        def _clearMRU(self, jar):
+            pass # Figure this out later
+
+        def _makeCache(self, jar):
+            from persistent.cPickleCache import PickleCache
+            return PickleCache(jar)

Modified: persistent/trunk/setup.py
===================================================================
--- persistent/trunk/setup.py	2011-02-23 00:32:20 UTC (rev 120524)
+++ persistent/trunk/setup.py	2011-02-23 00:33:43 UTC (rev 120525)
@@ -23,6 +23,11 @@
 from setuptools import find_packages
 from setuptools import setup
 
+TESTS_REQUIRE = [
+    'zope.interface',
+    'zope.testing>=3.7.0',
+    'zope.testrunner',
+]
 
 here = os.path.abspath(os.path.dirname(__file__))
 README = (open(os.path.join(here, 'README.txt')).read()
@@ -75,11 +80,8 @@
                     ],
       headers = ['persistent/cPersistence.h',
                  'persistent/ring.h'],
-      tests_require = [
-        'zope.interface',
-        'zope.testing>=3.7.0',
-        'zope.testrunner',
-        ],
+      tests_require = TESTS_REQUIRE,
+      extras_require = {'test': TESTS_REQUIRE},
       test_loader="zope.testrunner.eggsupport:SkipLayers",
       test_suite="persistent.tests",
       install_requires=[



More information about the checkins mailing list