/* Wrap void * pointers to be passed between C modules */
#include "Python.h"
+#include "pycore_gc.h" // _PyObject_GC_IS_TRACKED()
+#include "pycore_object.h" // _PyObject_GC_TRACK()
+
/* Internal structure of PyCapsule */
typedef struct {
capsule->destructor = destructor;
capsule->traverse_func = NULL;
capsule->clear_func = NULL;
- // Only track the capsule if _PyCapsule_SetTraverse() is called
+ // Only track the object by the GC when _PyCapsule_SetTraverse() is called
return (PyObject *)capsule;
}
}
PyCapsule *capsule = (PyCapsule *)op;
- if (!PyObject_GC_IsTracked(op)) {
- PyObject_GC_Track(op);
+ if (traverse_func == NULL || clear_func == NULL) {
+ PyErr_SetString(PyExc_ValueError,
+ "_PyCapsule_SetTraverse() called with NULL callback");
+ return -1;
+ }
+
+ if (!_PyObject_GC_IS_TRACKED(op)) {
+ _PyObject_GC_TRACK(op);
}
capsule->traverse_func = traverse_func;
static int
capsule_traverse(PyCapsule *capsule, visitproc visit, void *arg)
{
- if (capsule->traverse_func) {
- return capsule->traverse_func((PyObject*)capsule, visit, arg);
- }
- else {
- return 0;
- }
+ // Capsule object is only tracked by the GC
+ // if _PyCapsule_SetTraverse() is called
+ assert(capsule->traverse_func != NULL);
+
+ return capsule->traverse_func((PyObject*)capsule, visit, arg);
}
static int
capsule_clear(PyCapsule *capsule)
{
- if (capsule->clear_func) {
- return capsule->clear_func((PyObject*)capsule);
- }
- else {
- return 0;
- }
+ // Capsule object is only tracked by the GC
+ // if _PyCapsule_SetTraverse() is called
+ assert(capsule->clear_func != NULL);
+
+ return capsule->clear_func((PyObject*)capsule);
}