Skip to content

Commit 17ea22a

Browse files
iakovmrbean-bremen
authored andcommitted
Use XSETREF for safety
More details on [XSETREF macro for safer code](python/cpython#99537)
1 parent fb1eb93 commit 17ea22a

File tree

1 file changed

+21
-18
lines changed

1 file changed

+21
-18
lines changed

src/PythonQtObjectPtr.cpp

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,16 @@
4141

4242
#include <PythonQt.h>
4343

44+
#ifndef Py_XSETREF // Some Python2, but not the latest one
45+
#define Py_XSETREF(op1, op2) \
46+
do { \
47+
auto **op = &(op1); \
48+
PyObject *tmp = static_cast<PyObject *>(*op); \
49+
*op = (op2); \
50+
Py_XDECREF(tmp); \
51+
} while (0)
52+
#endif
53+
4454
QVariant PythonQtObjectPtr::evalScript(const QString& script, int start)
4555
{
4656
return PythonQt::self()->evalScript(_object, script, start);
@@ -89,8 +99,8 @@ QVariant PythonQtObjectPtr::call(const QVariantList& args, const QVariantMap& kw
8999

90100
PythonQtObjectPtr::PythonQtObjectPtr(PyObject* o)
91101
{
102+
Py_XINCREF(o);
92103
_object = o;
93-
if (o) Py_INCREF(_object);
94104
}
95105

96106
PythonQtObjectPtr::PythonQtObjectPtr(PythonQtSafeObjectPtr &&p) :_object(p.takeObject())
@@ -99,14 +109,13 @@ PythonQtObjectPtr::PythonQtObjectPtr(PythonQtSafeObjectPtr &&p) :_object(p.takeO
99109

100110
PythonQtObjectPtr::~PythonQtObjectPtr()
101111
{
102-
if (_object) Py_DECREF(_object);
112+
Py_XDECREF(_object);
103113
}
104114

105115
void PythonQtObjectPtr::setNewRef(PyObject* o)
106116
{
107117
if (o != _object) {
108-
if (_object) Py_DECREF(_object);
109-
_object = o;
118+
Py_XSETREF(_object, o);
110119
}
111120
}
112121

@@ -136,19 +145,15 @@ QVariant PythonQtObjectPtr::toVariant()
136145

137146
PythonQtObjectPtr & PythonQtObjectPtr::operator=(PythonQtSafeObjectPtr &&p)
138147
{
139-
if (_object) {
140-
setObject(nullptr);
141-
}
142-
_object = p.takeObject();
148+
Py_XSETREF(_object, p.takeObject());
143149
return *this;
144150
}
145151

146152
void PythonQtObjectPtr::setObject(PyObject* o)
147153
{
148154
if (o != _object) {
149-
if (_object) Py_DECREF(_object);
150-
_object = o;
151-
if (_object) Py_INCREF(_object);
155+
Py_XINCREF(o);
156+
Py_XSETREF(_object, o);
152157
}
153158
}
154159

@@ -159,7 +164,7 @@ PythonQtSafeObjectPtr::PythonQtSafeObjectPtr(PyObject* o)
159164
_object = o;
160165
if (o) {
161166
PYTHONQT_GIL_SCOPE
162-
Py_INCREF(_object);
167+
Py_INCREF(o);
163168
}
164169
}
165170

@@ -175,18 +180,16 @@ void PythonQtSafeObjectPtr::setObject(PyObject* o)
175180
{
176181
if (o != _object) {
177182
PYTHONQT_GIL_SCOPE
178-
if (_object) Py_DECREF(_object);
179-
_object = o;
180-
if (_object) Py_INCREF(_object);
183+
Py_XINCREF(o);
184+
Py_XSETREF(_object, o);
181185
}
182186
}
183187

184188
void PythonQtSafeObjectPtr::setObjectUnsafe(PyObject* o)
185189
{
186190
if (o != _object) {
187-
if (_object) Py_DECREF(_object);
188-
_object = o;
189-
if (_object) Py_INCREF(_object);
191+
Py_XINCREF(o);
192+
Py_XSETREF(_object, o);
190193
}
191194
}
192195

0 commit comments

Comments
 (0)