[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