@@ -141,6 +141,7 @@ _PyArg_VaParse_SizeT(PyObject *args, char *format, va_list va)
141141
142142#define GETARGS_CAPSULE_NAME_CLEANUP_PTR "getargs.cleanup_ptr"
143143#define GETARGS_CAPSULE_NAME_CLEANUP_BUFFER "getargs.cleanup_buffer"
144+ #define GETARGS_CAPSULE_NAME_CLEANUP_CONVERT "getargs.cleanup_convert"
144145
145146static void
146147cleanup_ptr (PyObject * self )
@@ -194,6 +195,46 @@ addcleanup(void *ptr, PyObject **freelist, PyCapsule_Destructor destr)
194195 return 0 ;
195196}
196197
198+ static void
199+ cleanup_convert (PyObject * self )
200+ {
201+ typedef int (* destr_t )(PyObject * , void * );
202+ destr_t destr = (destr_t )PyCapsule_GetContext (self );
203+ void * ptr = PyCapsule_GetPointer (self ,
204+ GETARGS_CAPSULE_NAME_CLEANUP_CONVERT );
205+ if (ptr && destr )
206+ destr (NULL , ptr );
207+ }
208+
209+ static int
210+ addcleanup_convert (void * ptr , PyObject * * freelist , int (* destr )(PyObject * ,void * ))
211+ {
212+ PyObject * cobj ;
213+ if (!* freelist ) {
214+ * freelist = PyList_New (0 );
215+ if (!* freelist ) {
216+ destr (NULL , ptr );
217+ return -1 ;
218+ }
219+ }
220+ cobj = PyCapsule_New (ptr , GETARGS_CAPSULE_NAME_CLEANUP_CONVERT ,
221+ cleanup_convert );
222+ if (!cobj ) {
223+ destr (NULL , ptr );
224+ return -1 ;
225+ }
226+ if (PyCapsule_SetContext (cobj , destr ) == -1 ) {
227+ /* This really should not happen. */
228+ Py_FatalError ("capsule refused setting of context." );
229+ }
230+ if (PyList_Append (* freelist , cobj )) {
231+ Py_DECREF (cobj ); /* This will also call destr. */
232+ return -1 ;
233+ }
234+ Py_DECREF (cobj );
235+ return 0 ;
236+ }
237+
197238static int
198239cleanreturn (int retval , PyObject * freelist )
199240{
@@ -1253,10 +1294,15 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
12531294 typedef int (* converter )(PyObject * , void * );
12541295 converter convert = va_arg (* p_va , converter );
12551296 void * addr = va_arg (* p_va , void * );
1297+ int res ;
12561298 format ++ ;
1257- if (! (* convert )(arg , addr ))
1299+ if (! (res = ( * convert )(arg , addr ) ))
12581300 return converterr ("(unspecified)" ,
12591301 arg , msgbuf , bufsize );
1302+ if (res == Py_CLEANUP_SUPPORTED &&
1303+ addcleanup_convert (addr , freelist , convert ) == -1 )
1304+ return converterr ("(cleanup problem)" ,
1305+ arg , msgbuf , bufsize );
12601306 }
12611307 else {
12621308 p = va_arg (* p_va , PyObject * * );
0 commit comments