diff --git a/src/PythonQt.cpp b/src/PythonQt.cpp index a1ff153cf..3c091bd0b 100644 --- a/src/PythonQt.cpp +++ b/src/PythonQt.cpp @@ -68,16 +68,6 @@ void PythonQt_init_QtGuiBuiltin(PyObject*); void PythonQt_init_QtCoreBuiltin(PyObject*); -static inline int PyModule_AddObject_DECREF(PyObject *module, const char *name, PyObject *value) -{ - int ret = PyModule_AddObject(module, name, value); - if (ret < 0) { - Py_XDECREF(value); - } - return ret; -} - - void PythonQt::init(int flags, const QByteArray& pythonQtModuleName) { if (!_self) { @@ -254,9 +244,9 @@ void PythonQt::init(int flags, const QByteArray& pythonQtModuleName) for (unsigned int i = 0;i<16; i++) { PyObject* obj = PyObject_GetAttrString(qtNamespace, names[i]); if (obj) { - PyModule_AddObject_DECREF(pack, names[i], obj); + PyModule_AddObject(pack, names[i], obj); Py_INCREF(obj); - PyModule_AddObject_DECREF(pack2, names[i], obj); + PyModule_AddObject(pack2, names[i], obj); } else { std::cerr << "method not found " << names[i] << std::endl; } @@ -278,9 +268,9 @@ void PythonQt::init(int flags, const QByteArray& pythonQtModuleName) for (int i = 0; ipriv()->pythonQtModule().addObject("Debug", _self->priv()->_debugAPI); @@ -288,9 +278,9 @@ void PythonQt::init(int flags, const QByteArray& pythonQtModuleName) Py_INCREF((PyObject*)&PythonQtSlotDecorator_Type); Py_INCREF((PyObject*)&PythonQtSignalFunction_Type); Py_INCREF((PyObject*)&PythonQtProperty_Type); - PyModule_AddObject_DECREF(pack, "Slot", (PyObject*)&PythonQtSlotDecorator_Type); - PyModule_AddObject_DECREF(pack, "Signal", (PyObject*)&PythonQtSignalFunction_Type); - PyModule_AddObject_DECREF(pack, "Property", (PyObject*)&PythonQtProperty_Type); + PyModule_AddObject(pack, "Slot", (PyObject*)&PythonQtSlotDecorator_Type); + PyModule_AddObject(pack, "Signal", (PyObject*)&PythonQtSignalFunction_Type); + PyModule_AddObject(pack, "Property", (PyObject*)&PythonQtProperty_Type); } } @@ -389,23 +379,18 @@ PythonQt::PythonQt(int flags, const QByteArray& pythonQtModuleName) PythonQt::~PythonQt() { delete _p; _p = NULL; - - Py_DECREF(&PythonQtSlotFunction_Type); - Py_DECREF(&PythonQtSignalFunction_Type); - Py_DECREF(&PythonQtSlotDecorator_Type); - Py_DECREF(&PythonQtProperty_Type); - Py_DECREF(&PythonQtBoolResult_Type); - Py_DECREF(&PythonQtClassWrapper_Type); - Py_DECREF(&PythonQtInstanceWrapper_Type); - Py_DECREF(&PythonQtStdOutRedirectType); - Py_DECREF(&PythonQtStdInRedirectType); } PythonQtPrivate::~PythonQtPrivate() { delete _defaultImporter; _defaultImporter = NULL; - qDeleteAll(_knownClassInfos); + { + QHashIterator i(_knownClassInfos); + while (i.hasNext()) { + delete i.next().value(); + } + } PythonQtMethodInfo::cleanupCachedMethodInfos(); PythonQtArgumentFrame::cleanupFreeList(); @@ -424,20 +409,18 @@ void PythonQt::setRedirectStdInCallback(PythonQtInputChangedCB* callback, void * // Backup original 'sys.stdin' if not yet done if( !PyObject_HasAttrString(sys.object(), "pythonqt_original_stdin") ) { - PyObject *_stdin = PyObject_GetAttrString(sys.object(), "stdin"); - PyObject_SetAttrString(sys.object(), "pythonqt_original_stdin", _stdin); - Py_XDECREF(_stdin); + PyObject_SetAttrString(sys.object(), "pythonqt_original_stdin", PyObject_GetAttrString(sys.object(), "stdin")); } in = PythonQtStdInRedirectType.tp_new(&PythonQtStdInRedirectType, NULL, NULL); ((PythonQtStdInRedirect*)in.object())->_cb = callback; ((PythonQtStdInRedirect*)in.object())->_callData = callbackData; // replace the built in file objects with our own objects - PyModule_AddObject_DECREF(sys.object(), "stdin", in); + PyModule_AddObject(sys.object(), "stdin", in); // Backup custom 'stdin' into 'pythonqt_stdin' Py_INCREF(in); // AddObject steals the reference, so increment it - PyModule_AddObject_DECREF(sys.object(), "pythonqt_stdin", in); + PyModule_AddObject(sys.object(), "pythonqt_stdin", in); } void PythonQt::setRedirectStdInCallbackEnabled(bool enabled) @@ -445,19 +428,15 @@ void PythonQt::setRedirectStdInCallbackEnabled(bool enabled) PythonQtObjectPtr sys; sys.setNewRef(PyImport_ImportModule("sys")); - PythonQtObjectPtr _stdin; if (enabled) { - if( PyObject_HasAttrString(sys.object(), "pythonqt_stdin") ) { - _stdin.setNewRef(PyObject_GetAttrString(sys.object(), "pythonqt_stdin")); + if( !PyObject_HasAttrString(sys.object(), "pythonqt_stdin") ) { + PyObject_SetAttrString(sys.object(), "stdin", PyObject_GetAttrString(sys.object(), "pythonqt_stdin")); } } else { - if( PyObject_HasAttrString(sys.object(), "pythonqt_original_stdin") ) { - _stdin.setNewRef(PyObject_GetAttrString(sys.object(), "pythonqt_original_stdin")); + if( !PyObject_HasAttrString(sys.object(), "pythonqt_original_stdin") ) { + PyObject_SetAttrString(sys.object(), "stdin", PyObject_GetAttrString(sys.object(), "pythonqt_original_stdin")); } } - if (_stdin) { - PyObject_SetAttrString(sys.object(), "stdin", _stdin); - } } PythonQtImportFileInterface* PythonQt::importInterface() @@ -469,7 +448,7 @@ void PythonQt::qObjectNoLongerWrappedCB(QObject* o) { if (_self->_p->_noLongerWrappedCB) { (*_self->_p->_noLongerWrappedCB)(o); - } + }; } void PythonQt::setQObjectMissingAttributeCallback(PythonQtQObjectMissingAttributeCB* cb) @@ -513,7 +492,7 @@ void PythonQtPrivate::registerClass(const QMetaObject* metaobject, const char* p PyObject* classWrapper = info->pythonQtClassWrapper(); // AddObject steals a reference, so we need to INCREF Py_INCREF(classWrapper); - PyModule_AddObject_DECREF(module, info->className(), classWrapper); + PyModule_AddObject(module, info->className(), classWrapper); } if (first) { first = false; @@ -546,17 +525,15 @@ void PythonQtPrivate::createPythonQtClassWrapper(PythonQtClassInfo* info, const PythonQtClassInfo* outerClassInfo = lookupClassInfoAndCreateIfNotPresent(outerClass); outerClassInfo->addNestedClass(info); } else { - Py_INCREF(pyobj); - PyModule_AddObject_DECREF(pack, info->className(), pyobj); + PyModule_AddObject(pack, info->className(), pyobj); } if (!module && package && strncmp(package, "Qt", 2) == 0) { // since PyModule_AddObject steals the reference, we need a incref once more... Py_INCREF(pyobj); // put all qt objects into Qt as well - PyModule_AddObject_DECREF(packageByName("Qt"), info->className(), pyobj); + PyModule_AddObject(packageByName("Qt"), info->className(), pyobj); } info->setPythonQtClassWrapper(pyobj); - Py_DECREF(pyobj); } PyObject* PythonQtPrivate::wrapQObject(QObject* obj) @@ -571,7 +548,6 @@ PyObject* PythonQtPrivate::wrapQObject(QObject* obj) // address, so probably that C++ wrapper has been deleted earlier and // now we see a QObject with the same address. // Do not use the old wrapper anymore. - removeWrapperPointer(obj); wrap = NULL; } if (!wrap) { @@ -757,7 +733,6 @@ PythonQtClassWrapper* PythonQtPrivate::createNewPythonQtClassWrapper(PythonQtCla PyObject* typeDict = PyDict_New(); PyObject* moduleName = PyObject_GetAttrString(parentModule, "__name__"); PyDict_SetItemString(typeDict, "__module__", moduleName); - Py_DECREF(moduleName); PyObject* args = Py_BuildValue("OOO", className, baseClasses, typeDict); @@ -794,7 +769,6 @@ PyObject* PythonQtPrivate::createNewPythonQtEnumWrapper(const char* enumName, Py PyObject* module = PyObject_GetAttrString(parentObject, "__module__"); PyObject* typeDict = PyDict_New(); PyDict_SetItemString(typeDict, "__module__", module); - Py_DECREF(module); PyObject* args = Py_BuildValue("OOO", className, baseClasses, typeDict); @@ -919,8 +893,8 @@ QVariant PythonQt::evalCode(PyObject* object, PyObject* pycode) { QVariant result; clearError(); if (pycode) { - PythonQtObjectPtr dict; - PythonQtObjectPtr globals; + PyObject* dict = NULL; + PyObject* globals = NULL; if (PyModule_Check(object)) { dict = PyModule_GetDict(object); globals = dict; @@ -928,12 +902,8 @@ QVariant PythonQt::evalCode(PyObject* object, PyObject* pycode) { dict = object; globals = dict; } else { - PyObject *moduleName = PyObject_GetAttrString(object, "__module__"); - PyObject *module = PyImport_ImportModule(PyString_AS_STRING(moduleName)); - dict.setNewRef(PyObject_GetAttrString(object, "__dict__")); - globals.setNewRef(PyObject_GetAttrString(module, "__dict__")); - Py_XDECREF(moduleName); - Py_XDECREF(module); + dict = PyObject_GetAttrString(object, "__dict__"); + globals = PyObject_GetAttrString(PyImport_ImportModule(PyString_AS_STRING(PyObject_GetAttrString(object, "__module__"))),"__dict__"); } PyObject* r = NULL; if (dict) { @@ -1078,30 +1048,24 @@ PythonQtObjectPtr PythonQt::createUniqueModule() void PythonQt::addObject(PyObject* object, const QString& name, QObject* qObject) { - PyObject *wrappedObject = _p->wrapQObject(qObject); if (PyModule_Check(object)) { - Py_XINCREF(wrappedObject); - PyModule_AddObject_DECREF(object, QStringToPythonCharPointer(name), wrappedObject); + PyModule_AddObject(object, QStringToPythonCharPointer(name), _p->wrapQObject(qObject)); } else if (PyDict_Check(object)) { - PyDict_SetItemString(object, QStringToPythonCharPointer(name), wrappedObject); + PyDict_SetItemString(object, QStringToPythonCharPointer(name), _p->wrapQObject(qObject)); } else { - PyObject_SetAttrString(object, QStringToPythonCharPointer(name), wrappedObject); + PyObject_SetAttrString(object, QStringToPythonCharPointer(name), _p->wrapQObject(qObject)); } - Py_XDECREF(wrappedObject); } void PythonQt::addVariable(PyObject* object, const QString& name, const QVariant& v) { - PyObject *value = PythonQtConv::QVariantToPyObject(v); if (PyModule_Check(object)) { - Py_XINCREF(value); - PyModule_AddObject_DECREF(object, QStringToPythonCharPointer(name), value); + PyModule_AddObject(object, QStringToPythonCharPointer(name), PythonQtConv::QVariantToPyObject(v)); } else if (PyDict_Check(object)) { - PyDict_SetItemString(object, QStringToPythonCharPointer(name), value); + PyDict_SetItemString(object, QStringToPythonCharPointer(name), PythonQtConv::QVariantToPyObject(v)); } else { - PyObject_SetAttrString(object, QStringToPythonCharPointer(name), value); + PyObject_SetAttrString(object, QStringToPythonCharPointer(name), PythonQtConv::QVariantToPyObject(v)); } - Py_XDECREF(value); } void PythonQt::removeVariable(PyObject* object, const QString& name) @@ -1143,7 +1107,7 @@ QStringList PythonQt::introspection(PyObject* module, const QString& objectname, } else { object = lookupObject(module, objectname); if (!object && type == CallOverloads) { - PythonQtObjectPtr dict = lookupObject(module, "__builtins__"); + PyObject* dict = lookupObject(module, "__builtins__"); if (dict) { object = PyDict_GetItemString(dict, QStringToPythonCharPointer(objectname)); } @@ -1195,33 +1159,36 @@ QStringList PythonQt::introspectObject(PyObject* object, ObjectType type) } } } else { - PythonQtObjectPtr keys; + PyObject* keys = NULL; bool isDict = false; if (PyDict_Check(object)) { - keys.setNewRef(PyDict_Keys(object)); + keys = PyDict_Keys(object); isDict = true; } else { #if defined(MEVISLAB) && !defined(PY3K) int oldPy3kWarningFlag = Py_Py3kWarningFlag; Py_Py3kWarningFlag = 0; // temporarily disable Python 3 warnings - keys.setNewRef(PyObject_Dir(object)); + keys = PyObject_Dir(object); Py_Py3kWarningFlag = oldPy3kWarningFlag; #else - keys.setNewRef(PyObject_Dir(object)); + keys = PyObject_Dir(object); #endif } if (keys) { int count = PyList_Size(keys); + PyObject* key; + PyObject* value; + QString keystr; for (int i = 0;i_pythonQtModule.setNewRef(PyModule_Create(&PythonQtModuleDef)); + _p->_pythonQtModule = PyModule_Create(&PythonQtModuleDef); #else _p->_pythonQtModule = Py_InitModule(name.constData(), PythonQtMethods); #endif _p->_pythonQtModuleName = name; Py_INCREF((PyObject*)&PythonQtBoolResult_Type); - PyModule_AddObject_DECREF(_p->pythonQtModule().object(), "BoolResult", (PyObject*)&PythonQtBoolResult_Type); + PyModule_AddObject(_p->pythonQtModule().object(), "BoolResult", (PyObject*)&PythonQtBoolResult_Type); PythonQtObjectPtr sys; sys.setNewRef(PyImport_ImportModule("sys")); @@ -1803,8 +1770,8 @@ void PythonQt::initPythonQtModule(bool redirectStdOut, const QByteArray& pythonQ err = PythonQtStdOutRedirectType.tp_new(&PythonQtStdOutRedirectType,NULL, NULL); ((PythonQtStdOutRedirect*)err.object())->_cb = stdErrRedirectCB; // replace the built in file objects with our own objects - PyModule_AddObject_DECREF(sys, "stdout", out); - PyModule_AddObject_DECREF(sys, "stderr", err); + PyModule_AddObject(sys, "stdout", out); + PyModule_AddObject(sys, "stderr", err); } // add PythonQt to the list of builtin module names @@ -1818,16 +1785,12 @@ void PythonQt::initPythonQtModule(bool redirectStdOut, const QByteArray& pythonQ PyTuple_SetItem(module_names, i, val); } PyTuple_SetItem(module_names, old_size, PyString_FromString(name.constData())); - PyModule_AddObject_DECREF(sys.object(), "builtin_module_names", module_names); + PyModule_AddObject(sys.object(), "builtin_module_names", module_names); } Py_XDECREF(old_module_names); #ifdef PY3K - PyObject *modules = PyObject_GetAttrString(sys.object(), "modules"); - PyObject *nameObj = PyUnicode_FromString(name.constData()); - PyDict_SetItem(modules, nameObj, _p->_pythonQtModule.object()); - Py_XDECREF(modules); - Py_XDECREF(nameObj); + PyDict_SetItem(PyObject_GetAttrString(sys.object(), "modules"), PyUnicode_FromString(name.constData()), _p->_pythonQtModule.object()); #endif } @@ -1847,8 +1810,7 @@ QString PythonQt::getReturnTypeOfWrappedMethod(PyObject* module, const QString& QString PythonQt::getReturnTypeOfWrappedMethod(const QString& typeName, const QString& methodName) { - PythonQtObjectPtr typeObject; - typeObject.setNewRef(getObjectByType(typeName)); + PythonQtObjectPtr typeObject = getObjectByType(typeName); if (typeObject.isNull()) { return ""; } @@ -2001,7 +1963,7 @@ PyObject* PythonQtPrivate::packageByName(const char* name) _packages.insert(name, v); // AddObject steals the reference, so increment it! Py_INCREF(v); - PyModule_AddObject_DECREF(_pythonQtModule, name, v); + PyModule_AddObject(_pythonQtModule, name, v); } return v; } @@ -2143,13 +2105,10 @@ const QMetaObject* PythonQtPrivate::buildDynamicMetaObject(PythonQtClassWrapper* builder.setClassName(((PyTypeObject*)type)->tp_name); PyObject* dict = ((PyTypeObject*)type)->tp_dict; - Py_ssize_t pos = 0; + Py_ssize_t pos = NULL; PyObject* value = NULL; PyObject* key = NULL; - static PyObject* qtSlots = NULL; - if (!qtSlots) { - qtSlots = PyString_FromString("_qtSlots"); - } + static PyObject* qtSlots = PyString_FromString("_qtSlots"); bool needsMetaObject = false; // Iterate over all members and check if they affect the QMetaObject: @@ -2167,7 +2126,7 @@ const QMetaObject* PythonQtPrivate::buildDynamicMetaObject(PythonQtClassWrapper* } } } - pos = 0; + pos = NULL; value = NULL; key = NULL; // Now look for slots: (this is a bug in QMetaObjectBuilder, all signals need to be added first) @@ -2201,11 +2160,10 @@ const QMetaObject* PythonQtPrivate::buildDynamicMetaObject(PythonQtClassWrapper* } if (PyFunction_Check(value) && PyObject_HasAttr(value, qtSlots)) { // A function which has a "_qtSlots" signature list, add the slots to the meta object - PythonQtObjectPtr signatures; - signatures.setNewRef(PyObject_GetAttr(value, qtSlots)); + PyObject* signatures = PyObject_GetAttr(value, qtSlots); Py_ssize_t count = PyList_Size(signatures); for (Py_ssize_t i = 0; i < count; i++) { - PyObject* signature = PyList_GET_ITEM(signatures.object(), i); + PyObject* signature = PyList_GET_ITEM(signatures, i); QByteArray sig = PyString_AsString(signature); // Split the return type and the rest of the signature, // no spaces should be in the rest of the signature... @@ -2251,11 +2209,9 @@ int PythonQtPrivate::handleMetaCall(QObject* object, PythonQtInstanceWrapper* wr } PythonQtProperty* prop = NULL; // Get directly from the Python class, since we don't want to get the value of the property - PythonQtObjectPtr name, maybeProp; - name.setNewRef(PyString_FromString(metaProp.name())); - maybeProp.setNewRef(PyBaseObject_Type.tp_getattro((PyObject*)wrapper, name)); + PyObject* maybeProp = PyBaseObject_Type.tp_getattro((PyObject*)wrapper, PyString_FromString(metaProp.name())); if (maybeProp && PythonQtProperty_Check(maybeProp)) { - prop = (PythonQtProperty*)maybeProp.object(); + prop = (PythonQtProperty*)maybeProp; } else { return id - methodCount; } @@ -2272,7 +2228,7 @@ int PythonQtPrivate::handleMetaCall(QObject* object, PythonQtInstanceWrapper* wr PyObject* value = prop->data->callGetter((PyObject*)wrapper); if (value) { - void* result = PythonQtConv::ConvertPythonToQt(info, value, false, NULL, args[0]); // FIXME: what happens with result? free? + void* result = PythonQtConv::ConvertPythonToQt(info, value, false, NULL, args[0]); Py_DECREF(value); return (result == NULL ? -1 : 0); } else { @@ -2311,15 +2267,17 @@ QString PythonQtPrivate::getSignature(PyObject* object) PyMethodObject* method = NULL; PyFunctionObject* func = NULL; + bool decrefMethod = false; + if (PythonQtUtils::isPythonClassType(object)) { method = (PyMethodObject*)PyObject_GetAttrString(object, "__init__"); + decrefMethod = true; } else if (object->ob_type == &PyFunction_Type) { func = (PyFunctionObject*)object; } else if (object->ob_type == &PyMethod_Type) { method = (PyMethodObject*)object; - Py_XINCREF(method); } - if (method) { + if (method) { if (PyFunction_Check(method->im_func)) { func = (PyFunctionObject*)method->im_func; } else if (isMethodDescriptor((PyObject*)method)) { @@ -2426,7 +2384,9 @@ QString PythonQtPrivate::getSignature(PyObject* object) signature = funcName + "(" + signature + ")"; } - Py_XDECREF(method); + if (method && decrefMethod) { + Py_DECREF(method); + } } return signature; @@ -2491,7 +2451,7 @@ PythonQtClassInfo* PythonQtPrivate::getClassInfo( const QByteArray& className ) if (_knownLazyClasses.contains(className)) { QByteArray module = _knownLazyClasses.value(className); recursion = true; - PyImport_ImportModule(module); // FIXME: reference leaked + PyImport_ImportModule(module); recursion = false; result = _knownClassInfos.value(className); if (!result) { diff --git a/src/PythonQt.h b/src/PythonQt.h index 436edf393..93e62c30d 100644 --- a/src/PythonQt.h +++ b/src/PythonQt.h @@ -813,7 +813,7 @@ class PYTHONQT_EXPORT PythonQtPrivate : public QObject { PythonQtInstanceWrapper* findWrapperAndRemoveUnused(void* obj); //! stores pointer to PyObject mapping of wrapped QObjects AND C++ objects - QHash _wrappedObjects; // FIXME: remove unused entries in cleanup() + QHash _wrappedObjects; //! stores the meta info of known Qt classes QHash _knownClassInfos; diff --git a/src/PythonQtImporter.cpp b/src/PythonQtImporter.cpp index 6e798a9bb..21ec5a43b 100644 --- a/src/PythonQtImporter.cpp +++ b/src/PythonQtImporter.cpp @@ -224,9 +224,9 @@ PythonQtImporter_load_module(PyObject *obj, PyObject *args) PyObject *code = NULL, *mod = NULL, *dict = NULL; char *fullname; - if (!PyArg_ParseTuple(args, "s:PythonQtImporter.load_module", &fullname)) { + if (!PyArg_ParseTuple(args, "s:PythonQtImporter.load_module", + &fullname)) return NULL; - } PythonQtImport::ModuleInfo info = PythonQtImport::getModuleInfo(self, fullname); if (info.type == PythonQtImport::MI_NOT_FOUND) { @@ -250,6 +250,7 @@ PythonQtImporter_load_module(PyObject *obj, PyObject *args) if (PyDict_SetItemString(dict, "__loader__", (PyObject *)self) != 0) { Py_DECREF(code); + Py_DECREF(mod); return NULL; } @@ -264,6 +265,7 @@ PythonQtImporter_load_module(PyObject *obj, PyObject *args) QStringToPythonConstCharPointer(subname)); if (fullpath == NULL) { Py_DECREF(code); + Py_DECREF(mod); return NULL; } @@ -271,12 +273,14 @@ PythonQtImporter_load_module(PyObject *obj, PyObject *args) Py_DECREF(fullpath); if (pkgpath == NULL) { Py_DECREF(code); + Py_DECREF(mod); return NULL; } err = PyDict_SetItemString(dict, "__path__", pkgpath); Py_DECREF(pkgpath); if (err != 0) { Py_DECREF(code); + Py_DECREF(mod); return NULL; } @@ -285,11 +289,10 @@ PythonQtImporter_load_module(PyObject *obj, PyObject *args) // The package attribute is needed to resolve the package name if it is referenced as '.'. For example, // when importing the encodings package, there is an import statement 'from . import aliases'. This import // would fail when reloading the encodings package with importlib. - PyObject* fullnameObj = PyUnicode_FromString(fullname); - err = PyDict_SetItemString(dict, "__package__", fullnameObj); - Py_XDECREF(fullnameObj); + err = PyDict_SetItemString(dict, "__package__", PyUnicode_FromString(fullname)); if (err != 0) { Py_DECREF(code); + Py_DECREF(mod); return NULL; } #endif @@ -909,32 +912,22 @@ void PythonQtImport::init() PythonQtImportError = PyErr_NewException(const_cast("PythonQtImport.PythonQtImportError"), PyExc_ImportError, NULL); - if (PythonQtImportError == NULL) { - Py_XDECREF(mod); + if (PythonQtImportError == NULL) return; - } Py_INCREF(PythonQtImportError); if (PyModule_AddObject(mod, "PythonQtImportError", - PythonQtImportError) < 0) { - Py_DECREF(PythonQtImportError); - Py_DECREF(mod); + PythonQtImportError) < 0) return; - } Py_INCREF(&PythonQtImporter_Type); if (PyModule_AddObject(mod, "PythonQtImporter", - (PyObject *)&PythonQtImporter_Type) < 0) { - Py_DECREF(&PythonQtImporter_Type); - Py_DECREF(mod); + (PyObject *)&PythonQtImporter_Type) < 0) return; - } // set our importer into the path_hooks to handle all path on sys.path PyObject* classobj = PyDict_GetItemString(PyModule_GetDict(mod), "PythonQtImporter"); PyObject* path_hooks = PySys_GetObject(const_cast("path_hooks")); // insert our importer before all other loaders PyList_Insert(path_hooks, 0, classobj); - - Py_DECREF(mod); } diff --git a/src/PythonQtInstanceWrapper.cpp b/src/PythonQtInstanceWrapper.cpp index 67d1ace1f..7b99e8e9d 100644 --- a/src/PythonQtInstanceWrapper.cpp +++ b/src/PythonQtInstanceWrapper.cpp @@ -91,7 +91,7 @@ static void PythonQtInstanceWrapper_deleteObject(PythonQtInstanceWrapper* self, } } else { //mlabDebugConst("Python","qobject wrapper removed " << self->_obj->className() << " " << self->classInfo()->wrappedClassName().latin1()); - if (self->_objPointerCopy && PythonQt::self() && PythonQt::priv()) { + if (self->_objPointerCopy) { PythonQt::priv()->removeWrapperPointer(self->_objPointerCopy); } if (self->_obj) { diff --git a/src/PythonQtSignalReceiver.cpp b/src/PythonQtSignalReceiver.cpp index 594cdacbb..406e1939e 100644 --- a/src/PythonQtSignalReceiver.cpp +++ b/src/PythonQtSignalReceiver.cpp @@ -54,7 +54,9 @@ int PythonQtSignalReceiver::_destroyedSignal2Id = -2; void PythonQtSignalTarget::call(void **arguments) const { PYTHONQT_GIL_SCOPE PyObject* result = call(_callable, methodInfo(), arguments); - Py_XDECREF(result); + if (result) { + Py_DECREF(result); + } } PyObject* PythonQtSignalTarget::call(PyObject* callable, const PythonQtMethodInfo* methodInfos, void **arguments, bool skipFirstArgumentOfMethodInfo) @@ -98,9 +100,9 @@ PyObject* PythonQtSignalTarget::call(PyObject* callable, const PythonQtMethodInf } } - PythonQtObjectPtr pargs; + PyObject* pargs = NULL; if (count>1) { - pargs.setNewRef(PyTuple_New(count-1)); + pargs = PyTuple_New(count-1); } bool err = false; // transform Qt values to Python @@ -115,7 +117,7 @@ PyObject* PythonQtSignalTarget::call(PyObject* callable, const PythonQtMethodInf } if (arg) { // steals reference, no unref - PyTuple_SetItem(pargs, i-1, arg); + PyTuple_SetItem(pargs, i-1,arg); } else { err = true; break; @@ -132,6 +134,10 @@ PyObject* PythonQtSignalTarget::call(PyObject* callable, const PythonQtMethodInf PythonQt::self()->handleError(); } } + if (pargs) { + // free the arguments again + Py_DECREF(pargs); + } return result; }