Merge branch 'coleb-python35_dtor_exception_fix'
* coleb-python35_dtor_exception_fix: Add test case for Python 3.5 assertion with a pending StopIteration Amend python_destructor_exception runtime test Call PyErr_WriteUnraisable if a destructor sets a Python exception (-builtin) Extended zjturner's changes to encompass all function dispatch and use PyErr_WriteUnraisable to handle exceptions during __del__. Python - Save and restore exception state before calling destroy.
This commit is contained in:
commit
b15ad9349e
5 changed files with 118 additions and 10 deletions
|
|
@ -9,9 +9,17 @@ SWIGINTERN void \
|
|||
wrapper##_closure(PyObject *a) { \
|
||||
SwigPyObject *sobj; \
|
||||
sobj = (SwigPyObject *)a; \
|
||||
Py_XDECREF(sobj->dict); \
|
||||
Py_XDECREF(sobj->dict); \
|
||||
if (sobj->own) { \
|
||||
PyObject *val = 0, *type = 0, *tb = 0; \
|
||||
PyErr_Fetch(&val, &type, &tb); \
|
||||
PyObject *o = wrapper(a, NULL); \
|
||||
if (!o) { \
|
||||
PyObject *deallocname = PyString_FromString(#wrapper); \
|
||||
PyErr_WriteUnraisable(deallocname); \
|
||||
Py_DECREF(deallocname); \
|
||||
} \
|
||||
PyErr_Restore(val, type, tb); \
|
||||
Py_XDECREF(o); \
|
||||
} \
|
||||
if (PyType_IS_GC(a->ob_type)) { \
|
||||
|
|
@ -64,7 +72,7 @@ wrapper##_closure(PyObject *a, PyObject *b, PyObject *c) { \
|
|||
|
||||
#define SWIGPY_TERNARYCALLFUNC_CLOSURE(wrapper) \
|
||||
SWIGINTERN PyObject * \
|
||||
wrapper##_closure(PyObject *callable_object, PyObject *args, PyObject *) { \
|
||||
wrapper##_closure(PyObject *callable_object, PyObject *args, PyObject *) { \
|
||||
return wrapper(callable_object, args); \
|
||||
}
|
||||
|
||||
|
|
@ -124,7 +132,7 @@ wrapper##_closure(PyObject *a, Py_ssize_t b) { \
|
|||
return result; \
|
||||
}
|
||||
|
||||
#define SWIGPY_FUNPACK_SSIZEARGFUNC_CLOSURE(wrapper) \
|
||||
#define SWIGPY_FUNPACK_SSIZEARGFUNC_CLOSURE(wrapper) \
|
||||
SWIGINTERN PyObject * \
|
||||
wrapper##_closure(PyObject *a, Py_ssize_t b) { \
|
||||
PyObject *arg, *result; \
|
||||
|
|
|
|||
|
|
@ -536,16 +536,32 @@ SwigPyObject_dealloc(PyObject *v)
|
|||
if (destroy) {
|
||||
/* destroy is always a VARARGS method */
|
||||
PyObject *res;
|
||||
|
||||
/* PyObject_CallFunction() has the potential to silently drop
|
||||
the active active exception. In cases of unnamed temporary
|
||||
variable or where we just finished iterating over a generator
|
||||
StopIteration will be active right now, and this needs to
|
||||
remain true upon return from SwigPyObject_dealloc. So save
|
||||
and restore. */
|
||||
|
||||
PyObject *val = NULL, *type = NULL, *tb = NULL;
|
||||
PyErr_Fetch(&val, &type, &tb);
|
||||
|
||||
if (data->delargs) {
|
||||
/* we need to create a temporary object to carry the destroy operation */
|
||||
PyObject *tmp = SwigPyObject_New(sobj->ptr, ty, 0);
|
||||
res = SWIG_Python_CallFunctor(destroy, tmp);
|
||||
Py_DECREF(tmp);
|
||||
/* we need to create a temporary object to carry the destroy operation */
|
||||
PyObject *tmp = SwigPyObject_New(sobj->ptr, ty, 0);
|
||||
res = SWIG_Python_CallFunctor(destroy, tmp);
|
||||
Py_DECREF(tmp);
|
||||
} else {
|
||||
PyCFunction meth = PyCFunction_GET_FUNCTION(destroy);
|
||||
PyObject *mself = PyCFunction_GET_SELF(destroy);
|
||||
res = ((*meth)(mself, v));
|
||||
PyCFunction meth = PyCFunction_GET_FUNCTION(destroy);
|
||||
PyObject *mself = PyCFunction_GET_SELF(destroy);
|
||||
res = ((*meth)(mself, v));
|
||||
}
|
||||
if (!res)
|
||||
PyErr_WriteUnraisable(destroy);
|
||||
|
||||
PyErr_Restore(val, type, tb);
|
||||
|
||||
Py_XDECREF(res);
|
||||
}
|
||||
#if !defined(SWIG_PYTHON_SILENT_MEMLEAK)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue