diff options
-rw-r--r-- | sources/pyside2/libpyside/pysideweakref.cpp | 5 | ||||
-rw-r--r-- | sources/pyside2/tests/QtCore/qenum_test.py | 17 | ||||
-rw-r--r-- | sources/shiboken2/libshiboken/sbkenum.cpp | 23 |
3 files changed, 29 insertions, 16 deletions
diff --git a/sources/pyside2/libpyside/pysideweakref.cpp b/sources/pyside2/libpyside/pysideweakref.cpp index 84b390e96..cd90634bd 100644 --- a/sources/pyside2/libpyside/pysideweakref.cpp +++ b/sources/pyside2/libpyside/pysideweakref.cpp @@ -98,11 +98,6 @@ PyObject *create(PyObject *obj, PySideWeakRefFunction func, void *userData) PySideCallableObject *callable = PyObject_New(PySideCallableObject, type); if (!callable || PyErr_Occurred()) return 0; - if (!PepRuntime_38_flag) { - // PYSIDE-939: Handling references correctly. - // Workaround for Python issue 35810; no longer necessary in Python 3.8 - Py_INCREF(type); - } PyObject *weak = PyWeakref_NewRef(obj, reinterpret_cast<PyObject *>(callable)); if (!weak || PyErr_Occurred()) diff --git a/sources/pyside2/tests/QtCore/qenum_test.py b/sources/pyside2/tests/QtCore/qenum_test.py index ed58f4f20..1edb8981a 100644 --- a/sources/pyside2/tests/QtCore/qenum_test.py +++ b/sources/pyside2/tests/QtCore/qenum_test.py @@ -30,6 +30,7 @@ '''Test cases for QEnum and QFlags''' +import gc import os import sys import pickle @@ -75,6 +76,22 @@ class TestEnum(unittest.TestCase): with self.assertRaises(TypeError): a = k*2.0 + @unittest.skipUnless(getattr(sys, "getobjects", None), "requires debug build") + def testEnumNew_NoLeak(self): + gc.collect() + total = sys.gettotalrefcount() + for idx in range(1000): + ret = Qt.Key(42) + gc.collect() + delta = sys.gettotalrefcount() - total + print("delta total refcount =", delta) + if abs(delta) >= 10: + all = sys.getobjects(0) + all.sort(key=lambda x: sys.getrefcount(x), reverse=True) + for ob in all[:10]: + print(sys.getrefcount(ob), ob) + self.assertTrue(abs(delta) < 10) + class TestQFlags(unittest.TestCase): def testToItn(self): diff --git a/sources/shiboken2/libshiboken/sbkenum.cpp b/sources/shiboken2/libshiboken/sbkenum.cpp index 5b9718738..36f2f48f9 100644 --- a/sources/shiboken2/libshiboken/sbkenum.cpp +++ b/sources/shiboken2/libshiboken/sbkenum.cpp @@ -107,16 +107,18 @@ static PyObject *SbkEnum_tp_new(PyTypeObject *type, PyObject *args, PyObject *) if (!self) return nullptr; self->ob_value = itemValue; - PyObject *item = Shiboken::Enum::getEnumItemFromValue(type, itemValue); - if (item) { - self->ob_name = SbkEnumObject_name(item, nullptr); - Py_XDECREF(item); - } else { - self->ob_name = nullptr; - } + Shiboken::AutoDecRef item(Shiboken::Enum::getEnumItemFromValue(type, itemValue)); + self->ob_name = item.object() ? SbkEnumObject_name(item, nullptr) : nullptr; return reinterpret_cast<PyObject *>(self); } +void enum_object_dealloc(PyObject *ob) +{ + auto self = reinterpret_cast<SbkEnumObject *>(ob); + Py_XDECREF(self->ob_name); + Sbk_object_dealloc(ob); +} + static PyObject *enum_op(enum_func f, PyObject *a, PyObject *b) { PyObject *valA = a; PyObject *valB = b; @@ -448,7 +450,7 @@ static bool _init_enum() static void init_enum() { if (!(enum_unpickler || _init_enum())) - Py_FatalError("could not load enum helper functions"); + Py_FatalError("could not load enum pickling helper function"); } static PyMethodDef SbkEnumObject_Methods[] = { @@ -497,7 +499,7 @@ PyObject *getEnumItemFromValue(PyTypeObject *enumType, long itemValue) while (PyDict_Next(values, &pos, &key, &value)) { auto *obj = reinterpret_cast<SbkEnumObject *>(value); if (obj->ob_value == itemValue) { - Py_INCREF(obj); + Py_INCREF(value); return value; } } @@ -644,7 +646,7 @@ static PyType_Slot SbkNewType_slots[] = { {Py_nb_index, (void *)enum_int}, {Py_tp_richcompare, (void *)enum_richcompare}, {Py_tp_hash, (void *)enum_hash}, - {Py_tp_dealloc, (void *)Sbk_object_dealloc}, + {Py_tp_dealloc, (void *)enum_object_dealloc}, {0, nullptr} }; static PyType_Spec SbkNewType_spec = { @@ -735,7 +737,6 @@ newTypeWithName(const char *name, newspec->slots = newslots; auto *type = reinterpret_cast<PyTypeObject *>(SbkType_FromSpec(newspec)); Py_TYPE(type) = SbkEnumType_TypeF(); - Py_INCREF(Py_TYPE(type)); auto *enumType = reinterpret_cast<SbkEnumType *>(type); PepType_SETP(enumType)->cppName = cppName; |