[capi-sig] Reference counts and dictionary creadtion

M.-A. Lemburg mal at egenix.com
Wed Dec 30 23:41:15 CET 2009


Dan Colesworthy wrote:
> Hello,
> 
>  
> 
> I am attempting to write a python extension in C to "glue" the ASIO SDK
> to python 2.5.4.  However I am really confused about reference counts.
> Below is a code snippet that "seems" to work, however I suspect that
> some of the object reference counts have been incremented too many
> times.
> 
>  
> 
> static PyObject *
> 
> getAsioInfo(PyObject *self, PyObject *args) {
> 
>    PyObject *dict = Py_None;
> 
>    if (loadAsioDriver (ASIO_DRIVER_NAME)) {
> 
>       if (ASIOInit (&asioDriverInfo.driverInfo) == ASE_OK){
> 
>          dict = PyDict_New();
> 
>          PyDict_SetItem(dict,
> 
>                         PyString_FromString("asioVersion"),
> 
>  
> PyInt_FromLong(asioDriverInfo.driverInfo.asioVersion) );
> 
>          PyDict_SetItem(dict, 
> 
>                         PyString_FromString("driverName"),
> 
>  
> PyString_FromString(asioDriverInfo.driverInfo.name) );
> 
>          return dict;
> 
>       }
> 
>    }
> 
>    return Null;
> 
> }
> 
>  
> 
> As nearly as I can tell from the Python source code, PyDict_SetItem will
> do a Py_INCREF on both the key and value parameters.  However, it looks
> as if PyInt_FromLong will incref the object it is returning - at least
> if it is a "small value". 

Object constructors will always return objects with a
refcount of 1.

When adding a key, value pair to a dictionary using PyDict_SetItem()
the function will take care of adjusting the refcounts.

After the call, you still own the objects key and value, so
you have to decref them if you no longer need them.

> Am I on the right track here?  Or am I better
> off doing something like:
> 
>  
> 
>             PyObject *str, *lng;
> 
>  
> 
>             str = PyString_FromString("asioVersion");
> 
>             lng = PyInt_FromLong(asioDriverInfo.driverInfo.asioVersion)
> );
> 
> PyDict_SetItem(dict, str, lng);
> 
> Py_DECREF(str);
> 
> Py_DECREF(lng);

See above. The second approach is likely what you need.

BTW: PyDict_SetItemString() is usually a better approach to
filling dictionaries that use often used keys. It interns the
key string for you, making subsequent lookups faster.

OTOH, if you plan to port to Python 3.x, you will likely want
to use Unicode objects as keys.

-- 
Marc-Andre Lemburg
eGenix.com

Professional Python Services directly from the Source  (#1, Dec 30 2009)
>>> Python/Zope Consulting and Support ...        http://www.egenix.com/
>>> mxODBC.Zope.Database.Adapter ...             http://zope.egenix.com/
>>> mxODBC, mxDateTime, mxTextTools ...        http://python.egenix.com/
________________________________________________________________________

::: Try our new mxODBC.Connect Python Database Interface for free ! ::::


   eGenix.com Software, Skills and Services GmbH  Pastor-Loeh-Str.48
    D-40764 Langenfeld, Germany. CEO Dipl.-Math. Marc-Andre Lemburg
           Registered at Amtsgericht Duesseldorf: HRB 46611
               http://www.egenix.com/company/contact/


More information about the capi-sig mailing list