This question is pretty simple but will help cement my understanding. I know that arguments to C extension functions are guaranteed to be live references for the duration of the C code (unless manually DECREFed). However, if I have a C extension code that returns a PyObject* that was present in its argument list, do I need to INCREF the argument before returning it? I.e., which of the following two is correct:
static PyObject return_item(PyObject *self, PyObject *item)
{
// manipulate item
return item;
}
or
static PyObject return_item(PyObject *self, PyObject *item)
{
// manipulate item
Py_INCREF(item);
return item;
}
Based on https://docs.python.org/3/extending/extending.html#ownership-rules, which says
The object reference returned from a C function that is called from Python must be an owned reference — ownership is transferred from the function to its caller.
and Returning objects to Python from C I assume it's the latter (INCREFing is the way to go) but I want to be sure.
If someone is calling the return_item
function from Python, they might do this:
something = Something()
something_else = return_item(something)
del something
If return_item
did not return the argument which was passed in, but something else, you would expect that at this point the something
which was passed in should be freed from memory, because its reference count falls to zero.
If you don't Py_INCREF
and return the same object, that will still happen - the object's reference count will fall to 0 and you will have an invalid object in something_else
.
TL;DR: Yes, you should Py_INCREF
, because you created another reference to that object by returning it from the function.