File tree Expand file tree Collapse file tree 2 files changed +24
-1
lines changed
Expand file tree Collapse file tree 2 files changed +24
-1
lines changed Original file line number Diff line number Diff line change @@ -328,6 +328,17 @@ def func():
328328 f"of ctypes callback function { func !r} " )
329329 self .assertIsNone (cm .unraisable .object )
330330
331+ def test_callback_return_subclass (self ):
332+ class MyInt (ctypes .c_int ):
333+ pass
334+
335+ @ctypes .CFUNCTYPE (MyInt , MyInt )
336+ def identity (x ):
337+ return x
338+
339+ result = identity (MyInt (42 ))
340+ assert isinstance (result , MyInt )
341+ assert result .value == 42
331342
332343if __name__ == '__main__' :
333344 unittest .main ()
Original file line number Diff line number Diff line change @@ -239,7 +239,19 @@ static void _CallPythonObject(ctypes_state *st,
239239 be the result. EXCEPT when restype is py_object - Python
240240 itself knows how to manage the refcount of these objects.
241241 */
242- PyObject * keep = setfunc (mem , result , restype -> size );
242+ PyObject * value = result ; /* borrowed */
243+ PyObject * unwrapped = NULL ; /* new ref if created */
244+ if (value != NULL && PyObject_TypeCheck (value , st -> PyCData_Type )) {
245+ unwrapped = PyObject_GetAttrString (value , "value" );
246+ if (unwrapped != NULL ) {
247+ value = unwrapped ;
248+ } else {
249+ /* fallback: clear error and keep original */
250+ PyErr_Clear ();
251+ }
252+ }
253+
254+ PyObject * keep = setfunc (mem , value , restype -> size );
243255
244256 if (keep == NULL ) {
245257 /* Could not convert callback result. */
You can’t perform that action at this time.
0 commit comments