File tree Expand file tree Collapse file tree 2 files changed +21
-3
lines changed Expand file tree Collapse file tree 2 files changed +21
-3
lines changed Original file line number Diff line number Diff line change @@ -123,5 +123,22 @@ def test_finalize(self):
123
123
script_helper .assert_python_ok ("-c" , script )
124
124
125
125
126
+ class PyObjectRestypeTest (unittest .TestCase ):
127
+ def test_restype_py_object_with_null_return (self ):
128
+ # We need a function which returns a PyObject *, and returns NULL,
129
+ # without setting an exception.
130
+ # PyErr_Occurred is one such function (when no exception is set).
131
+ PyErr_Occurred = ctypes .pythonapi .PyErr_Occurred
132
+
133
+ PyErr_Occurred .argtypes = []
134
+ PyErr_Occurred .restype = ctypes .py_object
135
+
136
+ # At this point, there's no exception set, so PyErr_Occurred
137
+ # returns NULL. Given the restype is py_object, the
138
+ # ctypes machinery will raise a custom error.
139
+ with self .assertRaisesRegex (ValueError , "PyObject is NULL" ):
140
+ PyErr_Occurred ()
141
+
142
+
126
143
if __name__ == '__main__' :
127
144
unittest .main ()
Original file line number Diff line number Diff line change @@ -1022,11 +1022,12 @@ static PyObject *GetResult(ctypes_state *st,
1022
1022
if (info -> getfunc && !_ctypes_simple_instance (st , restype )) {
1023
1023
retval = info -> getfunc (result , info -> size );
1024
1024
/* If restype is py_object (detected by comparing getfunc with
1025
- O_get), we have to call Py_DECREF because O_get has already
1026
- called Py_INCREF.
1025
+ O_get), we have to call Py_XDECREF because O_get has already
1026
+ called Py_INCREF, unless the result was NULL, in which case
1027
+ an error is set (by the called function, or by O_get).
1027
1028
*/
1028
1029
if (info -> getfunc == _ctypes_get_fielddesc ("O" )-> getfunc ) {
1029
- Py_DECREF (retval );
1030
+ Py_XDECREF (retval );
1030
1031
}
1031
1032
}
1032
1033
else {
You can’t perform that action at this time.
0 commit comments