[Zope3-checkins] CVS: ZODB4/Persistence - cPersistence.c:1.31
Jeremy Hylton
jeremy@zope.com
Wed, 11 Dec 2002 18:24:25 -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