[Zodb-checkins] CVS: ZODB4/Persistence - cPersistence.c:1.31

Jeremy Hylton jeremy@zope.com
Wed, 11 Dec 2002 18:24:26 -0500


Update of /cvs-repository/ZODB4/Persistence
In directory cvs.zope.org:/tmp/cvs-serv16188/Persistence

Modified Files:
	cPersistence.c 
Log Message:
Add extra arg to call_p_deactivate() to handle unraisable exceptions.

If an error occurs in an _p_deactivate() method when there's no
practical way to raise an exception in user code, just write the
exception to stderr.  This is better than silently ignoring it, I
guess.




=== ZODB4/Persistence/cPersistence.c 1.30 => 1.31 ===
--- ZODB4/Persistence/cPersistence.c:1.30	Fri Nov 22 17:23:43 2002
+++ ZODB4/Persistence/cPersistence.c	Wed Dec 11 18:24:25 2002
@@ -239,7 +239,7 @@
 }
 
 static int
-call_p_deactivate(PyPersistObject *self)
+call_p_deactivate(PyPersistObject *self, int unraisable)
 {
     static PyObject *t = NULL;
     PyObject *func, *r;
@@ -252,6 +252,9 @@
     if (!func) 
 	return 0;
     r = PyObject_Call(func, t, NULL);
+    if (unraisable && !r) {
+	PyErr_WriteUnraisable(func);
+    }
     Py_DECREF(func);
     if (!r)
 	return 0;
@@ -320,14 +323,14 @@
 	   call_p_deactivate() will turn it into a ghost.
 	*/
 	self->po_state = UPTODATE;
-	if (!call_p_deactivate(self))
+	if (!call_p_deactivate(self, 0))
 	    return -1;
     } else if (self->po_state == UPTODATE) {
 	/* The final case is for CHANGED_NONE, which is only
 	   meaningful when the object is already in the up-to-date state. 
 	   In this case, turn the object into a ghost.
 	*/
-	if (!call_p_deactivate(self))
+	if (!call_p_deactivate(self, 0))
 	    return -1;
     }
 
@@ -404,7 +407,20 @@
 	    */
 	    self->po_state = CHANGED;
 	    if (!_PyPersist_Load((PyPersistObject *)self)) {
-		call_p_deactivate(self);
+		/* What if an error occured in _p_deactivate()?
+
+		   It's not clear what we should do here.  The code is
+		   obviously ignoring the exception, but it shouldn't
+		   return 0 for a getattr and set an exception.  The
+		   simplest change is to clear the exception, but that
+		   simply masks the error. 
+
+		   The second argument to call_p_deactivate() says
+		   to print the exception to stderr. It would probably be
+		   better to log it but that would be painful from C.
+		*/
+		if (!call_p_deactivate(self, 1))
+		    return NULL;
 		self->po_state = GHOST;
 		return NULL;
 	    } else