Skip to content

Commit ad9b6a0

Browse files
jcfrmrbean-bremen
authored andcommitted
fix(PythonQt): Explicitly support immortals introduced in Python >= 3.12
This commit switches to using the `Py_RETURN_*` macros which expand to the expected constructs. This helps avoid a no-op (and misleading) call to `Py_INCREF()` when building against Python >= 3.12. - `Py_RETURN_NOTIMPLEMENTED` was introduced in Python 3.3 through python/cpython@7d2f9e13424 ("Add Py_RETURN_NOTIMPLEMENTED macro. Fixes #12724.", 2011-08-10) - `Py_RETURN_TRUE`, `Py_RETURN_FALSE` and `Py_RETURN_NONE` were introduced in Python 2.4 through python/cpython@d05235ec49d ("Defined macros Py_RETURN_(TRUE|FALSE|NONE) as helper functions for returning the specified value. All three Py_INCREF the singleton and then return it.", 2003-10-19) References: * https://docs.python.org/3/glossary.html#term-immortal * https://peps.python.org/pep-0683/
1 parent b0e0b91 commit ad9b6a0

File tree

8 files changed

+23
-46
lines changed

8 files changed

+23
-46
lines changed

src/PythonQt.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -622,8 +622,7 @@ void PythonQtPrivate::createPythonQtClassWrapper(PythonQtClassInfo* info, const
622622
PyObject* PythonQtPrivate::wrapQObject(QObject* obj)
623623
{
624624
if (!obj) {
625-
Py_INCREF(Py_None);
626-
return Py_None;
625+
Py_RETURN_NONE;
627626
}
628627
PythonQtInstanceWrapper* wrap = findWrapperAndRemoveUnused(obj);
629628
if (wrap && wrap->_wrappedPtr) {
@@ -652,8 +651,7 @@ PyObject* PythonQtPrivate::wrapQObject(QObject* obj)
652651
PyObject* PythonQtPrivate::wrapPtr(void* ptr, const QByteArray& name, bool passOwnership)
653652
{
654653
if (!ptr) {
655-
Py_INCREF(Py_None);
656-
return Py_None;
654+
Py_RETURN_NONE;
657655
}
658656

659657
PythonQtInstanceWrapper* wrap = findWrapperAndRemoveUnused(ptr);

src/PythonQtClassWrapper.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -449,8 +449,7 @@ static PyObject* PythonQtClassWrapper_getDummyInstanceForProperty(PythonQtClassW
449449
if (info) {
450450
return (PyObject*)PythonQt::priv()->createNewPythonQtInstanceWrapper(nullptr, info);
451451
}
452-
Py_INCREF(Py_None);
453-
return Py_None;
452+
Py_RETURN_NONE;
454453
}
455454

456455
static PyObject *PythonQtClassWrapper_getattro(PyObject *obj, PyObject *name)

src/PythonQtConversion.cpp

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -83,22 +83,19 @@ PyObject* PythonQtConv::ConvertQtValueToPython(const PythonQtMethodInfo::Paramet
8383
return PythonQtPrivate::createEnumValueInstance(info.enumWrapper, *((unsigned int*)data));
8484
} else {
8585
// we do not support pointers to enums (who needs them?)
86-
Py_INCREF(Py_None);
87-
return Py_None;
86+
Py_RETURN_NONE;
8887
}
8988
}
9089

9190
if (info.typeId == QMetaType::Void) {
92-
Py_INCREF(Py_None);
93-
return Py_None;
91+
Py_RETURN_NONE;
9492
} else if ((info.pointerCount == 1) && (info.typeId == QMetaType::Char)) {
9593
// a char ptr will probably be a null terminated string, so we support that:
9694
char* charPtr = *((char**)data);
9795
if (charPtr) {
9896
return PyString_FromString(charPtr);
9997
} else {
100-
Py_INCREF(Py_None);
101-
return Py_None;
98+
Py_RETURN_NONE;
10299
}
103100
} else if ((info.typeId == PythonQtMethodInfo::Unknown || info.typeId >= QMetaType::User) &&
104101
info.isQList && (info.innerNamePointerCount == 1)) {
@@ -151,15 +148,13 @@ PyObject* PythonQtConv::ConvertQtValueToPython(const PythonQtMethodInfo::Paramet
151148
}
152149
}
153150
}
154-
Py_INCREF(Py_None);
155-
return Py_None;
151+
Py_RETURN_NONE;
156152
}
157153

158154
PyObject* PythonQtConv::convertQtValueToPythonInternal(int type, const void* data) {
159155
switch (type) {
160156
case QMetaType::Void:
161-
Py_INCREF(Py_None);
162-
return Py_None;
157+
Py_RETURN_NONE;
163158
case QMetaType::Char:
164159
return PyInt_FromLong(*((char*)data));
165160
case QMetaType::UChar:
@@ -232,8 +227,7 @@ PyObject* PythonQtConv::convertQtValueToPythonInternal(int type, const void* dat
232227
}
233228
}
234229
}
235-
Py_INCREF(Py_None);
236-
return Py_None;
230+
Py_RETURN_NONE;
237231
}
238232

