C function to fully consume a Python iterator
You’ve got an object leak.

PyObject_GetIter() returns a new instance, which you aren’t calling Py_DECREF() on.

If you pass in an iterable object to your function (a list, a tuple, a dictionary, etc), PyObject_GetIter() will return a brand new iterator over than object.  You test the return value, discover it is not NULL, and then lose the returned value, since it was not stored in a local variable.  Then, you try to retrieve tp_iternext from the iterable’s type, which is likely not defined, so chaos will ensue.

If you pass in an iterator object to your function, PyObject_GetIter() will return it, but also increment the reference count of that object by one.  At the end of your function, you don’t call Py_DECREF() on the returned iterator, so the reference count will remain incremented, and the iterator will never be released.

static PyObject *
consume(PyObject *self, PyObject *iterable)
{
    PyObject *(*iternext)(PyObject *);
    PyObject *item;
    PyObject *iterator;

    iterator = PyObject_GetIter(iterable);  // No references to iterable beyond this point.
    if (iterator == NULL)
        return NULL;

    iternext = *Py_TYPE(iterator)-&gt;tp_iternext;
    while ((item = iternext(iterator)) != NULL) 
        Py_DECREF(item);

    Py_DECREF(iterator);

    if (PyErr_Occurred()) {
        if (PyErr_ExceptionMatches(PyExc_StopIteration))
            PyErr_Clear();
        else
            return NULL;
    }

    Py_RETURN_NONE;
}