aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCristian Maureira-Fredes <cristian.maureira-fredes@qt.io>2018-03-27 15:16:03 +0200
committerCristian Maureira-Fredes <cristian.maureira-fredes@qt.io>2018-04-19 11:00:18 +0000
commit4023ab3862eee7ca3084dd83ca76fba11b5db46b (patch)
tree5b52a1040fc5d5d34201c7484e479dac1fc6d0d2
parenta4690116881477d09f34f6b20b2ee0f31c06163d (diff)
Add default return value to pythonTypeIsValueType
When a class inherits from two base classes, Shiboken sets the converter of the newly created SbkObject to 0 (SbkObjectTypeTpNew), and handle the multiple inheritance in a different way. When any SbkObject try to release its ownership, it first verify if the ownership is already on the C++ side by checking the attribute hasOwership and also if the converter is a ValueType. The later fails if the converter is null, so a default value (false) was added. A test case using deleteLater() was included, which uses the releaseOwnership method internally. Task-number: PYSIDE-11 Change-Id: I34fba0d3e5d28b99b49a183ed08e977a311da632 Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io>
-rw-r--r--sources/pyside2/tests/QtCore/qobject_inherits_test.py37
-rw-r--r--sources/shiboken2/libshiboken/sbkconverter.cpp5
2 files changed, 40 insertions, 2 deletions
diff --git a/sources/pyside2/tests/QtCore/qobject_inherits_test.py b/sources/pyside2/tests/QtCore/qobject_inherits_test.py
index 8c4c797a4..1d089776b 100644
--- a/sources/pyside2/tests/QtCore/qobject_inherits_test.py
+++ b/sources/pyside2/tests/QtCore/qobject_inherits_test.py
@@ -29,8 +29,12 @@
'''Test cases for QObject methods'''
import unittest
+import sys
-from PySide2.QtCore import QObject
+from PySide2.QtCore import QObject, QTimer
+from PySide2.QtWidgets import QApplication, QLabel, QVBoxLayout
+
+is_alive = None
class InheritsCase(unittest.TestCase):
'''Test case for QObject.inherits'''
@@ -87,5 +91,36 @@ class InheritsCase(unittest.TestCase):
self.assertRaises(TypeError, declareClass)
+ # PYSIDE-11:
+ # The takeOwnership() method was relying that the SbkObject
+ # had a converter, which it's not the case when multiple
+ # inheritance is used.
+ # The deleteLater() method uses the takeOwnership() to give
+ # control of the object to C++, so it can be remove once
+ # the destructor is called.
+ # The solution was to add a default case when the object
+ # is null under the pythonTypeIsValueType() method in shiboken.
+ def testDeleteMultipleInheritance(self):
+ app = QApplication(sys.argv)
+ class DerivedLabel(QLabel, QObject):
+ def __del__(self):
+ global is_alive
+ is_alive = False
+
+ global is_alive
+ child = DerivedLabel('Hello')
+ is_alive = True
+ parent = QVBoxLayout()
+ parent.addWidget(child)
+ parent.removeWidget(child)
+ child.deleteLater()
+ self.assertTrue(is_alive)
+ del child
+ self.assertTrue(is_alive)
+ QTimer.singleShot(100, app.quit)
+ app.exec_()
+ self.assertFalse(is_alive)
+
+
if __name__ == '__main__':
unittest.main()
diff --git a/sources/shiboken2/libshiboken/sbkconverter.cpp b/sources/shiboken2/libshiboken/sbkconverter.cpp
index 0e154da39..c81a1612b 100644
--- a/sources/shiboken2/libshiboken/sbkconverter.cpp
+++ b/sources/shiboken2/libshiboken/sbkconverter.cpp
@@ -523,7 +523,10 @@ PyTypeObject* getPythonTypeObject(const char* typeName)
bool pythonTypeIsValueType(const SbkConverter *converter)
{
- assert(converter);
+ // Unlikely to happen but for multi-inheritance SbkObjs
+ // the converter is not defined, hence we need a default return.
+ if (!converter)
+ return false;
return converter->pointerToPython && converter->copyToPython;
}