239233
void* PythonQtConv::CreateQtReturnValue(const PythonQtMethodInfo::ParameterInfo& info, PythonQtArgumentFrame* frame) {
@@ -1389,8 +1383,7 @@ PyObject* PythonQtConv::QStringListToPyList(const QStringList& list)
13891383
PyObject* PythonQtConv::QVariantToPyObject(const QVariant& v)
13901384
{
13911385
if (!v.isValid()) {
1392-
Py_INCREF(Py_None);
1393-
return Py_None;
1386+
Py_RETURN_NONE;
13941387
}
13951388
PyObject* obj = nullptr;
13961389
if (v.userType() >= QMetaType::User && !PythonQt::priv()->isPythonQtAnyObjectPtrMetaId(v.userType())) {

src/PythonQtImporter.cpp

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -191,8 +191,7 @@ PythonQtImporter_find_module(PyObject *obj, PyObject *args)
191191
Py_INCREF(self);
192192
return (PyObject *)self;
193193
} else {
194-
Py_INCREF(Py_None);
195-
return Py_None;
194+
Py_RETURN_NONE;
196195
}
197196
}
198197

@@ -625,16 +624,14 @@ PythonQtImport::unmarshalCode(const QString& path, const QByteArray& data, time_
625624
if (size <= 9) {
626625
PySys_WriteStderr("# %s has bad pyc data\n",
627626
QStringToPythonConstCharPointer(path));
628-
Py_INCREF(Py_None);
629-
return Py_None;
627+
Py_RETURN_NONE;
630628
}
631629

632630
if (getLong((unsigned char *)buf) != PyImport_GetMagicNumber()) {
633631
if (Py_VerboseFlag)
634632
PySys_WriteStderr("# %s has bad magic\n",
635633
QStringToPythonConstCharPointer(path));
636-
Py_INCREF(Py_None);
637-
return Py_None;
634+
Py_RETURN_NONE;
638635
}
639636

640637
if (mtime != 0) {
@@ -644,8 +641,7 @@ PythonQtImport::unmarshalCode(const QString& path, const QByteArray& data, time_
644641
if (Py_VerboseFlag)
645642
PySys_WriteStderr("# %s has bad mtime\n",
646643
QStringToPythonConstCharPointer(path));
647-
Py_INCREF(Py_None);
648-
return Py_None;
644+
Py_RETURN_NONE;
649645
}
650646
}
651647

src/PythonQtInstanceWrapper.cpp

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -253,8 +253,7 @@ static PyObject *PythonQtInstanceWrapper_richcompare(PythonQtInstanceWrapper* wr
253253
} else if (validPtrs && code == Py_NE) {
254254
return PythonQtConv::GetPyBool(!areSamePtrs);
255255
}
256-
Py_INCREF(Py_NotImplemented);
257-
return Py_NotImplemented;
256+
Py_RETURN_NOTIMPLEMENTED;
258257
}
259258

260259
QByteArray memberName;
@@ -313,19 +312,16 @@ static PyObject *PythonQtInstanceWrapper_richcompare(PythonQtInstanceWrapper* wr
313312
// special handling of EQ and NE, if call fails we just return EQ == false / NE == true.
314313
if (code == Py_EQ) {
315314
PyErr_Clear();
316-
Py_INCREF(Py_False);
317-
return Py_False;
315+
Py_RETURN_FALSE;
318316
} else if (code == Py_NE) {
319317
PyErr_Clear();
320-
Py_INCREF(Py_True);
321-
return Py_True;
318+
Py_RETURN_TRUE;
322319
}
323320
}
324321
return result;
325322
} else {
326323
// not implemented, let python try something else!
327-
Py_INCREF(Py_NotImplemented);
328-
return Py_NotImplemented;
324+
Py_RETURN_NOTIMPLEMENTED;
329325
}
330326
}
331327

@@ -359,8 +355,7 @@ PyObject *PythonQtInstanceWrapper_delete(PythonQtInstanceWrapper * self)
359355
} else {
360356
PythonQtInstanceWrapper_deleteObject(self, true);
361357
}
362-
Py_INCREF(Py_None);
363-
return Py_None;
358+
Py_RETURN_NONE;
364359
}
365360

366361

@@ -509,8 +504,7 @@ static PyObject *PythonQtInstanceWrapper_getattro(PyObject *obj,PyObject *name)
509504
return value;
510505

511506
} else {
512-
Py_INCREF(Py_None);
513-
return Py_None;
507+
Py_RETURN_NONE;
514508
}
515509
} else {
516510
QString error = QString("Trying to read property '") + attributeName + "' from a destroyed " + wrapper->classInfo()->className() + " object";

src/PythonQtProperty.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -179,8 +179,7 @@ static PyObject *PythonQtProperty_get_doc(PythonQtProperty* self, void * /*closu
179179
return self->data->doc;
180180
} else {
181181
//TODO: we could get the doc string from the fget method if no doc string is given...
182-
Py_INCREF(Py_None);
183-
return Py_None;
182+
Py_RETURN_NONE;
184183
}
185184
}
186185

src/PythonQtSignal.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,8 +116,7 @@ meth_dealloc(PyObject *o)
116116
static PyObject *
117117
meth_get__doc__(PythonQtSignalFunctionObject * /*m*/, void * /*closure*/)
118118
{
119-
Py_INCREF(Py_None);
120-
return Py_None;
119+
Py_RETURN_NONE;
121120
}
122121

123122
static PyObject *

src/PythonQtStdOut.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,8 +102,7 @@ static PyObject *PythonQtStdOutRedirect_flush(PyObject * /*self*/, PyObject * /*
102102

103103
static PyObject *PythonQtStdOutRedirect_isatty(PyObject * /*self*/, PyObject * /*args*/)
104104
{
105-
Py_INCREF(Py_False);
106-
return Py_False;
105+
Py_RETURN_FALSE;
107106
}
108107

109108
static PyMethodDef PythonQtStdOutRedirect_methods[] = {

0 commit comments

Comments
 (0)