[Zodb-checkins] SVN: ZODB/trunk/ When obj is a ghost, "obj._p_changed = some_true_value"

Tim Peters tim.one at comcast.net
Tue Sep 13 18:38:20 EDT 2005


Log message for revision 38459:
  When obj is a ghost, "obj._p_changed = some_true_value"
  now activates obj.
  

Changed:
  U   ZODB/trunk/NEWS.txt
  U   ZODB/trunk/src/persistent/cPersistence.c
  U   ZODB/trunk/src/persistent/interfaces.py
  U   ZODB/trunk/src/persistent/tests/persistent.txt

-=-
Modified: ZODB/trunk/NEWS.txt
===================================================================
--- ZODB/trunk/NEWS.txt	2005-09-13 18:15:42 UTC (rev 38458)
+++ ZODB/trunk/NEWS.txt	2005-09-13 22:38:19 UTC (rev 38459)
@@ -10,6 +10,17 @@
 - 3.6a2 06-Sep-2005
 - 3.6a1 04-Sep-2005
 
+Persistent
+----------
+
+- (3.6a4) ZODB 3.6 introduces a change to the basic behavior of Persistent
+  objects in a particular end case.  Before ZODB 3.6, setting
+  ``obj._p_changed`` to a true value when ``obj`` was a ghost was ignored:
+  ``obj`` remained a ghost, and getting ``obj._p_changed`` continued to
+  return ``None``.  Starting with ZODB 3.6, ``obj`` is activated instead
+  (unghostified), and its state is changed from the ghost state to the
+  changed state.  The new behavior is less surprising and more robust.
+
 Commit hooks
 ------------
 

Modified: ZODB/trunk/src/persistent/cPersistence.c
===================================================================
--- ZODB/trunk/src/persistent/cPersistence.c	2005-09-13 18:15:42 UTC (rev 38458)
+++ ZODB/trunk/src/persistent/cPersistence.c	2005-09-13 22:38:19 UTC (rev 38459)
@@ -832,7 +832,9 @@
 static int
 Per_set_changed(cPersistentObject *self, PyObject *v)
 {
-    int deactivate = 0, true;
+    int deactivate = 0;
+    int true;
+
     if (!v) {
 	/* delattr is used to invalidate an object even if it has changed. */
 	if (self->state != cPersistent_GHOST_STATE)
@@ -868,12 +870,25 @@
 	Py_DECREF(meth);
 	return 0;
     }
+    /* !deactivate.  If passed a true argument, mark self as changed (starting
+     * with ZODB 3.6, that includes activating the object if it's a ghost).
+     * If passed a false argument, and the object isn't a ghost, set the
+     * state as up-to-date.
+     */
     true = PyObject_IsTrue(v);
     if (true == -1)
 	return -1;
-    else if (true)
+    if (true) {
+    	if (self->state < 0) {
+    	    if (unghostify(self) < 0)
+    	        return -1;
+    	    }
 	return changed(self);
+    }
 
+    /* We were passed a false, non-None argument.  If we're not a ghost,
+     * mark self as up-to-date.
+     */
     if (self->state >= 0)
 	self->state = cPersistent_UPTODATE_STATE;
     return 0;

Modified: ZODB/trunk/src/persistent/interfaces.py
===================================================================
--- ZODB/trunk/src/persistent/interfaces.py	2005-09-13 18:15:42 UTC (rev 38458)
+++ ZODB/trunk/src/persistent/interfaces.py	2005-09-13 22:38:19 UTC (rev 38459)
@@ -71,7 +71,7 @@
     In all the above, _p_oid (the persistent object id) is set when
     _p_jar first gets set.
 
-    The following state transactions are possible:
+    The following state transitions are possible:
 
     - Unsaved -> Saved
 
@@ -82,13 +82,18 @@
 
     - Saved  -> Changed
       Sticky -> Changed
+      Ghost  -> Changed
 
       This transition occurs when someone sets an attribute or sets
-      _p_changed to a true value on a saved or sticky object.  When the
-      transition occurs, the persistent object is required to call the
+      _p_changed to a true value on a saved, sticky or ghost object.  When
+      the transition occurs, the persistent object is required to call the
       register() method on its data manager, passing itself as the
       only argument.
 
+      Prior to ZODB 3.6, setting _p_changed to a true value on a ghost object
+      was ignored (the object remained a ghost, and getting its _p_changed
+      attribute continued to return None).
+
     - Saved -> Sticky
 
       This transition occurs when C code marks the object as sticky to
@@ -166,7 +171,7 @@
         """)
 
     _p_changed = Attribute(
-        """The persistent state of the object
+        """The persistent state of the object.
 
         This is one of:
 
@@ -181,6 +186,10 @@
         not in the saved state, and may be ignored even if the object is
         in the saved state.
 
+        At and after ZODB 3.6, setting _p_changed to a true value for a ghost
+        object activates the object; prior to 3.6, setting _p_changed to a
+        true value on a ghost object was ignored.
+
         Note that an object can transition to the changed state only if
         it has a data manager.  When such a state change occurs, the
         'register' method of the data manager must be called, passing the
@@ -273,8 +282,8 @@
         obj: a persistent object from this Connection.
         tid: id of a transaction that wrote an earlier revision.
 
-        Raises KeyError if tid does not exist or if tid deleted a revision of 
-            obj. 
+        Raises KeyError if tid does not exist or if tid deleted a revision of
+        obj.
         """
 
     def register(object):

Modified: ZODB/trunk/src/persistent/tests/persistent.txt
===================================================================
--- ZODB/trunk/src/persistent/tests/persistent.txt	2005-09-13 18:15:42 UTC (rev 38458)
+++ ZODB/trunk/src/persistent/tests/persistent.txt	2005-09-13 22:38:19 UTC (rev 38459)
@@ -87,7 +87,7 @@
 
 Next try some tests of an object with a data manager.  The DM class is
 a simple testing stub.
-    
+
 >>> p = P()
 >>> dm = DM()
 >>> p._p_oid = "00000012"
@@ -194,20 +194,24 @@
 Change Ghost test
 -----------------
 
-If an object is a ghost and it's _p_changed is set to True, it should
-have no effect.
+If an object is a ghost and its _p_changed is set to True (any true value),
+it should activate (unghostify) the object.  This behavior is new in ZODB
+3.6; before then, an attempt to do "ghost._p_changed = True" was ignored.
 
 >>> p = P()
 >>> p._p_jar = DM()
 >>> p._p_oid = 1
 >>> p._p_deactivate()
->>> p._p_changed
->>> p._p_state
+>>> p._p_changed # None
+>>> p._p_state # ghost state
 -1
 >>> p._p_changed = True
 >>> p._p_changed
->>> p._p_state
--1
+1
+>>> p._p_state # changed state
+1
+>>> p.x
+42
 
 Activate, deactivate, and invalidate
 ------------------------------------
@@ -338,7 +342,7 @@
 Basic type structure
 --------------------
 
->>> Persistent.__dictoffset__ 
+>>> Persistent.__dictoffset__
 0
 >>> Persistent.__weakrefoffset__
 0
@@ -392,7 +396,7 @@
 >>> p._p_state
 0
 
-If the most-derived class does not specify 
+If the most-derived class does not specify
 
 >>> p_shouldHaveDict.__dictoffset__ > 0
 True



More information about the Zodb-checkins mailing list