This is due to an oversight in _CallPythonObject in Modules/_ctypes/callbacks.c. The setfunc protocol is to return None if there's no object to keep alive. This isn't applicable to py_object (i.e. O_set in Modules/_ctypes/cfield.c). So the problem is the unconditional decref of None in the following snippet from _CallPythonObject:
if (keep == NULL) /* Could not convert callback result. */
PyErr_WriteUnraisable(callable);
else if (keep == Py_None) /* Nothing to keep */
Py_DECREF(keep);
else if (setfunc != _ctypes_get_fielddesc("O")->setfunc) {
if (-1 == PyErr_WarnEx(PyExc_RuntimeWarning,
"memory leak in callback function.",
1))
PyErr_WriteUnraisable(callable);
}
I'd rewrite it as follows:
if (keep == NULL) { /* Could not convert callback result. */
PyErr_WriteUnraisable(callable);
} else if (setfunc != _ctypes_get_fielddesc("O")->setfunc) {
if (keep == Py_None) { /* Nothing to keep */
Py_DECREF(keep);
} else if (PyErr_WarnEx(PyExc_RuntimeWarning, "memory leak "
"in callback function.", 1) == -1) {
PyErr_WriteUnraisable(callable);
}
} |