@@ -435,6 +435,16 @@ PythonQt::PythonQt(int flags, const QByteArray& pythonQtModuleName)
435435PythonQt::~PythonQt () {
436436 delete _p;
437437 _p = nullptr ;
438+
439+ Py_DECREF (&PythonQtSlotFunction_Type);
440+ Py_DECREF (&PythonQtSignalFunction_Type);
441+ Py_DECREF (&PythonQtSlotDecorator_Type);
442+ Py_DECREF (&PythonQtProperty_Type);
443+ Py_DECREF (&PythonQtBoolResult_Type);
444+ Py_DECREF (&PythonQtClassWrapper_Type);
445+ Py_DECREF (&PythonQtInstanceWrapper_Type);
446+ Py_DECREF (&PythonQtStdOutRedirectType);
447+ Py_DECREF (&PythonQtStdInRedirectType);
438448}
439449
440450PythonQtPrivate::~PythonQtPrivate () {
@@ -446,7 +456,7 @@ PythonQtPrivate::~PythonQtPrivate() {
446456 }
447457
448458 PythonQtMethodInfo::cleanupCachedMethodInfos ();
449- PythonQtArgumentFrame::cleanupFreeList ();
459+ PythonQtArgumentFrame::cleanupFreeList ();
450460}
451461
452462void PythonQtPrivate::setTaskDoneCallback (const PythonQtObjectPtr & callable)
@@ -509,7 +519,9 @@ void PythonQt::setRedirectStdInCallback(PythonQtInputChangedCB* callback, void *
509519
510520 // Backup original 'sys.stdin' if not yet done
511521 if ( !PyObject_HasAttrString (sys.object (), " pythonqt_original_stdin" ) ) {
512- PyObject_SetAttrString (sys.object (), " pythonqt_original_stdin" , PyObject_GetAttrString (sys.object (), " stdin" ));
522+ PyObject *_stdin = PyObject_GetAttrString (sys.object (), " stdin" );
523+ PyObject_SetAttrString (sys.object (), " pythonqt_original_stdin" , _stdin);
524+ Py_XDECREF (_stdin);
513525 }
514526
515527 in = PythonQtStdInRedirectType.tp_new (&PythonQtStdInRedirectType, nullptr , nullptr );
@@ -526,15 +538,16 @@ void PythonQt::setRedirectStdInCallback(PythonQtInputChangedCB* callback, void *
526538void PythonQt::setRedirectStdInCallbackEnabled (bool enabled)
527539{
528540 PythonQtObjectPtr sys;
541+ PythonQtObjectPtr _stdin;
529542 sys.setNewRef (PyImport_ImportModule (" sys" ));
530543
531544 if (enabled) {
532- if ( ! PyObject_HasAttrString (sys.object (), " pythonqt_stdin" ) ) {
533- PyObject_SetAttrString (sys. object (), " stdin " , PyObject_GetAttrString (sys.object (), " pythonqt_stdin" ));
545+ if ( PyObject_HasAttrString (sys.object (), " pythonqt_stdin" ) ) {
546+ _stdin. setNewRef ( PyObject_GetAttrString (sys.object (), " pythonqt_stdin" ));
534547 }
535548 } else {
536- if ( ! PyObject_HasAttrString (sys.object (), " pythonqt_original_stdin" ) ) {
537- PyObject_SetAttrString (sys. object (), " stdin " , PyObject_GetAttrString (sys.object (), " pythonqt_original_stdin" ));
549+ if ( PyObject_HasAttrString (sys.object (), " pythonqt_original_stdin" ) ) {
550+ _stdin. setNewRef ( PyObject_GetAttrString (sys.object (), " pythonqt_original_stdin" ));
538551 }
539552 }
540553}
@@ -627,19 +640,20 @@ void PythonQtPrivate::createPythonQtClassWrapper(PythonQtClassInfo* info, const
627640 PythonQtClassInfo* outerClassInfo = lookupClassInfoAndCreateIfNotPresent (outerClass);
628641 outerClassInfo->addNestedClass (info);
629642 } else {
630- if ( PyModule_AddObject (pack, info-> className (), pyobj) == 0 ) {
631- // since PyModule_AddObject steals the reference, we need a incref once more...
632- Py_INCREF (pyobj);
643+ Py_INCREF ( pyobj);
644+ if ( PyModule_AddObject (pack, info-> className (), pyobj)) {
645+ Py_DECREF (pyobj);
633646 }
634647 }
635648 if (!module && package && strncmp (package, " Qt" , 2 ) == 0 ) {
649+ Py_INCREF (pyobj);
636650 // put all qt objects into Qt as well
637- if (PyModule_AddObject (packageByName (" Qt" ), info->className (), pyobj) == 0 ) {
638- // since PyModule_AddObject steals the reference, we need a incref once more...
639- Py_INCREF (pyobj);
651+ if (PyModule_AddObject (packageByName (" Qt" ), info->className (), pyobj)) {
652+ Py_DECREF (pyobj);
640653 }
641654 }
642655 info->setPythonQtClassWrapper (pyobj);
656+ Py_DECREF (pyobj);
643657}
644658
645659PyObject* PythonQtPrivate::wrapQObject (QObject* obj)
@@ -1001,17 +1015,21 @@ QVariant PythonQt::evalCode(PyObject* object, PyObject* pycode) {
10011015 QVariant result;
10021016 clearError ();
10031017 if (pycode) {
1004- PyObject* dict = nullptr ;
1005- PyObject* globals = nullptr ;
1018+ PythonQtObjectPtr dict;
1019+ PythonQtObjectPtr globals;
10061020 if (PyModule_Check (object)) {
10071021 dict = PyModule_GetDict (object);
10081022 globals = dict;
10091023 } else if (PyDict_Check (object)) {
10101024 dict = object;
10111025 globals = dict;
10121026 } else {
1013- dict = PyObject_GetAttrString (object, " __dict__" );
1014- globals = PyObject_GetAttrString (PyImport_ImportModule (PyString_AS_STRING (PyObject_GetAttrString (object, " __module__" )))," __dict__" );
1027+ PyObject *moduleName = PyObject_GetAttrString (object, " __module__" );
1028+ PyObject *module = PyImport_ImportModule (PyString_AS_STRING (moduleName));
1029+ dict.setNewRef (PyObject_GetAttrString (object, " __dict__" ));
1030+ globals.setNewRef (PyObject_GetAttrString (module , " __dict__" ));
1031+ Py_XDECREF (moduleName);
1032+ Py_XDECREF (module );
10151033 }
10161034 PyObject* r = nullptr ;
10171035 if (dict) {
@@ -1156,30 +1174,30 @@ PythonQtObjectPtr PythonQt::createUniqueModule()
11561174
11571175void PythonQt::addObject (PyObject* object, const QString& name, QObject* qObject)
11581176{
1159- if (PyModule_Check (object)) {
1160- auto pyobj = _p->wrapQObject (qObject);
1161- if (PyModule_AddObject (object, QStringToPythonCharPointer (name), pyobj) < 0 ) {
1162- Py_DECREF (pyobj);
1177+ PyObject *wrappedObject = _p->wrapQObject (qObject);
1178+ if (PyModule_Check (object)) {
1179+ Py_XINCREF (wrappedObject);
1180+ PyModule_AddObject (object, QStringToPythonCharPointer (name), wrappedObject);
1181+ } else if (PyDict_Check (object)) {
1182+ PyDict_SetItemString (object, QStringToPythonCharPointer (name), wrappedObject);
1183+ } else {
1184+ PyObject_SetAttrString (object, QStringToPythonCharPointer (name), wrappedObject);
11631185 }
1164- } else if (PyDict_Check (object)) {
1165- PyDict_SetItemString (object, QStringToPythonCharPointer (name), _p->wrapQObject (qObject));
1166- } else {
1167- PyObject_SetAttrString (object, QStringToPythonCharPointer (name), _p->wrapQObject (qObject));
1168- }
1186+ Py_XDECREF (wrappedObject);
11691187}
11701188
11711189void PythonQt::addVariable (PyObject* object, const QString& name, const QVariant& v)
11721190{
1173- if ( PyModule_Check (object)) {
1174- auto pyobj = PythonQtConv::QVariantToPyObject (v);
1175- if ( PyModule_AddObject (object, QStringToPythonCharPointer (name), pyobj) < 0 ) {
1176- Py_DECREF (pyobj );
1177- }
1178- } else if ( PyDict_Check ( object)) {
1179- PyDict_SetItemString (object, QStringToPythonCharPointer (name), PythonQtConv::QVariantToPyObject (v));
1180- } else {
1181- PyObject_SetAttrString (object, QStringToPythonCharPointer (name), PythonQtConv::QVariantToPyObject (v));
1182- }
1191+ PyObject *value = PythonQtConv::QVariantToPyObject (v);
1192+ if ( PyModule_Check (object)) {
1193+ Py_XINCREF (value);
1194+ PyModule_AddObject (object, QStringToPythonCharPointer (name), value );
1195+ } else if ( PyDict_Check (object)) {
1196+ PyDict_SetItemString ( object, QStringToPythonCharPointer (name), value);
1197+ } else {
1198+ PyObject_SetAttrString (object, QStringToPythonCharPointer (name), value);
1199+ }
1200+ Py_XDECREF (value);
11831201}
11841202
11851203void PythonQt::removeVariable (PyObject* object, const QString& name)
@@ -1221,7 +1239,7 @@ QStringList PythonQt::introspection(PyObject* module, const QString& objectname,
12211239 } else {
12221240 object = lookupObject (module , objectname);
12231241 if (!object && type == CallOverloads) {
1224- PyObject* dict = lookupObject (module , " __builtins__" );
1242+ PythonQtObjectPtr dict = lookupObject (module , " __builtins__" );
12251243 if (dict) {
12261244 object = PyDict_GetItemString (dict, QStringToPythonCharPointer (objectname));
12271245 }
@@ -1273,38 +1291,36 @@ QStringList PythonQt::introspectObject(PyObject* object, ObjectType type)
12731291 }
12741292 }
12751293 } else {
1276- PyObject* keys = nullptr ;
1277- bool isDict = false ;
1278- if (PyDict_Check (object)) {
1279- keys = PyDict_Keys (object);
1280- isDict = true ;
1281- } else {
1282- #if defined(MEVISLAB) && !defined(PY3K)
1283- int oldPy3kWarningFlag = Py_Py3kWarningFlag;
1284- Py_Py3kWarningFlag = 0 ; // temporarily disable Python 3 warnings
1285- keys = PyObject_Dir (object);
1286- Py_Py3kWarningFlag = oldPy3kWarningFlag;
1287- #else
1288- keys = PyObject_Dir (object);
1289- #endif
1294+ PythonQtObjectPtr keys;
1295+ bool isDict = false ;
1296+ if (PyDict_Check (object)) {
1297+ keys. setNewRef ( PyDict_Keys (object) );
1298+ isDict = true ;
1299+ } else {
1300+ #if defined(MEVISLAB) && !defined(PY3K)
1301+ int oldPy3kWarningFlag = Py_Py3kWarningFlag;
1302+ Py_Py3kWarningFlag = 0 ; // temporarily disable Python 3 warnings
1303+ keys. setNewRef ( PyObject_Dir (object) );
1304+ Py_Py3kWarningFlag = oldPy3kWarningFlag;
1305+ #else
1306+ keys. setNewRef ( PyObject_Dir (object) );
1307+ #endif
12901308 }
12911309 if (keys) {
12921310 int count = PyList_Size (keys);
1293- PyObject* key;
1294- PyObject* value;
1295- QString keystr;
12961311 for (int i = 0 ;i<count;i++) {
1297- key = PyList_GetItem (keys,i);
1298- if (isDict) {
1299- value = PyDict_GetItem (object, key);
1300- Py_INCREF (value);
1301- } else {
1302- value = PyObject_GetAttr (object, key);
1303- }
1304- if (!value) continue ;
1305- keystr = PyString_AsString (key);
1306- static const QString underscoreStr (" __tmp" );
1307- if (!keystr.startsWith (underscoreStr)) {
1312+ PythonQtObjectPtr key = PyList_GetItem (keys,i);
1313+ PythonQtObjectPtr value;
1314+ if (isDict) {
1315+ value.setNewRef (PyDict_GetItem (object, key));
1316+ Py_INCREF (value);
1317+ } else {
1318+ value = PyObject_GetAttr (object, key);
1319+ }
1320+ if (!value) continue ;
1321+ QString keystr = PyString_AsString (key);
1322+ static const QString underscoreStr (" __tmp" );
1323+ if (!keystr.startsWith (underscoreStr)) {
13081324 switch (type) {
13091325 case Anything:
13101326 results << keystr;
@@ -1347,9 +1363,7 @@ QStringList PythonQt::introspectObject(PyObject* object, ObjectType type)
13471363 std::cerr << " PythonQt: introspection: unknown case" << " , in " << __FILE__ << " :" << __LINE__ << std::endl;
13481364 }
13491365 }
1350- Py_DECREF (value);
13511366 }
1352- Py_DECREF (keys);
13531367 }
13541368 }
13551369 PyErr_Clear ();
@@ -1402,6 +1416,7 @@ QStringList PythonQt::introspectType(const QString& typeName, ObjectType type)
14021416 PyObject* typeObject = getObjectByType (typeName);
14031417 if (typeObject) {
14041418 object = PyObject_GetAttrString (typeObject, QStringToPythonCharPointer (memberName));
1419+ Py_DECREF (typeObject);
14051420 }
14061421 }
14071422 if (object) {
@@ -1473,6 +1488,7 @@ PyObject* PythonQt::callAndReturnPyObject(PyObject* callable, const QVariantList
14731488 PyObject* arg = PythonQtConv::QVariantToPyObject (it.value ());
14741489 if (arg) {
14751490 PyDict_SetItemString (pkwargs, QStringToPythonCharPointer (it.key ()), arg);
1491+ Py_DECREF (arg);
14761492 } else {
14771493 err = true ;
14781494 break ;
@@ -1549,6 +1565,7 @@ PythonQtPrivate::PythonQtPrivate()
15491565 _systemExitExceptionHandlerEnabled = false ;
15501566 _debugAPI = new PythonQtDebugAPI (this );
15511567 _configAPI = new PythonQtConfigAPI (this );
1568+ _qtSlotsName.setNewRef (PyString_FromString (" _qtSlots" ));
15521569}
15531570
15541571void PythonQtPrivate::setupSharedLibrarySuffixes ()
@@ -1879,7 +1896,7 @@ void PythonQt::initPythonQtModule(bool redirectStdOut, const QByteArray& pythonQ
18791896 }
18801897#ifdef PY3K
18811898 PythonQtModuleDef.m_name = name.constData ();
1882- _p->_pythonQtModule = PyModule_Create (&PythonQtModuleDef);
1899+ _p->_pythonQtModule . setNewRef ( PyModule_Create (&PythonQtModuleDef) );
18831900#else
18841901 _p->_pythonQtModule = Py_InitModule (name.constData (), PythonQtMethods);
18851902#endif
@@ -1919,7 +1936,11 @@ void PythonQt::initPythonQtModule(bool redirectStdOut, const QByteArray& pythonQ
19191936 Py_XDECREF (old_module_names);
19201937
19211938#ifdef PY3K
1922- PyDict_SetItem (PyObject_GetAttrString (sys.object (), " modules" ), PyUnicode_FromString (name.constData ()), _p->_pythonQtModule .object ());
1939+ PyObject *modules = PyObject_GetAttrString (sys.object (), " modules" );
1940+ PyObject *nameObj = PyUnicode_FromString (name.constData ());
1941+ PyDict_SetItem (modules, nameObj, _p->_pythonQtModule .object ());
1942+ Py_XDECREF (modules);
1943+ Py_XDECREF (nameObj);
19231944#endif
19241945}
19251946
@@ -1939,8 +1960,9 @@ QString PythonQt::getReturnTypeOfWrappedMethod(PyObject* module, const QString&
19391960
19401961QString PythonQt::getReturnTypeOfWrappedMethod (const QString& typeName, const QString& methodName)
19411962{
1942- PythonQtObjectPtr typeObject = getObjectByType (typeName);
1943- if (typeObject.isNull ()) {
1963+ PythonQtObjectPtr typeObject;
1964+ typeObject.setNewRef (getObjectByType (typeName));
1965+ if (typeObject.isNull ()) {
19441966 return " " ;
19451967 }
19461968 return getReturnTypeOfWrappedMethodHelper (typeObject, methodName, typeName + " ." + methodName);
@@ -2237,8 +2259,7 @@ const QMetaObject* PythonQtPrivate::buildDynamicMetaObject(PythonQtClassWrapper*
22372259 PyObject* dict = ((PyTypeObject*)type)->tp_dict ;
22382260 Py_ssize_t pos = 0 ;
22392261 PyObject* value = nullptr ;
2240- PyObject* key = nullptr ;
2241- static PyObject* qtSlots = PyString_FromString (" _qtSlots" );
2262+ PyObject* key = nullptr ;
22422263
22432264 bool needsMetaObject = false ;
22442265 // Iterate over all members and check if they affect the QMetaObject:
@@ -2288,12 +2309,13 @@ const QMetaObject* PythonQtPrivate::buildDynamicMetaObject(PythonQtClassWrapper*
22882309 }
22892310 }
22902311 }
2291- if (PyFunction_Check (value) && PyObject_HasAttr (value, qtSlots )) {
2312+ if (PyFunction_Check (value) && PyObject_HasAttr (value, _qtSlotsName )) {
22922313 // A function which has a "_qtSlots" signature list, add the slots to the meta object
2293- PyObject* signatures = PyObject_GetAttr (value, qtSlots);
2314+ PythonQtObjectPtr signatures;
2315+ signatures.setNewRef (PyObject_GetAttr (value, _qtSlotsName));
22942316 Py_ssize_t count = PyList_Size (signatures);
22952317 for (Py_ssize_t i = 0 ; i < count; i++) {
2296- PyObject* signature = PyList_GET_ITEM (signatures, i);
2318+ PyObject* signature = PyList_GET_ITEM (signatures. object () , i);
22972319 QByteArray sig = PyString_AsString (signature);
22982320 // Split the return type and the rest of the signature,
22992321 // no spaces should be in the rest of the signature...
@@ -2339,9 +2361,11 @@ int PythonQtPrivate::handleMetaCall(QObject* object, PythonQtInstanceWrapper* wr
23392361 }
23402362 PythonQtProperty* prop = nullptr ;
23412363 // Get directly from the Python class, since we don't want to get the value of the property
2342- PyObject* maybeProp = PyBaseObject_Type.tp_getattro ((PyObject*)wrapper, PyString_FromString (metaProp.name ()));
2364+ PythonQtObjectPtr name, maybeProp;
2365+ name.setNewRef (PyString_FromString (metaProp.name ()));
2366+ maybeProp.setNewRef (PyBaseObject_Type.tp_getattro ((PyObject*)wrapper, name));
23432367 if (maybeProp && PythonQtProperty_Check (maybeProp)) {
2344- prop = (PythonQtProperty*)maybeProp;
2368+ prop = (PythonQtProperty*)maybeProp. object () ;
23452369 } else {
23462370 return id - methodCount;
23472371 }
@@ -2396,17 +2420,15 @@ QString PythonQtPrivate::getSignature(PyObject* object)
23962420 PyMethodObject* method = nullptr ;
23972421 PyFunctionObject* func = nullptr ;
23982422
2399- bool decrefMethod = false ;
2400-
24012423 if (PythonQtUtils::isPythonClassType (object)) {
24022424 method = (PyMethodObject*)PyObject_GetAttrString (object, " __init__" );
2403- decrefMethod = true ;
24042425 } else if (object->ob_type == &PyFunction_Type) {
24052426 func = (PyFunctionObject*)object;
24062427 } else if (object->ob_type == &PyMethod_Type) {
24072428 method = (PyMethodObject*)object;
2429+ Py_XINCREF (method);
24082430 }
2409- if (method) {
2431+ if (method) {
24102432 if (PyFunction_Check (method->im_func )) {
24112433 func = (PyFunctionObject*)method->im_func ;
24122434 } else if (isMethodDescriptor ((PyObject*)method)) {
@@ -2514,9 +2536,7 @@ QString PythonQtPrivate::getSignature(PyObject* object)
25142536 signature = funcName + " (" + signature + " )" ;
25152537 }
25162538
2517- if (method && decrefMethod) {
2518- Py_DECREF (method);
2519- }
2539+ Py_XDECREF (method);
25202540 }
25212541
25222542 return signature;
0 commit comments