Fabian Steiner wrote: > Georg Brandl wrote: >> Fabian Steiner wrote: >>> [...] >>> for (i = 0; i <= seqlen; i++) { >> >> That is one iteration too much. Use >> >> for (i = 0; i < seglen; i++) >> >>> item = PySequence_Fast_GET_ITEM(seq, i); >> >> Now item is a PyObject*. You'll have to convert it to an integer now: >> >> it = PyInt_AsLong(item); > > Why do you use PyInt_AsLong() here? As the documentation says it returns > a long type: long PyInt_AsLong(PyObject *io) > On the other hand I can't find anything like PyInt_AsInt().
Python's int objects carry a long, so they can return you this long. On most 32-bit platforms, int == long anyway, but for 64-bit you'd have to declare list as long too. >> if (it == -1 && PyErr_Occurred()) { >> Py_DECREF(seq); > > Why is this Py_DECREF() needed? What does it do exactly? When do I have > to call this function? Obviously, there is also Py_INCREF(). When do you > need this function? This is for reference counting. Since you created seq with PySequence_Fast you "own" a reference to it (it has reference count 1). Since nothing else references that sequence, it has to be deallocated before the function exits. You use Py_DECREF to decrease the reference count to 0, thus telling Python that it's safe to free the memory associated with it. Most API functions that return a PyObject increase its reference count by 1, leaving you in charge to do something with this ("your") reference. Other examples of how references can be juggled with: item = PySequence_Fast_GET_ITEM(seq, i); PySequence_Fast_GET_ITEM does return a PyObject, but it doesn't increase the reference count, so you don't have to DECREF item anywhere. However, if you were to store item in a structure of some sort, you'd have to INCREF it so that Python doesn't destroy it while it's still referenced by your structure. PyList_SetItem(newseq, i, PyInt_FromLong(list[i])); PyInt_FromLong() returns a new PyObject with one reference, but PyList_SetItem "steals" that reference from you (it stores the PyObject in a structure without increasing its reference count). Therefore, you don't own a reference to the integer object anymore and don't have to DECREF it. newseq = PyList_New(seqlen); (...) return newseq; Here, you own a reference to newseq, but you return the object, so you have to keep it alive. Thus, no DECREF. >> [...] >> There's quite a bit you can overlook, especially stale references to >> PyObjects. >> I'm not even sure the code compiles or runs correctly with my corrections ;) > > Now, it compiles fine, without any warnings and using it in Python works > either :-) Now I have to try to understand what the different parts are > doing and why they are necessary. Cheers, Georg -- http://mail.python.org/mailman/listinfo/python-list