Skip to content

Commit 525ea41

Browse files
More potential leak fixes and build fix
1 parent 06860d4 commit 525ea41

File tree

2 files changed

+66
-55
lines changed

2 files changed

+66
-55
lines changed

build/python.prf

Lines changed: 36 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -8,41 +8,43 @@ isEmpty( PYTHON_VERSION ) {
88
unix:PYTHON_VERSION=2.7
99
}
1010

11-
12-
macx {
13-
# for macx you need to have the Python development kit installed as framework
14-
INCLUDEPATH += /System/Library/Frameworks/Python.framework/Headers
15-
LIBS += -F/System/Library/Frameworks -framework Python
16-
} else:win32 {
17-
# for windows install a Python development kit or build Python yourself from the sources
18-
# Make sure that you set the environment variable PYTHON_PATH to point to your
19-
# python installation (or the python sources/header files when building from source).
20-
# Make sure that you set the environment variable PYTHON_LIB to point to
21-
# the directory where the python libs are located.
22-
#
23-
# When using the prebuild Python installer, this will be:
24-
# set PYTHON_PATH = c:\Python26
25-
# set PYTHON_LIB = c:\Python26\libs
26-
#
27-
# When using the python sources, this will be something like:
28-
# set PYTHON_PATH = c:\yourDir\Python-2.6.1\
29-
# set PYTHON_LIB = c:\yourDir\Python-2.6.1\PCbuild8\Win32
30-
31-
# check if debug or release
32-
CONFIG(debug, debug|release) {
33-
DEBUG_EXT = _d
34-
} else {
35-
DEBUG_EXT =
36-
}
37-
38-
win32:INCLUDEPATH += $$(PYTHON_PATH)/PC $$(PYTHON_PATH)/include
39-
win32:LIBS += $$(PYTHON_LIB)/python$${PYTHON_VERSION}$${DEBUG_EXT}.lib
40-
} else:unix {
41-
# on linux, python-config is used to autodetect Python.
42-
# make sure that you have installed a matching python-dev package.
11+
message(Using Python version $${PYTHON_VERSION})
12+
13+
macx {
14+
# for macx you need to have the Python development kit installed as framework
15+
INCLUDEPATH += /System/Library/Frameworks/Python.framework/Headers
16+
LIBS += -F/System/Library/Frameworks -framework Python
17+
} else:win32 {
18+
# for windows install a Python development kit or build Python yourself from the sources
19+
# Make sure that you set the environment variable PYTHON_PATH to point to your
20+
# python installation (or the python sources/header files when building from source).
21+
# Make sure that you set the environment variable PYTHON_LIB to point to
22+
# the directory where the python libs are located.
23+
#
24+
# When using the prebuild Python installer, this will be:
25+
# set PYTHON_PATH = c:\Python26
26+
# set PYTHON_LIB = c:\Python26\libs
27+
#
28+
# When using the python sources, this will be something like:
29+
# set PYTHON_PATH = c:\yourDir\Python-2.6.1\
30+
# set PYTHON_LIB = c:\yourDir\Python-2.6.1\PCbuild8\Win32
31+
32+
# check if debug or release
33+
CONFIG(debug, debug|release) {
34+
DEBUG_EXT = _d
35+
} else {
36+
DEBUG_EXT =
37+
}
38+
39+
win32:INCLUDEPATH += $$(PYTHON_PATH)/PC $$(PYTHON_PATH)/include
40+
win32:LIBS += $$(PYTHON_LIB)/python$${PYTHON_VERSION}$${DEBUG_EXT}.lib
41+
} else:unix {
42+
# on linux, python-config is used to autodetect Python.
43+
# make sure that you have installed a matching python-dev package.
4344

4445
system(python$${PYTHON_VERSION}-config --embed --libs) {
4546
unix:LIBS += $$system(python$${PYTHON_VERSION}-config --embed --libs)
4647
} else: unix:LIBS += $$system(python$${PYTHON_VERSION}-config --libs)
47-
unix:QMAKE_CXXFLAGS += $$system(python$${PYTHON_VERSION}-config --includes)
48-
}
48+
unix:QMAKE_CXXFLAGS += $$system(python$${PYTHON_VERSION}-config --includes)
49+
unix:QMAKE_LFLAGS += $$system(python$${PYTHON_VERSION}-config --ldflags)
50+
}

src/PythonQt.cpp

Lines changed: 30 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,15 @@ void PythonQt_init_QtGuiBuiltin(PyObject*);
6868
void PythonQt_init_QtCoreBuiltin(PyObject*);
6969

7070

