Details
-
Bug
-
Resolution: Done
-
P2: Important
-
None
-
1.1.0, 1.1.1, 1.1.2
-
None
-
6df4b307c5aec758ad954ab8717f5e85b44e2ae5
Description
While migrating our project from PySide v1.0.9 to v1.1.1 we've noticed memory leak.
We've found problem in PySide/QtCore/typesystem_core_common.xml
There's a converter template code for QMap->PyDict conversion:
<template name="cppmap_to_pymap_convertion"> PyObject* %out = PyDict_New(); %INTYPE::const_iterator it = %in.begin(); for (; it != %in.end(); ++it) { %INTYPE_0 key = it.key(); %INTYPE_1 value = it.value(); PyDict_SetItem(%out, %CONVERTTOPYTHON[%INTYPE_0](key), %CONVERTTOPYTHON[%INTYPE_1](value)); } return %out; </template>
But!
Python C-API documentation and sources tell us that PyDict_SetItem() INCREFs both the key and the value.
In Python 2.7.3 sources (http://svn.python.org/view/python/trunk/Objects/dictobject.c?view=markup)
Objects/dictobject.c: PyDict_SetItem() has
Py_INCREF(value); Py_INCREF(key);
at lines: 773,774
Since PyDict_SetItem() doesn't "steal" a reference to key and value, one should do Py_DECREF() manualy to key and value after call to PyDict_SetItem().
So, correct template looks following:
<template name="cppmap_to_pymap_convertion"> PyObject* %out = PyDict_New(); %INTYPE::const_iterator it = %in.begin(); for (; it != %in.end(); ++it) { %INTYPE_0 key = it.key(); %INTYPE_1 value = it.value(); PyObject* pyKey = %CONVERTTOPYTHON[%INTYPE_0](key); PyObject* pyValue = %CONVERTTOPYTHON[%INTYPE_1](value); PyDict_SetItem(%out, pyKey, pyValue); Py_DECREF(pyKey); Py_DECREF(pyValue); } return %out; </template>
We're using PySide v1.1.1.
We've checked latest pyside-qt4.8+1.1.2 and bug seems to be there also.
Corresponding Patch to for PySide 1.1.1 (file attached to ticket) is following:
--- typesystem_core_common.xml.v1.1.1 2012-04-19 03:06:40.000000000 +0400 +++ typesystem_core_common.xml 2012-09-10 12:32:33.214677526 +0400 @@ -658,9 +658,11 @@ for (; it != %in.end(); ++it) { %INTYPE_0 key = it.key(); %INTYPE_1 value = it.value(); - PyDict_SetItem(%out, - %CONVERTTOPYTHON[%INTYPE_0](key), - %CONVERTTOPYTHON[%INTYPE_1](value)); + PyObject* pyKey = %CONVERTTOPYTHON[%INTYPE_0](key); + PyObject* pyValue = %CONVERTTOPYTHON[%INTYPE_1](value); + PyDict_SetItem(%out, pyKey, pyValue); + Py_DECREF(pyKey); + Py_DECREF(pyValue); } return %out; </template>
Please apply this little patch, we're looking forward to help to maintain and use future versions of PySide.
Best regards.
Dennis Shilko.