[Tutor] Refcount in C extensions
Stefan Behnel
stefan_ml at behnel.de
Fri Jan 14 18:08:54 CET 2011
Izz ad-Din Ruhulessin, 14.01.2011 17:52:
> I am writing a Python C extension and I have some trouble understanding how
> reference counting works exactly. Though I think I understand the practice
> on simple operations (see my question at stackoverflow:
> http://stackoverflow.com/questions/4657764/py-incref-decref-when), but on
> more "complex" operations I cannot quite grasp it yet.
>
> For example, in the following helper function, do I need to DECREF or are
> all the references automatically destroyed when the function returns?
>
> double Py_GetAttr_DoubleFromFloat(PyObject *obj, const char *attr)
> {
> if ((PyObject_GetAttrString(obj, attr) == False) ||
> (PyObject_HasAttrString(obj, attr) == False)) {
> return -9999.0;
> }
This is C, nothing is done automatically. So you need to take care to
properly DECREF the references. one or two references are leaked in the above.
BTW, what's "False"? Did you mean "Py_False"?
> return PyFloat_AsDouble(PyNumber_Float(PyObject_GetAttrString(obj, attr)));
This leaks two references.
> Please share your thoughts, thanks in advance, kind regards,
Consider taking a look at Cython. It's an extension language that lets you
write Python code and generates C code for you. In Cython, your code above
simply spells
cdef double Py_GetAttr_DoubleFromFloat(obj, attr):
value = getattr(obj, attr, False)
if value is False:
return -9999.0
return value
Note that I'm using a Python object for 'attr' for performance reasons (and
for Python 3 portability).
I would expect that the above is at least a bit faster than your code, but
it handles ref-counting correctly.
Having said that, I'd frown a bit about an API that returns either False or
a double value ...
Stefan
More information about the Tutor
mailing list