@@ -379,18 +379,23 @@ PythonQt::PythonQt(int flags, const QByteArray& pythonQtModuleName)
379
379
PythonQt::~PythonQt () {
380
380
delete _p;
381
381
_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);
382
392
}
383
393
384
394
PythonQtPrivate::~PythonQtPrivate () {
385
395
delete _defaultImporter;
386
396
_defaultImporter = NULL ;
387
397
388
- {
389
- QHashIterator<QByteArray, PythonQtClassInfo *> i (_knownClassInfos);
390
- while (i.hasNext ()) {
391
- delete i.next ().value ();
392
- }
393
- }
398
+ qDeleteAll (_knownClassInfos);
394
399
395
400
PythonQtMethodInfo::cleanupCachedMethodInfos ();
396
401
PythonQtArgumentFrame::cleanupFreeList ();
@@ -409,7 +414,9 @@ void PythonQt::setRedirectStdInCallback(PythonQtInputChangedCB* callback, void *
409
414
410
415
// Backup original 'sys.stdin' if not yet done
411
416
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);
413
420
}
414
421
415
422
in = PythonQtStdInRedirectType.tp_new (&PythonQtStdInRedirectType, NULL , NULL );
@@ -428,15 +435,19 @@ void PythonQt::setRedirectStdInCallbackEnabled(bool enabled)
428
435
PythonQtObjectPtr sys;
429
436
sys.setNewRef (PyImport_ImportModule (" sys" ));
430
437
438
+ PythonQtObjectPtr stdin;
431
439
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" ));
434
442
}
435
443
} 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" ));
438
446
}
439
447
}
448
+ if (stdin) {
449
+ PyObject_SetAttrString (sys.object (), " stdin" , stdin);
450
+ }
440
451
}
441
452
442
453
PythonQtImportFileInterface* PythonQt::importInterface ()
@@ -448,7 +459,7 @@ void PythonQt::qObjectNoLongerWrappedCB(QObject* o)
448
459
{
449
460
if (_self->_p ->_noLongerWrappedCB ) {
450
461
(*_self->_p ->_noLongerWrappedCB )(o);
451
- };
462
+ }
452
463
}
453
464
454
465
void PythonQt::setQObjectMissingAttributeCallback (PythonQtQObjectMissingAttributeCB* cb)
@@ -525,6 +536,7 @@ void PythonQtPrivate::createPythonQtClassWrapper(PythonQtClassInfo* info, const
525
536
PythonQtClassInfo* outerClassInfo = lookupClassInfoAndCreateIfNotPresent (outerClass);
526
537
outerClassInfo->addNestedClass (info);
527
538
} else {
539
+ Py_INCREF (pyobj);
528
540
PyModule_AddObject (pack, info->className (), pyobj);
529
541
}
530
542
if (!module && package && strncmp (package, " Qt" , 2 ) == 0 ) {
@@ -534,6 +546,7 @@ void PythonQtPrivate::createPythonQtClassWrapper(PythonQtClassInfo* info, const
534
546
PyModule_AddObject (packageByName (" Qt" ), info->className (), pyobj);
535
547
}
536
548
info->setPythonQtClassWrapper (pyobj);
549
+ Py_DECREF (pyobj);
537
550
}
538
551
539
552
PyObject* PythonQtPrivate::wrapQObject (QObject* obj)
@@ -548,6 +561,7 @@ PyObject* PythonQtPrivate::wrapQObject(QObject* obj)
548
561
// address, so probably that C++ wrapper has been deleted earlier and
549
562
// now we see a QObject with the same address.
550
563
// Do not use the old wrapper anymore.
564
+ removeWrapperPointer (obj);
551
565
wrap = NULL ;
552
566
}
553
567
if (!wrap) {
@@ -733,6 +747,7 @@ PythonQtClassWrapper* PythonQtPrivate::createNewPythonQtClassWrapper(PythonQtCla
733
747
PyObject* typeDict = PyDict_New ();
734
748
PyObject* moduleName = PyObject_GetAttrString (parentModule, " __name__" );
735
749
PyDict_SetItemString (typeDict, " __module__" , moduleName);
750
+ Py_DECREF (moduleName);
736
751
737
752
PyObject* args = Py_BuildValue (" OOO" , className, baseClasses, typeDict);
738
753
@@ -769,6 +784,7 @@ PyObject* PythonQtPrivate::createNewPythonQtEnumWrapper(const char* enumName, Py
769
784
PyObject* module = PyObject_GetAttrString (parentObject, " __module__" );
770
785
PyObject* typeDict = PyDict_New ();
771
786
PyDict_SetItemString (typeDict, " __module__" , module );
787
+ Py_DECREF (module );
772
788
773
789
PyObject* args = Py_BuildValue (" OOO" , className, baseClasses, typeDict);
774
790
@@ -893,17 +909,21 @@ QVariant PythonQt::evalCode(PyObject* object, PyObject* pycode) {
893
909
QVariant result;
894
910
clearError ();
895
911
if (pycode) {
896
- PyObject* dict = NULL ;
897
- PyObject* globals = NULL ;
912
+ PythonQtObjectPtr dict;
913
+ PythonQtObjectPtr globals;
898
914
if (PyModule_Check (object)) {
899
915
dict = PyModule_GetDict (object);
900
916
globals = dict;
901
917
} else if (PyDict_Check (object)) {
902
918
dict = object;
903
919
globals = dict;
904
920
} 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 );
907
927
}
908
928
PyObject* r = NULL ;
909
929
if (dict) {
@@ -1048,24 +1068,30 @@ PythonQtObjectPtr PythonQt::createUniqueModule()
1048
1068
1049
1069
void PythonQt::addObject (PyObject* object, const QString& name, QObject* qObject)
1050
1070
{
1071
+ PyObject *wrappedObject = _p->wrapQObject (qObject);
1051
1072
if (PyModule_Check (object)) {
1052
- PyModule_AddObject (object, QStringToPythonCharPointer (name), _p->wrapQObject (qObject));
1073
+ Py_XINCREF (wrappedObject);
1074
+ PyModule_AddObject (object, QStringToPythonCharPointer (name), wrappedObject);
1053
1075
} else if (PyDict_Check (object)) {
1054
- PyDict_SetItemString (object, QStringToPythonCharPointer (name), _p-> wrapQObject (qObject) );
1076
+ PyDict_SetItemString (object, QStringToPythonCharPointer (name), wrappedObject );
1055
1077
} else {
1056
- PyObject_SetAttrString (object, QStringToPythonCharPointer (name), _p-> wrapQObject (qObject) );
1078
+ PyObject_SetAttrString (object, QStringToPythonCharPointer (name), wrappedObject );
1057
1079
}
1080
+ Py_XDECREF (wrappedObject);
1058
1081
}
1059
1082
1060
1083
void PythonQt::addVariable (PyObject* object, const QString& name, const QVariant& v)
1061
1084
{
1085
+ PyObject *value = PythonQtConv::QVariantToPyObject (v);
1062
1086
if (PyModule_Check (object)) {
1063
- PyModule_AddObject (object, QStringToPythonCharPointer (name), PythonQtConv::QVariantToPyObject (v));
1087
+ Py_XINCREF (value);
1088
+ PyModule_AddObject (object, QStringToPythonCharPointer (name), value);
1064
1089
} else if (PyDict_Check (object)) {
1065
- PyDict_SetItemString (object, QStringToPythonCharPointer (name), PythonQtConv::QVariantToPyObject (v) );
1090
+ PyDict_SetItemString (object, QStringToPythonCharPointer (name), value );
1066
1091
} else {
1067
- PyObject_SetAttrString (object, QStringToPythonCharPointer (name), PythonQtConv::QVariantToPyObject (v) );
1092
+ PyObject_SetAttrString (object, QStringToPythonCharPointer (name), value );
1068
1093
}
1094
+ Py_XDECREF (value);
1069
1095
}
1070
1096
1071
1097
void PythonQt::removeVariable (PyObject* object, const QString& name)
@@ -1107,7 +1133,7 @@ QStringList PythonQt::introspection(PyObject* module, const QString& objectname,
1107
1133
} else {
1108
1134
object = lookupObject (module , objectname);
1109
1135
if (!object && type == CallOverloads) {
1110
- PyObject* dict = lookupObject (module , " __builtins__" );
1136
+ PythonQtObjectPtr dict = lookupObject (module , " __builtins__" );
1111
1137
if (dict) {
1112
1138
object = PyDict_GetItemString (dict, QStringToPythonCharPointer (objectname));
1113
1139
}
@@ -1159,36 +1185,33 @@ QStringList PythonQt::introspectObject(PyObject* object, ObjectType type)
1159
1185
}
1160
1186
}
1161
1187
} else {
1162
- PyObject* keys = NULL ;
1188
+ PythonQtObjectPtr keys;
1163
1189
bool isDict = false ;
1164
1190
if (PyDict_Check (object)) {
1165
- keys = PyDict_Keys (object);
1191
+ keys. setNewRef ( PyDict_Keys (object) );
1166
1192
isDict = true ;
1167
1193
} else {
1168
1194
#if defined(MEVISLAB) && !defined(PY3K)
1169
1195
int oldPy3kWarningFlag = Py_Py3kWarningFlag;
1170
1196
Py_Py3kWarningFlag = 0 ; // temporarily disable Python 3 warnings
1171
- keys = PyObject_Dir (object);
1197
+ keys. setNewRef ( PyObject_Dir (object) );
1172
1198
Py_Py3kWarningFlag = oldPy3kWarningFlag;
1173
1199
#else
1174
- keys = PyObject_Dir (object);
1200
+ keys. setNewRef ( PyObject_Dir (object) );
1175
1201
#endif
1176
1202
}
1177
1203
if (keys) {
1178
1204
int count = PyList_Size (keys);
1179
- PyObject* key;
1180
- PyObject* value;
1181
- QString keystr;
1182
1205
for (int i = 0 ;i<count;i++) {
1183
- key = PyList_GetItem (keys,i);
1206
+ PythonQtObjectPtr key = PyList_GetItem (keys,i);
1207
+ PythonQtObjectPtr value;
1184
1208
if (isDict) {
1185
1209
value = PyDict_GetItem (object, key);
1186
- Py_INCREF (value);
1187
1210
} else {
1188
- value = PyObject_GetAttr (object, key);
1211
+ value. setNewRef ( PyObject_GetAttr (object, key) );
1189
1212
}
1190
1213
if (!value) continue ;
1191
- keystr = PyString_AsString (key);
1214
+ QString keystr = PyString_AsString (key);
1192
1215
static const QString underscoreStr (" __tmp" );
1193
1216
if (!keystr.startsWith (underscoreStr)) {
1194
1217
switch (type) {
@@ -1233,9 +1256,7 @@ QStringList PythonQt::introspectObject(PyObject* object, ObjectType type)
1233
1256
std::cerr << " PythonQt: introspection: unknown case" << " , in " << __FILE__ << " :" << __LINE__ << std::endl;
1234
1257
}
1235
1258
}
1236
- Py_DECREF (value);
1237
1259
}
1238
- Py_DECREF (keys);
1239
1260
}
1240
1261
}
1241
1262
PyErr_Clear ();
@@ -1288,6 +1309,7 @@ QStringList PythonQt::introspectType(const QString& typeName, ObjectType type)
1288
1309
PyObject* typeObject = getObjectByType (typeName);
1289
1310
if (typeObject) {
1290
1311
object = PyObject_GetAttrString (typeObject, QStringToPythonCharPointer (memberName));
1312
+ Py_DECREF (typeObject);
1291
1313
}
1292
1314
}
1293
1315
if (object) {
@@ -1359,6 +1381,7 @@ PyObject* PythonQt::callAndReturnPyObject(PyObject* callable, const QVariantList
1359
1381
PyObject* arg = PythonQtConv::QVariantToPyObject (it.value ());
1360
1382
if (arg) {
1361
1383
PyDict_SetItemString (pkwargs, QStringToPythonCharPointer (it.key ()), arg);
1384
+ Py_DECREF (arg);
1362
1385
} else {
1363
1386
err = true ;
1364
1387
break ;
@@ -1750,7 +1773,7 @@ void PythonQt::initPythonQtModule(bool redirectStdOut, const QByteArray& pythonQ
1750
1773
}
1751
1774
#ifdef PY3K
1752
1775
PythonQtModuleDef.m_name = name.constData ();
1753
- _p->_pythonQtModule = PyModule_Create (&PythonQtModuleDef);
1776
+ _p->_pythonQtModule . setNewRef ( PyModule_Create (&PythonQtModuleDef) );
1754
1777
#else
1755
1778
_p->_pythonQtModule = Py_InitModule (name.constData (), PythonQtMethods);
1756
1779
#endif
@@ -1790,7 +1813,11 @@ void PythonQt::initPythonQtModule(bool redirectStdOut, const QByteArray& pythonQ
1790
1813
Py_XDECREF (old_module_names);
1791
1814
1792
1815
#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);
1794
1821
#endif
1795
1822
}
1796
1823
@@ -1810,7 +1837,8 @@ QString PythonQt::getReturnTypeOfWrappedMethod(PyObject* module, const QString&
1810
1837
1811
1838
QString PythonQt::getReturnTypeOfWrappedMethod (const QString& typeName, const QString& methodName)
1812
1839
{
1813
- PythonQtObjectPtr typeObject = getObjectByType (typeName);
1840
+ PythonQtObjectPtr typeObject;
1841
+ typeObject.setNewRef (getObjectByType (typeName));
1814
1842
if (typeObject.isNull ()) {
1815
1843
return " " ;
1816
1844
}
@@ -2105,10 +2133,12 @@ const QMetaObject* PythonQtPrivate::buildDynamicMetaObject(PythonQtClassWrapper*
2105
2133
builder.setClassName (((PyTypeObject*)type)->tp_name );
2106
2134
2107
2135
PyObject* dict = ((PyTypeObject*)type)->tp_dict ;
2108
- Py_ssize_t pos = NULL ;
2136
+ Py_ssize_t pos = 0 ;
2109
2137
PyObject* value = NULL ;
2110
2138
PyObject* key = NULL ;
2111
- static PyObject* qtSlots = PyString_FromString (" _qtSlots" );
2139
+ static PyObject* qtSlots = NULL ;
2140
+ if (!qtSlots)
2141
+ qtSlots = PyString_FromString (" _qtSlots" );
2112
2142
2113
2143
bool needsMetaObject = false ;
2114
2144
// Iterate over all members and check if they affect the QMetaObject:
@@ -2126,7 +2156,7 @@ const QMetaObject* PythonQtPrivate::buildDynamicMetaObject(PythonQtClassWrapper*
2126
2156
}
2127
2157
}
2128
2158
}
2129
- pos = NULL ;
2159
+ pos = 0 ;
2130
2160
value = NULL ;
2131
2161
key = NULL ;
2132
2162
// 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*
2160
2190
}
2161
2191
if (PyFunction_Check (value) && PyObject_HasAttr (value, qtSlots)) {
2162
2192
// 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));
2164
2195
Py_ssize_t count = PyList_Size (signatures);
2165
2196
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);
2167
2198
QByteArray sig = PyString_AsString (signature);
2168
2199
// Split the return type and the rest of the signature,
2169
2200
// no spaces should be in the rest of the signature...
@@ -2209,9 +2240,11 @@ int PythonQtPrivate::handleMetaCall(QObject* object, PythonQtInstanceWrapper* wr
2209
2240
}
2210
2241
PythonQtProperty* prop = NULL ;
2211
2242
// 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));
2213
2246
if (maybeProp && PythonQtProperty_Check (maybeProp)) {
2214
- prop = (PythonQtProperty*)maybeProp;
2247
+ prop = (PythonQtProperty*)maybeProp. object () ;
2215
2248
} else {
2216
2249
return id - methodCount;
2217
2250
}
@@ -2228,7 +2261,7 @@ int PythonQtPrivate::handleMetaCall(QObject* object, PythonQtInstanceWrapper* wr
2228
2261
2229
2262
PyObject* value = prop->data ->callGetter ((PyObject*)wrapper);
2230
2263
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?
2232
2265
Py_DECREF (value);
2233
2266
return (result == NULL ? -1 : 0 );
2234
2267
} else {
@@ -2267,17 +2300,15 @@ QString PythonQtPrivate::getSignature(PyObject* object)
2267
2300
PyMethodObject* method = NULL ;
2268
2301
PyFunctionObject* func = NULL ;
2269
2302
2270
- bool decrefMethod = false ;
2271
-
2272
2303
if (PythonQtUtils::isPythonClassType (object)) {
2273
2304
method = (PyMethodObject*)PyObject_GetAttrString (object, " __init__" );
2274
- decrefMethod = true ;
2275
2305
} else if (object->ob_type == &PyFunction_Type) {
2276
2306
func = (PyFunctionObject*)object;
2277
2307
} else if (object->ob_type == &PyMethod_Type) {
2278
2308
method = (PyMethodObject*)object;
2309
+ Py_XINCREF (method);
2279
2310
}
2280
- if (method) {
2311
+ if (method) {
2281
2312
if (PyFunction_Check (method->im_func )) {
2282
2313
func = (PyFunctionObject*)method->im_func ;
2283
2314
} else if (isMethodDescriptor ((PyObject*)method)) {
@@ -2384,9 +2415,7 @@ QString PythonQtPrivate::getSignature(PyObject* object)
2384
2415
signature = funcName + " (" + signature + " )" ;
2385
2416
}
2386
2417
2387
- if (method && decrefMethod) {
2388
- Py_DECREF (method);
2389
- }
2418
+ Py_XDECREF (method);
2390
2419
}
2391
2420
2392
2421
return signature;
@@ -2451,7 +2480,7 @@ PythonQtClassInfo* PythonQtPrivate::getClassInfo( const QByteArray& className )
2451
2480
if (_knownLazyClasses.contains (className)) {
2452
2481
QByteArray module = _knownLazyClasses.value (className);
2453
2482
recursion = true ;
2454
- PyImport_ImportModule (module );
2483
+ PyImport_ImportModule (module ); // FIXME: reference leaked
2455
2484
recursion = false ;
2456
2485
result = _knownClassInfos.value (className);
2457
2486
if (!result) {
0 commit comments