71+
static inline int PyModule_AddObject_DECREF(PyObject *module, const char *name, PyObject *value)
72+
{
73+
int ret = PyModule_AddObject(module, name, value);
74+
if (ret < 0)
75+
Py_XDECREF(value);
76+
return ret;
77+
}
78+
79+
7180
void PythonQt::init(int flags, const QByteArray& pythonQtModuleName)
7281
{
7382
if (!_self) {
@@ -244,9 +253,9 @@ void PythonQt::init(int flags, const QByteArray& pythonQtModuleName)
244253
for (unsigned int i = 0;i<16; i++) {
245254
PyObject* obj = PyObject_GetAttrString(qtNamespace, names[i]);
246255
if (obj) {
247-
PyModule_AddObject(pack, names[i], obj);
256+
PyModule_AddObject_DECREF(pack, names[i], obj);
248257
Py_INCREF(obj);
249-
PyModule_AddObject(pack2, names[i], obj);
258+
PyModule_AddObject_DECREF(pack2, names[i], obj);
250259
} else {
251260
std::cerr << "method not found " << names[i] << std::endl;
252261
}
@@ -268,19 +277,19 @@ void PythonQt::init(int flags, const QByteArray& pythonQtModuleName)
268277

269278
for (int i = 0; i<sizeof(enumValues)/sizeof(int); i++) {
270279
PyObject* obj = PyInt_FromLong(enumValues[i]);
271-
PyModule_AddObject(pack, enumNames[i], obj);
280+
PyModule_AddObject_DECREF(pack, enumNames[i], obj);
272281
Py_INCREF(obj);
273-
PyModule_AddObject(pack2, enumNames[i], obj);
282+
PyModule_AddObject_DECREF(pack2, enumNames[i], obj);
274283
}
275284

276285
_self->priv()->pythonQtModule().addObject("Debug", _self->priv()->_debugAPI);
277286

278287
Py_INCREF((PyObject*)&PythonQtSlotDecorator_Type);
279288
Py_INCREF((PyObject*)&PythonQtSignalFunction_Type);
280289
Py_INCREF((PyObject*)&PythonQtProperty_Type);
281-
PyModule_AddObject(pack, "Slot", (PyObject*)&PythonQtSlotDecorator_Type);
282-
PyModule_AddObject(pack, "Signal", (PyObject*)&PythonQtSignalFunction_Type);
283-
PyModule_AddObject(pack, "Property", (PyObject*)&PythonQtProperty_Type);
290+
PyModule_AddObject_DECREF(pack, "Slot", (PyObject*)&PythonQtSlotDecorator_Type);
291+
PyModule_AddObject_DECREF(pack, "Signal", (PyObject*)&PythonQtSignalFunction_Type);
292+
PyModule_AddObject_DECREF(pack, "Property", (PyObject*)&PythonQtProperty_Type);
284293

285294
}
286295
}
@@ -423,11 +432,11 @@ void PythonQt::setRedirectStdInCallback(PythonQtInputChangedCB* callback, void *
423432
((PythonQtStdInRedirect*)in.object())->_cb = callback;
424433
((PythonQtStdInRedirect*)in.object())->_callData = callbackData;
425434
// replace the built in file objects with our own objects
426-
PyModule_AddObject(sys.object(), "stdin", in);
435+
PyModule_AddObject_DECREF(sys.object(), "stdin", in);
427436

428437
// Backup custom 'stdin' into 'pythonqt_stdin'
429438
Py_INCREF(in); // AddObject steals the reference, so increment it
430-
PyModule_AddObject(sys.object(), "pythonqt_stdin", in);
439+
PyModule_AddObject_DECREF(sys.object(), "pythonqt_stdin", in);
431440
}
432441

433442
void PythonQt::setRedirectStdInCallbackEnabled(bool enabled)
@@ -503,7 +512,7 @@ void PythonQtPrivate::registerClass(const QMetaObject* metaobject, const char* p
503512
PyObject* classWrapper = info->pythonQtClassWrapper();
504513
// AddObject steals a reference, so we need to INCREF
505514
Py_INCREF(classWrapper);
506-
PyModule_AddObject(module, info->className(), classWrapper);
515+
PyModule_AddObject_DECREF(module, info->className(), classWrapper);
507516
}
508517
if (first) {
509518
first = false;
@@ -537,13 +546,13 @@ void PythonQtPrivate::createPythonQtClassWrapper(PythonQtClassInfo* info, const
537546
outerClassInfo->addNestedClass(info);
538547
} else {
539548
Py_INCREF(pyobj);
540-
PyModule_AddObject(pack, info->className(), pyobj);
549+
PyModule_AddObject_DECREF(pack, info->className(), pyobj);
541550
}
542551
if (!module && package && strncmp(package, "Qt", 2) == 0) {
543552
// since PyModule_AddObject steals the reference, we need a incref once more...
544553
Py_INCREF(pyobj);
545554
// put all qt objects into Qt as well
546-
PyModule_AddObject(packageByName("Qt"), info->className(), pyobj);
555+
PyModule_AddObject_DECREF(packageByName("Qt"), info->className(), pyobj);
547556
}
548557
info->setPythonQtClassWrapper(pyobj);
549558
Py_DECREF(pyobj);
@@ -1071,7 +1080,7 @@ void PythonQt::addObject(PyObject* object, const QString& name, QObject* qObject
10711080
PyObject *wrappedObject = _p->wrapQObject(qObject);
10721081
if (PyModule_Check(object)) {
10731082
Py_XINCREF(wrappedObject);
1074-
PyModule_AddObject(object, QStringToPythonCharPointer(name), wrappedObject);
1083+
PyModule_AddObject_DECREF(object, QStringToPythonCharPointer(name), wrappedObject);
10751084
} else if (PyDict_Check(object)) {
10761085
PyDict_SetItemString(object, QStringToPythonCharPointer(name), wrappedObject);
10771086
} else {
@@ -1085,7 +1094,7 @@ void PythonQt::addVariable(PyObject* object, const QString& name, const QVariant
10851094
PyObject *value = PythonQtConv::QVariantToPyObject(v);
10861095
if (PyModule_Check(object)) {
10871096
Py_XINCREF(value);
1088-
PyModule_AddObject(object, QStringToPythonCharPointer(name), value);
1097+
PyModule_AddObject_DECREF(object, QStringToPythonCharPointer(name), value);
10891098
} else if (PyDict_Check(object)) {
10901099
PyDict_SetItemString(object, QStringToPythonCharPointer(name), value);
10911100
} else {
@@ -1697,12 +1706,12 @@ void PythonQt::overwriteSysPath(const QStringList& paths)
16971706
foreach(QString path, paths) {
16981707
nativePaths << QDir::toNativeSeparators(path);
16991708
}
1700-
PyModule_AddObject(sys, "path", PythonQtConv::QStringListToPyList(nativePaths));
1709+
PyModule_AddObject_DECREF(sys, "path", PythonQtConv::QStringListToPyList(nativePaths));
17011710
}
17021711

17031712
void PythonQt::setModuleImportPath(PyObject* module, const QStringList& paths)
17041713
{
1705-
PyModule_AddObject(module, "__path__", PythonQtConv::QStringListToPyList(paths));
1714+
PyModule_AddObject_DECREF(module, "__path__", PythonQtConv::QStringListToPyList(paths));
17061715
}
17071716

17081717
void PythonQt::stdOutRedirectCB(const QString& str)
@@ -1780,7 +1789,7 @@ void PythonQt::initPythonQtModule(bool redirectStdOut, const QByteArray& pythonQ
17801789
_p->_pythonQtModuleName = name;
17811790

17821791
Py_INCREF((PyObject*)&PythonQtBoolResult_Type);
1783-
PyModule_AddObject(_p->pythonQtModule().object(), "BoolResult", (PyObject*)&PythonQtBoolResult_Type);
1792+
PyModule_AddObject_DECREF(_p->pythonQtModule().object(), "BoolResult", (PyObject*)&PythonQtBoolResult_Type);
17841793
PythonQtObjectPtr sys;
17851794
sys.setNewRef(PyImport_ImportModule("sys"));
17861795

@@ -1793,8 +1802,8 @@ void PythonQt::initPythonQtModule(bool redirectStdOut, const QByteArray& pythonQ
17931802
err = PythonQtStdOutRedirectType.tp_new(&PythonQtStdOutRedirectType,NULL, NULL);
17941803
((PythonQtStdOutRedirect*)err.object())->_cb = stdErrRedirectCB;
17951804
// replace the built in file objects with our own objects
1796-
PyModule_AddObject(sys, "stdout", out);
1797-
PyModule_AddObject(sys, "stderr", err);
1805+
PyModule_AddObject_DECREF(sys, "stdout", out);
1806+
PyModule_AddObject_DECREF(sys, "stderr", err);
17981807
}
17991808

18001809
// add PythonQt to the list of builtin module names
@@ -1808,7 +1817,7 @@ void PythonQt::initPythonQtModule(bool redirectStdOut, const QByteArray& pythonQ
18081817
PyTuple_SetItem(module_names, i, val);
18091818
}
18101819
PyTuple_SetItem(module_names, old_size, PyString_FromString(name.constData()));
1811-
PyModule_AddObject(sys.object(), "builtin_module_names", module_names);
1820+
PyModule_AddObject_DECREF(sys.object(), "builtin_module_names", module_names);
18121821
}
18131822
Py_XDECREF(old_module_names);
18141823

@@ -1991,7 +2000,7 @@ PyObject* PythonQtPrivate::packageByName(const char* name)
19912000
_packages.insert(name, v);
19922001
// AddObject steals the reference, so increment it!
19932002
Py_INCREF(v);
1994-
PyModule_AddObject(_pythonQtModule, name, v);
2003+
PyModule_AddObject_DECREF(_pythonQtModule, name, v);
19952004
}
19962005
return v;
19972006
}

0 commit comments

Comments
 (0)