[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