@@ -71,7 +71,7 @@ PyCapsule_New(void *pointer, const char *name, PyCapsule_Destructor destructor)
71
71
capsule -> destructor = destructor ;
72
72
capsule -> traverse_func = NULL ;
73
73
capsule -> clear_func = NULL ;
74
- // Only track the capsule if _PyCapsule_SetTraverse() is called
74
+ // Only track the object by the GC when _PyCapsule_SetTraverse() is called
75
75
76
76
return (PyObject * )capsule ;
77
77
}
@@ -204,8 +204,14 @@ _PyCapsule_SetTraverse(PyObject *op, traverseproc traverse_func, inquiry clear_f
204
204
}
205
205
PyCapsule * capsule = (PyCapsule * )op ;
206
206
207
- if (!PyObject_GC_IsTracked (op )) {
208
- PyObject_GC_Track (op );
207
+ if (traverse_func == NULL || clear_func == NULL ) {
208
+ PyErr_SetString (PyExc_ValueError ,
209
+ "_PyCapsule_SetTraverse() called with NULL callback" );
210
+ return -1 ;
211
+ }
212
+
213
+ if (!_PyObject_GC_IS_TRACKED (op )) {
214
+ _PyObject_GC_TRACK (op );
209
215
}
210
216
211
217
capsule -> traverse_func = traverse_func ;
@@ -306,24 +312,22 @@ capsule_repr(PyObject *o)
306
312
static int
307
313
capsule_traverse (PyCapsule * capsule , visitproc visit , void * arg )
308
314
{
309
- if (capsule -> traverse_func ) {
310
- return capsule -> traverse_func ((PyObject * )capsule , visit , arg );
311
- }
312
- else {
313
- return 0 ;
314
- }
315
+ // Capsule object is only tracked by the GC
316
+ // if _PyCapsule_SetTraverse() is called
317
+ assert (capsule -> traverse_func != NULL );
318
+
319
+ return capsule -> traverse_func ((PyObject * )capsule , visit , arg );
315
320
}
316
321
317
322
318
323
static int
319
324
capsule_clear (PyCapsule * capsule )
320
325
{
321
- if (capsule -> clear_func ) {
322
- return capsule -> clear_func ((PyObject * )capsule );
323
- }
324
- else {
325
- return 0 ;
326
- }
326
+ // Capsule object is only tracked by the GC
327
+ // if _PyCapsule_SetTraverse() is called
328
+ assert (capsule -> clear_func != NULL );
329
+
330
+ return capsule -> clear_func ((PyObject * )capsule );
327
331
}
328
332
329
333
0 commit comments