[Zope-Checkins] CVS: ZODB3/Persistence - cPersistence.c:1.72.8.5

Jeremy Hylton jeremy@zope.com
Tue, 1 Jul 2003 17:01:07 -0400


Update of /cvs-repository/ZODB3/Persistence
In directory cvs.zope.org:/tmp/cvs-serv12113

Modified Files:
      Tag: zodb33-devel-branch
	cPersistence.c 
Log Message:
A bunch of small fixes.

Reimplement _p_deactivate().

Add __del__ to the list of methods we don't unghostify for.

Rewrite callmethod1() to use sane variable names.


=== ZODB3/Persistence/cPersistence.c 1.72.8.4 => 1.72.8.5 ===
--- ZODB3/Persistence/cPersistence.c:1.72.8.4	Tue Jul  1 15:49:44 2003
+++ ZODB3/Persistence/cPersistence.c	Tue Jul  1 17:01:05 2003
@@ -75,19 +75,21 @@
 static PyObject *
 callmethod1(PyObject *self, PyObject *name, PyObject *arg)
 {
-  self = PyObject_GetAttr(self, name);
-  UNLESS(self) return NULL;
-  name = PyTuple_New(1);
-  UNLESS(name) 
-    {
-      Py_DECREF(self);
-      return NULL;
-    }
-  PyTuple_SET_ITEM(name, 0, arg);
-  ASSIGN(self, PyObject_CallObject(self, name));
-  PyTuple_SET_ITEM(name, 0, NULL);
-  Py_DECREF(name);
-  return self;
+    PyObject *args = NULL, *result = NULL, *meth = NULL;
+
+    meth = PyObject_GetAttr(self, name);
+    if (!meth)
+	goto err;
+    args = PyTuple_New(1);
+    if (!args)
+	goto err;
+    PyTuple_SET_ITEM(args, 0, arg);
+    result = PyObject_CallObject(meth, args);
+    PyTuple_SET_ITEM(name, 0, NULL);
+ err:
+    Py_XDECREF(meth);
+    Py_XDECREF(args);
+    return result;
 }
 
 
@@ -113,6 +115,9 @@
 	    home->prev = &self->ring;
 	    Py_INCREF(self);
         }
+	/* set state to CHANGED while setstate() call is in progress
+	   to prevent a recursive call to _PyPersist_Load().
+	*/
         self->state = cPersistent_CHANGED_STATE;
         /* Call the object's __setstate__() */
         r = callmethod1(self->jar, py_setstate, (PyObject*)self);
@@ -151,6 +156,7 @@
     /* are we already a ghost? */
     if (self->state == cPersistent_GHOST_STATE)
         return;
+
     /* XXX is it ever possible to not have a cache? */
     if (self->cache == NULL) {
         self->state = cPersistent_GHOST_STATE;
@@ -257,34 +263,23 @@
 static PyObject *
 Per__p_deactivate(cPersistentObject *self, PyObject *args)
 {
-  PyObject *dict, *dict2=NULL;
-
-  if (args && !checknoargs(args))
-    return NULL;
-
-  if (self->state==cPersistent_UPTODATE_STATE && self->jar) {
-      PyObject **dictptr = _PyObject_GetDictPtr((PyObject *)self);
-      if (dictptr) {
-	  dict = *dictptr;
-	  dict2 = PyDict_Copy(dict);
-	  PyDict_Clear(dict);
-	  /* Note that we need to set to ghost state unless we are 
-	     called directly. Methods that override this need to
-	     do the same! */
-	  ghostify(self);
-      }
-  }
+    if (args && !checknoargs(args))
+	return NULL;
 
-  /* need to delay releasing the last reference on instance attributes
-     until after we have finished accounting for losing our state */
-  if (dict2)
-  {
-      PyDict_Clear(dict2);
-      Py_DECREF(dict2);
-  }
+    if (self->state == cPersistent_UPTODATE_STATE && self->jar) {
+	PyObject **dictptr = _PyObject_GetDictPtr((PyObject *)self);
+	if (dictptr && *dictptr) {
+	    Py_DECREF(*dictptr);
+	    *dictptr = NULL;
+	}
+	/* Note that we need to set to ghost state unless we are 
+	   called directly. Methods that override this need to
+	   do the same! */
+	ghostify(self);
+    }
 
-  Py_INCREF(Py_None);
-  return Py_None;
+    Py_INCREF(Py_None);
+    return Py_None;
 }
 
 /* Load the object's state if necessary and become sticky */
@@ -452,10 +447,10 @@
   char *n, *name;
   name = PyString_AS_STRING(oname);
   n = name;
+  assert(n);
 
   if (n && *n++=='_')
-    if (*n++=='p' && *n++=='_')
-      {
+      if (*n++=='p' && *n++=='_') {
 	switch(*n++)
 	  {
 	  case 'o':
@@ -512,17 +507,19 @@
 	    break;
 	  }
 
-	return self->ob_type->tp_base->tp_getattro((PyObject *)self, oname);
+	return PyObject_GenericGetAttr((PyObject *)self, oname);
       }
-  if (! (name && *name++=='_' && *name++=='_' &&
-	(strcmp(name,"dict__")==0 || strcmp(name,"class__")==0
-	 || strcmp(name, "of__")==0)))
-    {
-        if (!unghostify(self))
-            return NULL;
 
+  /* If the name is not __dict__, __del__, __class__, or __of__,
+     unghostify the object.
+  */
+  if (! (*name++ == '_' && *name++ == '_' &&
+	(strcmp(name,"dict__") == 0 || strcmp(name,"class__") == 0
+	 || strcmp(name, "of__") == 0 || strcmp(name, "del__") == 0))) {
+      if (!unghostify(self))
+	  return NULL;
       accessed(self);
-    }
+  }
 
   return PyObject_GenericGetAttr((PyObject *)self, oname);
 }
@@ -555,7 +552,7 @@
   name = PyString_AS_STRING(oname);
   if (name == NULL)
       return -1;
-	
+
   if (*name == '_' && name[1] == 'p' && name[2] == '_') {
       if (strcmp(name + 3, "oid") == 0) {
 	  if (self->cache) {