On my last question How to improve Python C Extensions file line reading? was brought up some memory problems I had. Then, I wrote this simple and ridiculous usage of and Python C Extension, just with the purpose of trying to understanding better Python Borrowing and Owning References.
static void PyFastFile_dealloc(PyFastFile* self) {
for( PyObject* pyobject : linecache ) {
Py_XDECREF( pyobject );
}
Py_TYPE(self)->tp_free( (PyObject*) self );
}
static PyObject* PyFastFile_tp_iter(PyFastFile* self, PyObject* args) {
counter = 10;
std::string line{"sample line"}
PyObject* obj = PyUnicode_DecodeUTF8( line.c_str(), line.size(), "replace" );
linecache.push_back( obj );
}
static PyObject* PyFastFile_iternext(PyFastFile* self, PyObject* args) {
--counter;
if( !( counter ) ) {
PyErr_SetNone( PyExc_StopIteration );
return NULL;
}
PyObject* retval = linecache[0];
Py_XINCREF( retval );
return retval;
}
// create the module
PyMODINIT_FUNC PyInit_fastfilepackage(void) {
PyFastFileType.tp_iter = (getiterfunc) PyFastFile_tp_iter;
PyFastFileType.tp_iternext = (iternextfunc) PyFastFile_iternext;
PyFastFileType.tp_dealloc = (destructor) PyFastFile_dealloc;
...
}
On this case,
- Is the
tp_next()
returning an owned reference tolinecache[0]
because it is incrementing itsPy_XINCREF
? - Meaning, is my
linecache[0]
cache now a borrowed reference? - As
tp_next()
is being called more than once, and I am returning the same pointer several times incrementing itsPy_XINCREF
, is this going to lead to double/triple/several frees? - Has the
tp_next()
return object only one owned reference, which will lead to double/triple/several?
Related: