Search code examples
pythonclistfreepython-extensions

Freeing a python list from C extension code


We have some code which creates a python list and then appends data items to it. Our concern is that if one of the data items turns out to be NULL, then we consider the whole of the list (that is, any previously added items) to be worthless, and we'd like to free the list and it's memory. What do I need to do to ensure that the garbage collector frees up all the memory?

The current code is:

PyObject* retval = PyList_New(0);

QList<QVariant> varList = value.toList();
foreach(QVariant var, varList)
{
    // variantToPython(var) returns either NULL
    // or a valid object whose reference count is 1
    PyObject *pyVar = variantToPython(var);
    if (pyVar)
    {
        PyList_Append(retval, pyVar);
        Py_DECREF(pyVar);
    }
}

return retval;

but we'd like to do something like this:

PyObject* retval = PyList_New(0);

QList<QVariant> varList = value.toList();
foreach(QVariant var, varList)
{
    // variantToPython(var) returns either NULL
    // or a valid object whose reference count is 1
    PyObject *pyVar = variantToPython(var);
    if (pyVar)
    {
        PyList_Append(retval, pyVar);
        Py_DECREF(pyVar);
    }
    else
    {
        Py_DECREF(retval);
        retval = 0;
        break;
    }
}

return retval;

so is the DECREF on the list object adequate to ensure the GC frees everything?


Solution

  • Yes, since PyList_New() creates an object with a refcount of 1. You should set an appropriate exception before returning though.