
I'm using PyDict_SetItemString to add a long from a C struct into a Python dictionary. The full code is in the usn2dict function in here:
http://svn.timgolden.me.uk/extensions/change-journal/_usn.c
but the sort of thing I'm talking about is this:
PyDict_SetItemString ( dict, "RecordLength", PyLong_FromLongLong (usn_record->RecordLength) );
My understanding is that PyLong_FromLongLong passes its reference to my function, which then passes it to PyDict_Set... which INCREFs it. That means, I think, that my function should DECREF it before exit since I'm only creating it to store it in the dict. Is that correct?
In other words, should my code really do this?
record_length = PyLong_FromLongLong (usn_record->RecordLength); PyDict_SetItemString (dict, "RecordLength", record_length); Py_DECREF (record_length)
Thanks
TJG

Tim Golden <mail@timgolden.me.uk> writes:
Your understanding is correct.
Note that the same reasoning doesn't apply to, for instance, PyList_SetItem, which actually "steals" a reference to the value it receives. Fortunately, functions that behave in this fashion are very rare, and clearly documented to do so.
Yes, and don't forget to check for PyLong_FromLongLong returning NULL:
if (!record_length) { Py_DECREF(dict); /* presumably */ return NULL; }
(And of course the same goes for PyDict_SetItemString.)

Tim Golden <mail@timgolden.me.uk> writes:
Your understanding is correct.
Note that the same reasoning doesn't apply to, for instance, PyList_SetItem, which actually "steals" a reference to the value it receives. Fortunately, functions that behave in this fashion are very rare, and clearly documented to do so.
Yes, and don't forget to check for PyLong_FromLongLong returning NULL:
if (!record_length) { Py_DECREF(dict); /* presumably */ return NULL; }
(And of course the same goes for PyDict_SetItemString.)
participants (3)
-
Hrvoje Niksic
-
Stefan Behnel
-
Tim Golden