Skip to content

Commit 2d1128e

Browse files
GH-81061: Fix refcount issue when returning None from a ctypes.py_object callback (GH-13364)
(cherry picked from commit 837ba05) Co-authored-by: dgelessus <[email protected]>
1 parent 074b881 commit 2d1128e

File tree

3 files changed

+24
-8
lines changed

3 files changed

+24
-8
lines changed

Lib/ctypes/test/test_refcounts.py

+15
Original file line numberDiff line numberDiff line change
@@ -97,5 +97,20 @@ def func(a, b):
9797
f(1, 2)
9898
self.assertEqual(sys.getrefcount(ctypes.c_int), a)
9999

100+
@support.refcount_test
101+
def test_callback_py_object_none_return(self):
102+
# bpo-36880: test that returning None from a py_object callback
103+
# does not decrement the refcount of None.
104+
105+
for FUNCTYPE in (ctypes.CFUNCTYPE, ctypes.PYFUNCTYPE):
106+
with self.subTest(FUNCTYPE=FUNCTYPE):
107+
@FUNCTYPE(ctypes.py_object)
108+
def func():
109+
return None
110+
111+
# Check that calling func does not affect None's refcount.
112+
for _ in range(10000):
113+
func()
114+
100115
if __name__ == '__main__':
101116
unittest.main()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix a reference counting issue when a :mod:`ctypes` callback with return
2+
type :class:`~ctypes.py_object` returns ``None``, which could cause crashes.

Modules/_ctypes/callbacks.c

+7-8
Original file line numberDiff line numberDiff line change
@@ -276,15 +276,14 @@ static void _CallPythonObject(void *mem,
276276
"of ctypes callback function",
277277
callable);
278278
}
279-
else if (keep == Py_None) {
280-
/* Nothing to keep */
281-
Py_DECREF(keep);
282-
}
283279
else if (setfunc != _ctypes_get_fielddesc("O")->setfunc) {
284-
if (-1 == PyErr_WarnEx(PyExc_RuntimeWarning,
285-
"memory leak in callback function.",
286-
1))
287-
{
280+
if (keep == Py_None) {
281+
/* Nothing to keep */
282+
Py_DECREF(keep);
283+
}
284+
else if (PyErr_WarnEx(PyExc_RuntimeWarning,
285+
"memory leak in callback function.",
286+
1) == -1) {
288287
_PyErr_WriteUnraisableMsg("on converting result "
289288
"of ctypes callback function",
290289
callable);

0 commit comments

Comments
 (0)