@@ -379,18 +379,23 @@ PythonQt::PythonQt(int flags, const QByteArray& pythonQtModuleName)
379379PythonQt::~PythonQt () {
380380 delete _p;
381381 _p = NULL ;
382+
383+ Py_DECREF (&PythonQtSlotFunction_Type);
384+ Py_DECREF (&PythonQtSignalFunction_Type);
385+ Py_DECREF (&PythonQtSlotDecorator_Type);
386+ Py_DECREF (&PythonQtProperty_Type);
387+ Py_DECREF (&PythonQtBoolResult_Type);
388+ Py_DECREF (&PythonQtClassWrapper_Type);
389+ Py_DECREF (&PythonQtInstanceWrapper_Type);
390+ Py_DECREF (&PythonQtStdOutRedirectType);
391+ Py_DECREF (&PythonQtStdInRedirectType);
382392}
383393
384394PythonQtPrivate::~PythonQtPrivate () {
385395 delete _defaultImporter;
386396 _defaultImporter = NULL ;
387397
388- {
389- QHashIterator<QByteArray, PythonQtClassInfo *> i (_knownClassInfos);
390- while (i.hasNext ()) {
391- delete i.next ().value ();
392- }
393- }
398+ qDeleteAll (_knownClassInfos);
394399
395400 PythonQtMethodInfo::cleanupCachedMethodInfos ();
396401 PythonQtArgumentFrame::cleanupFreeList ();
@@ -409,7 +414,9 @@ void PythonQt::setRedirectStdInCallback(PythonQtInputChangedCB* callback, void *
409414
410415 // Backup original 'sys.stdin' if not yet done
411416 if ( !PyObject_HasAttrString (sys.object (), " pythonqt_original_stdin" ) ) {
412- PyObject_SetAttrString (sys.object (), " pythonqt_original_stdin" , PyObject_GetAttrString (sys.object (), " stdin" ));
417+ PyObject *stdin = PyObject_GetAttrString (sys.object (), " stdin" );
418+ PyObject_SetAttrString (sys.object (), " pythonqt_original_stdin" , stdin);
419+ Py_XDECREF (stdin);
413420 }
414421
415422 in = PythonQtStdInRedirectType.tp_new (&PythonQtStdInRedirectType, NULL , NULL );
@@ -428,15 +435,19 @@ void PythonQt::setRedirectStdInCallbackEnabled(bool enabled)
428435 PythonQtObjectPtr sys;
429436 sys.setNewRef (PyImport_ImportModule (" sys" ));
430437
438+ PythonQtObjectPtr stdin;
431439 if (enabled) {
432- if ( ! PyObject_HasAttrString (sys.object (), " pythonqt_stdin" ) ) {
433- PyObject_SetAttrString (sys. object (), " stdin " , PyObject_GetAttrString (sys.object (), " pythonqt_stdin" ));
440+ if ( PyObject_HasAttrString (sys.object (), " pythonqt_stdin" ) ) {
441+ stdin. setNewRef ( PyObject_GetAttrString (sys.object (), " pythonqt_stdin" ));
434442 }
435443 } else {
436- if ( ! PyObject_HasAttrString (sys.object (), " pythonqt_original_stdin" ) ) {
437- PyObject_SetAttrString (sys. object (), " stdin " , PyObject_GetAttrString (sys.object (), " pythonqt_original_stdin" ));
444+ if ( PyObject_HasAttrString (sys.object (), " pythonqt_original_stdin" ) ) {
445+ stdin. setNewRef ( PyObject_GetAttrString (sys.object (), " pythonqt_original_stdin" ));
438446 }
439447 }
448+ if (stdin) {
449+ PyObject_SetAttrString (sys.object (), " stdin" , stdin);
450+ }
440451}
441452
442453PythonQtImportFileInterface* PythonQt::importInterface ()
@@ -448,7 +459,7 @@ void PythonQt::qObjectNoLongerWrappedCB(QObject* o)
448459{
449460 if (_self->_p ->_noLongerWrappedCB ) {
450461 (*_self->_p ->_noLongerWrappedCB )(o);
451- };
462+ }
452463}
453464
454465void PythonQt::setQObjectMissingAttributeCallback (PythonQtQObjectMissingAttributeCB* cb)
@@ -525,6 +536,7 @@ void PythonQtPrivate::createPythonQtClassWrapper(PythonQtClassInfo* info, const
525536 PythonQtClassInfo* outerClassInfo = lookupClassInfoAndCreateIfNotPresent (outerClass);
526537 outerClassInfo->addNestedClass (info);
527538 } else {
539+ Py_INCREF (pyobj);
528540 PyModule_AddObject (pack, info->className (), pyobj);
529541 }
530542 if (!module && package && strncmp (package, " Qt" , 2 ) == 0 ) {
@@ -534,6 +546,7 @@ void PythonQtPrivate::createPythonQtClassWrapper(PythonQtClassInfo* info, const
534546 PyModule_AddObject (packageByName (" Qt" ), info->className (), pyobj);
535547 }
536548 info->setPythonQtClassWrapper (pyobj);
549+ Py_DECREF (pyobj);
537550}
538551
539552PyObject* PythonQtPrivate::wrapQObject (QObject* obj)
@@ -548,6 +561,7 @@ PyObject* PythonQtPrivate::wrapQObject(QObject* obj)
548561 // address, so probably that C++ wrapper has been deleted earlier and
549562 // now we see a QObject with the same address.
550563 // Do not use the old wrapper anymore.
564+ removeWrapperPointer (obj);
551565 wrap = NULL ;
552566 }
553567 if (!wrap) {
@@ -733,6 +747,7 @@ PythonQtClassWrapper* PythonQtPrivate::createNewPythonQtClassWrapper(PythonQtCla
733747 PyObject* typeDict = PyDict_New ();
734748 PyObject* moduleName = PyObject_GetAttrString (parentModule, " __name__" );
735749 PyDict_SetItemString (typeDict, " __module__" , moduleName);
750+ Py_DECREF (moduleName);
736751
737752 PyObject* args = Py_BuildValue (" OOO" , className, baseClasses, typeDict);
738753
@@ -769,6 +784,7 @@ PyObject* PythonQtPrivate::createNewPythonQtEnumWrapper(const char* enumName, Py
769784 PyObject* module = PyObject_GetAttrString (parentObject, " __module__" );
770785 PyObject* typeDict = PyDict_New ();
771786 PyDict_SetItemString (typeDict, " __module__" , module );
787+ Py_DECREF (module );
772788
773789 PyObject* args = Py_BuildValue (" OOO" , className, baseClasses, typeDict);
774790
@@ -893,17 +909,21 @@ QVariant PythonQt::evalCode(PyObject* object, PyObject* pycode) {
893909 QVariant result;
894910 clearError ();
895911 if (pycode) {
896- PyObject* dict = NULL ;
897- PyObject* globals = NULL ;
912+ PythonQtObjectPtr dict;
913+ PythonQtObjectPtr globals;
898914 if (PyModule_Check (object)) {
899915 dict = PyModule_GetDict (object);
900916 globals = dict;
901917 } else if (PyDict_Check (object)) {
902918 dict = object;
903919 globals = dict;
904920 } else {
905- dict = PyObject_GetAttrString (object, " __dict__" );
906- globals = PyObject_GetAttrString (PyImport_ImportModule (PyString_AS_STRING (PyObject_GetAttrString (object, " __module__" )))," __dict__" );
921+ PyObject *moduleName = PyObject_GetAttrString (object, " __module__" );
922+ PyObject *module = PyImport_ImportModule (PyString_AS_STRING (moduleName));
923+ dict.setNewRef (PyObject_GetAttrString (object, " __dict__" ));
924+ globals.setNewRef (PyObject_GetAttrString (module , " __dict__" ));
925+ Py_XDECREF (moduleName);
926+ Py_XDECREF (module );
907927 }
908928 PyObject* r = NULL ;
909929 if (dict) {
@@ -1048,24 +1068,30 @@ PythonQtObjectPtr PythonQt::createUniqueModule()
10481068
10491069void PythonQt::addObject (PyObject* object, const QString& name, QObject* qObject)
10501070{
1071+ PyObject *wrappedObject = _p->wrapQObject (qObject);
10511072 if (PyModule_Check (object)) {
1052- PyModule_AddObject (object, QStringToPythonCharPointer (name), _p->wrapQObject (qObject));
1073+ Py_XINCREF (wrappedObject);
1074+ PyModule_AddObject (object, QStringToPythonCharPointer (name), wrappedObject);
10531075 } else if (PyDict_Check (object)) {
1054- PyDict_SetItemString (object, QStringToPythonCharPointer (name), _p-> wrapQObject (qObject) );
1076+ PyDict_SetItemString (object, QStringToPythonCharPointer (name), wrappedObject );
10551077 } else {
1056- PyObject_SetAttrString (object, QStringToPythonCharPointer (name), _p-> wrapQObject (qObject) );
1078+ PyObject_SetAttrString (object, QStringToPythonCharPointer (name), wrappedObject );
10571079 }
1080+ Py_XDECREF (wrappedObject);
10581081}
10591082
10601083void PythonQt::addVariable (PyObject* object, const QString& name, const QVariant& v)
10611084{
1085+ PyObject *value = PythonQtConv::QVariantToPyObject (v);
10621086 if (PyModule_Check (object)) {
1063- PyModule_AddObject (object, QStringToPythonCharPointer (name), PythonQtConv::QVariantToPyObject (v));
1087+ Py_XINCREF (value);
1088+ PyModule_AddObject (object, QStringToPythonCharPointer (name), value);
10641089 } else if (PyDict_Check (object)) {
1065- PyDict_SetItemString (object, QStringToPythonCharPointer (name), PythonQtConv::QVariantToPyObject (v) );
1090+ PyDict_SetItemString (object, QStringToPythonCharPointer (name), value );
10661091 } else {
1067- PyObject_SetAttrString (object, QStringToPythonCharPointer (name), PythonQtConv::QVariantToPyObject (v) );
1092+ PyObject_SetAttrString (object, QStringToPythonCharPointer (name), value );
10681093 }
1094+ Py_XDECREF (value);
10691095}
10701096
10711097void PythonQt::removeVariable (PyObject* object, const QString& name)
@@ -1107,7 +1133,7 @@ QStringList PythonQt::introspection(PyObject* module, const QString& objectname,
11071133 } else {
11081134 object = lookupObject (module , objectname);
11091135 if (!object && type == CallOverloads) {
1110- PyObject* dict = lookupObject (module , " __builtins__" );
1136+ PythonQtObjectPtr dict = lookupObject (module , " __builtins__" );
11111137 if (dict) {
11121138 object = PyDict_GetItemString (dict, QStringToPythonCharPointer (objectname));
11131139 }
@@ -1159,36 +1185,33 @@ QStringList PythonQt::introspectObject(PyObject* object, ObjectType type)
11591185 }
11601186 }
11611187 } else {
1162- PyObject* keys = NULL ;
1188+ PythonQtObjectPtr keys;
11631189 bool isDict = false ;
11641190 if (PyDict_Check (object)) {
1165- keys = PyDict_Keys (object);
1191+ keys. setNewRef ( PyDict_Keys (object) );
11661192 isDict = true ;
11671193 } else {
11681194#if defined(MEVISLAB) && !defined(PY3K)
11691195 int oldPy3kWarningFlag = Py_Py3kWarningFlag;
11701196 Py_Py3kWarningFlag = 0 ; // temporarily disable Python 3 warnings
1171- keys = PyObject_Dir (object);
1197+ keys. setNewRef ( PyObject_Dir (object) );
11721198 Py_Py3kWarningFlag = oldPy3kWarningFlag;
11731199#else
1174- keys = PyObject_Dir (object);
1200+ keys. setNewRef ( PyObject_Dir (object) );
11751201#endif
11761202 }
11771203 if (keys) {
11781204 int count = PyList_Size (keys);
1179- PyObject* key;
1180- PyObject* value;
1181- QString keystr;
11821205 for (int i = 0 ;i<count;i++) {
1183- key = PyList_GetItem (keys,i);
1206+ PythonQtObjectPtr key = PyList_GetItem (keys,i);
1207+ PythonQtObjectPtr value;
11841208 if (isDict) {
11851209 value = PyDict_GetItem (object, key);
1186- Py_INCREF (value);
11871210 } else {
1188- value = PyObject_GetAttr (object, key);
1211+ value. setNewRef ( PyObject_GetAttr (object, key) );
11891212 }
11901213 if (!value) continue ;
1191- keystr = PyString_AsString (key);
1214+ QString keystr = PyString_AsString (key);
11921215 static const QString underscoreStr (" __tmp" );
11931216 if (!keystr.startsWith (underscoreStr)) {
11941217 switch (type) {
@@ -1233,9 +1256,7 @@ QStringList PythonQt::introspectObject(PyObject* object, ObjectType type)
12331256 std::cerr << " PythonQt: introspection: unknown case" << " , in " << __FILE__ << " :" << __LINE__ << std::endl;
12341257 }
12351258 }
1236- Py_DECREF (value);
12371259 }
1238- Py_DECREF (keys);
12391260 }
12401261 }
12411262 PyErr_Clear ();
@@ -1288,6 +1309,7 @@ QStringList PythonQt::introspectType(const QString& typeName, ObjectType type)
12881309 PyObject* typeObject = getObjectByType (typeName);
12891310 if (typeObject) {
12901311 object = PyObject_GetAttrString (typeObject, QStringToPythonCharPointer (memberName));
1312+ Py_DECREF (typeObject);
12911313 }
12921314 }
12931315 if (object) {
@@ -1359,6 +1381,7 @@ PyObject* PythonQt::callAndReturnPyObject(PyObject* callable, const QVariantList
13591381 PyObject* arg = PythonQtConv::QVariantToPyObject (it.value ());
13601382 if (arg) {
13611383 PyDict_SetItemString (pkwargs, QStringToPythonCharPointer (it.key ()), arg);
1384+ Py_DECREF (arg);
13621385 } else {
13631386 err = true ;
13641387 break ;
@@ -1750,7 +1773,7 @@ void PythonQt::initPythonQtModule(bool redirectStdOut, const QByteArray& pythonQ
17501773 }
17511774#ifdef PY3K
17521775 PythonQtModuleDef.m_name = name.constData ();
1753- _p->_pythonQtModule = PyModule_Create (&PythonQtModuleDef);
1776+ _p->_pythonQtModule . setNewRef ( PyModule_Create (&PythonQtModuleDef) );
17541777#else
17551778 _p->_pythonQtModule = Py_InitModule (name.constData (), PythonQtMethods);
17561779#endif
@@ -1790,7 +1813,11 @@ void PythonQt::initPythonQtModule(bool redirectStdOut, const QByteArray& pythonQ
17901813 Py_XDECREF (old_module_names);
17911814
17921815#ifdef PY3K
1793- PyDict_SetItem (PyObject_GetAttrString (sys.object (), " modules" ), PyUnicode_FromString (name.constData ()), _p->_pythonQtModule .object ());
1816+ PyObject *modules = PyObject_GetAttrString (sys.object (), " modules" );
1817+ PyObject *nameObj = PyUnicode_FromString (name.constData ());
1818+ PyDict_SetItem (modules, nameObj, _p->_pythonQtModule .object ());
1819+ Py_XDECREF (modules);
1820+ Py_XDECREF (nameObj);
17941821#endif
17951822}
17961823
@@ -1810,7 +1837,8 @@ QString PythonQt::getReturnTypeOfWrappedMethod(PyObject* module, const QString&
18101837
18111838QString PythonQt::getReturnTypeOfWrappedMethod (const QString& typeName, const QString& methodName)
18121839{
1813- PythonQtObjectPtr typeObject = getObjectByType (typeName);
1840+ PythonQtObjectPtr typeObject;
1841+ typeObject.setNewRef (getObjectByType (typeName));
18141842 if (typeObject.isNull ()) {
18151843 return " " ;
18161844 }
@@ -2105,10 +2133,12 @@ const QMetaObject* PythonQtPrivate::buildDynamicMetaObject(PythonQtClassWrapper*
21052133 builder.setClassName (((PyTypeObject*)type)->tp_name );
21062134
21072135 PyObject* dict = ((PyTypeObject*)type)->tp_dict ;
2108- Py_ssize_t pos = NULL ;
2136+ Py_ssize_t pos = 0 ;
21092137 PyObject* value = NULL ;
21102138 PyObject* key = NULL ;
2111- static PyObject* qtSlots = PyString_FromString (" _qtSlots" );
2139+ static PyObject* qtSlots = NULL ;
2140+ if (!qtSlots)
2141+ qtSlots = PyString_FromString (" _qtSlots" );
21122142
21132143 bool needsMetaObject = false ;
21142144 // Iterate over all members and check if they affect the QMetaObject:
@@ -2126,7 +2156,7 @@ const QMetaObject* PythonQtPrivate::buildDynamicMetaObject(PythonQtClassWrapper*
21262156 }
21272157 }
21282158 }
2129- pos = NULL ;
2159+ pos = 0 ;
21302160 value = NULL ;
21312161 key = NULL ;
21322162 // Now look for slots: (this is a bug in QMetaObjectBuilder, all signals need to be added first)
@@ -2160,10 +2190,11 @@ const QMetaObject* PythonQtPrivate::buildDynamicMetaObject(PythonQtClassWrapper*
21602190 }
21612191 if (PyFunction_Check (value) && PyObject_HasAttr (value, qtSlots)) {
21622192 // A function which has a "_qtSlots" signature list, add the slots to the meta object
2163- PyObject* signatures = PyObject_GetAttr (value, qtSlots);
2193+ PythonQtObjectPtr signatures;
2194+ signatures.setNewRef (PyObject_GetAttr (value, qtSlots));
21642195 Py_ssize_t count = PyList_Size (signatures);
21652196 for (Py_ssize_t i = 0 ; i < count; i++) {
2166- PyObject* signature = PyList_GET_ITEM (signatures, i);
2197+ PyObject* signature = PyList_GET_ITEM (signatures. object () , i);
21672198 QByteArray sig = PyString_AsString (signature);
21682199 // Split the return type and the rest of the signature,
21692200 // no spaces should be in the rest of the signature...
@@ -2209,9 +2240,11 @@ int PythonQtPrivate::handleMetaCall(QObject* object, PythonQtInstanceWrapper* wr
22092240 }
22102241 PythonQtProperty* prop = NULL ;
22112242 // Get directly from the Python class, since we don't want to get the value of the property
2212- PyObject* maybeProp = PyBaseObject_Type.tp_getattro ((PyObject*)wrapper, PyString_FromString (metaProp.name ()));
2243+ PythonQtObjectPtr name, maybeProp;
2244+ name.setNewRef (PyString_FromString (metaProp.name ()));
2245+ maybeProp.setNewRef (PyBaseObject_Type.tp_getattro ((PyObject*)wrapper, name));
22132246 if (maybeProp && PythonQtProperty_Check (maybeProp)) {
2214- prop = (PythonQtProperty*)maybeProp;
2247+ prop = (PythonQtProperty*)maybeProp. object () ;
22152248 } else {
22162249 return id - methodCount;
22172250 }
@@ -2228,7 +2261,7 @@ int PythonQtPrivate::handleMetaCall(QObject* object, PythonQtInstanceWrapper* wr
22282261
22292262 PyObject* value = prop->data ->callGetter ((PyObject*)wrapper);
22302263 if (value) {
2231- void * result = PythonQtConv::ConvertPythonToQt (info, value, false , NULL , args[0 ]);
2264+ void * result = PythonQtConv::ConvertPythonToQt (info, value, false , NULL , args[0 ]); // FIXME: what happens with result? free?
22322265 Py_DECREF (value);
22332266 return (result == NULL ? -1 : 0 );
22342267 } else {
@@ -2267,17 +2300,15 @@ QString PythonQtPrivate::getSignature(PyObject* object)
22672300 PyMethodObject* method = NULL ;
22682301 PyFunctionObject* func = NULL ;
22692302
2270- bool decrefMethod = false ;
2271-
22722303 if (PythonQtUtils::isPythonClassType (object)) {
22732304 method = (PyMethodObject*)PyObject_GetAttrString (object, " __init__" );
2274- decrefMethod = true ;
22752305 } else if (object->ob_type == &PyFunction_Type) {
22762306 func = (PyFunctionObject*)object;
22772307 } else if (object->ob_type == &PyMethod_Type) {
22782308 method = (PyMethodObject*)object;
2309+ Py_XINCREF (method);
22792310 }
2280- if (method) {
2311+ if (method) {
22812312 if (PyFunction_Check (method->im_func )) {
22822313 func = (PyFunctionObject*)method->im_func ;
22832314 } else if (isMethodDescriptor ((PyObject*)method)) {
@@ -2384,9 +2415,7 @@ QString PythonQtPrivate::getSignature(PyObject* object)
23842415 signature = funcName + " (" + signature + " )" ;
23852416 }
23862417
2387- if (method && decrefMethod) {
2388- Py_DECREF (method);
2389- }
2418+ Py_XDECREF (method);
23902419 }
23912420
23922421 return signature;
@@ -2451,7 +2480,7 @@ PythonQtClassInfo* PythonQtPrivate::getClassInfo( const QByteArray& className )
24512480 if (_knownLazyClasses.contains (className)) {
24522481 QByteArray module = _knownLazyClasses.value (className);
24532482 recursion = true ;
2454- PyImport_ImportModule (module );
2483+ PyImport_ImportModule (module ); // FIXME: reference leaked
24552484 recursion = false ;
24562485 result = _knownClassInfos.value (className);
24572486 if (!result) {
0 commit comments