aboutsummaryrefslogtreecommitdiffstats
path: root/sources/pyside6/tests/pysidetest
diff options
context:
space:
mode:
Diffstat (limited to 'sources/pyside6/tests/pysidetest')
-rw-r--r--sources/pyside6/tests/pysidetest/CMakeLists.txt21
-rw-r--r--sources/pyside6/tests/pysidetest/constructor_properties_test.py14
-rw-r--r--sources/pyside6/tests/pysidetest/container_test.py4
-rw-r--r--sources/pyside6/tests/pysidetest/enum_test.py25
-rw-r--r--sources/pyside6/tests/pysidetest/flagstest.h4
-rw-r--r--sources/pyside6/tests/pysidetest/hiddenobject.cpp2
-rw-r--r--sources/pyside6/tests/pysidetest/hiddenobject.h6
-rw-r--r--sources/pyside6/tests/pysidetest/homonymoussignalandmethod_test.py4
-rw-r--r--sources/pyside6/tests/pysidetest/multiple_inheritance_test.py189
-rw-r--r--sources/pyside6/tests/pysidetest/pyenum_relax_options_test.py22
-rw-r--r--sources/pyside6/tests/pysidetest/pysidetest_global.h1
-rw-r--r--sources/pyside6/tests/pysidetest/qvariant_test.py37
-rw-r--r--sources/pyside6/tests/pysidetest/repr_test.py9
-rw-r--r--sources/pyside6/tests/pysidetest/signalinstance_equality_test.py13
-rw-r--r--sources/pyside6/tests/pysidetest/signalwithdefaultvalue_test.py14
-rw-r--r--sources/pyside6/tests/pysidetest/snake_case_sub.py1
-rw-r--r--sources/pyside6/tests/pysidetest/snake_case_test.py6
-rw-r--r--sources/pyside6/tests/pysidetest/testobject.cpp20
-rw-r--r--sources/pyside6/tests/pysidetest/testobject.h26
-rw-r--r--sources/pyside6/tests/pysidetest/testqvariantenum.cpp29
-rw-r--r--sources/pyside6/tests/pysidetest/testqvariantenum.h35
-rw-r--r--sources/pyside6/tests/pysidetest/testview.cpp2
-rw-r--r--sources/pyside6/tests/pysidetest/testview.h5
-rw-r--r--sources/pyside6/tests/pysidetest/true_property_test.py22
-rw-r--r--sources/pyside6/tests/pysidetest/typedef_signal_test.py15
-rw-r--r--sources/pyside6/tests/pysidetest/typesystem_pysidetest.xml12
26 files changed, 477 insertions, 61 deletions
diff --git a/sources/pyside6/tests/pysidetest/CMakeLists.txt b/sources/pyside6/tests/pysidetest/CMakeLists.txt
index 76a8e02f5..38f42f342 100644
--- a/sources/pyside6/tests/pysidetest/CMakeLists.txt
+++ b/sources/pyside6/tests/pysidetest/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
project(pysidetest)
project(testbinding)
@@ -17,12 +20,15 @@ add_definitions(-DRXX_ALLOCATOR_INIT_0)
find_package(Qt6 REQUIRED COMPONENTS Widgets)
set(pysidetest_SRC
-containertest.cpp
-flagstest.cpp
-testobject.cpp
-testview.cpp
-hiddenobject.cpp
-sharedpointertestbench.cpp
+containertest.cpp containertest.h
+flagstest.cpp flagstest.h
+hiddenobject.cpp hiddenobject.h
+pysidetest_global.h
+pysidetest_macros.h
+sharedpointertestbench.cpp sharedpointertestbench.h
+testobject.cpp testobject.h
+testview.cpp testview.h
+testqvariantenum.cpp testqvariantenum.h
)
set(testbinding_SRC
@@ -39,6 +45,8 @@ ${CMAKE_CURRENT_BINARY_DIR}/testbinding/qsharedpointer_int_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/testbinding/sharedpointertestbench_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/testbinding/testview_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/testbinding/testbinding_module_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/testbinding/testqvariantenum_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/testbinding/qvariantholder_wrapper.cpp
)
# Get per module include dirs.
@@ -140,6 +148,7 @@ PYSIDE_TEST(iterable_test.py)
PYSIDE_TEST(list_signal_test.py)
PYSIDE_TEST(mixin_signal_slots_test.py)
PYSIDE_TEST(modelview_test.py)
+PYSIDE_TEST(multiple_inheritance_test.py)
PYSIDE_TEST(new_inherited_functions_test.py)
PYSIDE_TEST(notify_id.py)
PYSIDE_TEST(properties_test.py)
diff --git a/sources/pyside6/tests/pysidetest/constructor_properties_test.py b/sources/pyside6/tests/pysidetest/constructor_properties_test.py
index 9f1a9d43c..ec6e39821 100644
--- a/sources/pyside6/tests/pysidetest/constructor_properties_test.py
+++ b/sources/pyside6/tests/pysidetest/constructor_properties_test.py
@@ -36,7 +36,7 @@ class ConstructorPropertiesTest(unittest.TestCase):
def testCallConstructor(self):
label = QLabel(
frameStyle=QFrame.Panel | QFrame.Sunken, # QFrame attr, no property
- lineWidth = 2, # QFrame property
+ lineWidth=2, # QFrame property
text="first line\nsecond line", # QLabel property
alignment=Qt.AlignBottom | Qt.AlignRight # QLabel property
)
@@ -52,13 +52,13 @@ class ConstructorPropertiesTest(unittest.TestCase):
label = QLabel(
frame_style=QFrame.Panel | QFrame.Sunken, # QFrame attr, no property
- line_width = 2, # QFrame property
+ line_width=2, # QFrame property
text="first line\nsecond line", # QLabel property
alignment=Qt.AlignBottom | Qt.AlignRight # QLabel property
)
self.assertEqual(label.line_width(), 2)
self.assertRaises(AttributeError, lambda: QLabel(
- lineWidth = 2, # QFrame property
+ lineWidth=2, # QFrame property
))
# PYSIDE-1705: The same with true_property
@@ -68,13 +68,13 @@ class ConstructorPropertiesTest(unittest.TestCase):
label = QLabel(
frameStyle=QFrame.Panel | QFrame.Sunken, # QFrame attr, no property
- lineWidth = 2, # QFrame property
+ lineWidth=2, # QFrame property
text="first line\nsecond line", # QLabel property
alignment=Qt.AlignBottom | Qt.AlignRight # QLabel property
)
self.assertEqual(label.lineWidth, 2)
self.assertRaises(AttributeError, lambda: QLabel(
- line_width = 2, # QFrame property
+ line_width=2, # QFrame property
))
# PYSIDE-1705: The same with snake_case and true_property
@@ -84,13 +84,13 @@ class ConstructorPropertiesTest(unittest.TestCase):
label = QLabel(
frame_style=QFrame.Panel | QFrame.Sunken, # QFrame attr, no property
- line_width = 2, # QFrame property
+ line_width=2, # QFrame property
text="first line\nsecond line", # QLabel property
alignment=Qt.AlignBottom | Qt.AlignRight # QLabel property
)
self.assertEqual(label.line_width, 2)
self.assertRaises(AttributeError, lambda: QLabel(
- lineWidth = 2, # QFrame property
+ lineWidth=2, # QFrame property
))
diff --git a/sources/pyside6/tests/pysidetest/container_test.py b/sources/pyside6/tests/pysidetest/container_test.py
index 68c3638cd..c83e1f26c 100644
--- a/sources/pyside6/tests/pysidetest/container_test.py
+++ b/sources/pyside6/tests/pysidetest/container_test.py
@@ -44,13 +44,13 @@ class ContainerTestTest(unittest.TestCase):
self.assertEqual(sort_values(m2), EXPECTED_DICT)
def testList(self):
- l1 = ContainerTest.createList();
+ l1 = ContainerTest.createList()
self.assertEqual(l1, EXPECTED_LIST)
l2 = ContainerTest.passThroughList(l1)
self.assertEqual(l2, EXPECTED_LIST)
def testSet(self):
- s1 = ContainerTest.createSet(); # Order is not predictable
+ s1 = ContainerTest.createSet() # Order is not predictable
s2 = ContainerTest.passThroughSet(s1)
self.assertEqual(sorted(list(s1)), sorted(list(s2)))
diff --git a/sources/pyside6/tests/pysidetest/enum_test.py b/sources/pyside6/tests/pysidetest/enum_test.py
index 158faf37c..832834530 100644
--- a/sources/pyside6/tests/pysidetest/enum_test.py
+++ b/sources/pyside6/tests/pysidetest/enum_test.py
@@ -15,6 +15,7 @@ from testbinding import Enum1, TestObjectWithoutNamespace
import dis
+
class ListConnectionTest(unittest.TestCase):
def testEnumVisibility(self):
@@ -45,6 +46,7 @@ class ListConnectionTest(unittest.TestCase):
self.assertFalse(Qt.AlignBottom < Qt.AlignHCenter)
self.assertTrue(Qt.AlignBottom > Qt.AlignHCenter)
+
# PYSIDE-1735: We are testing that opcodes do what they are supposed to do.
# This is needed in the PyEnum forgiveness mode where we need
# to introspect the code if an Enum was called with no args.
@@ -68,7 +70,11 @@ class InvestigateOpcodesTest(unittest.TestCase):
res.append((ops[idx - 1][0], ops[idx][1] - ops[idx - 1][1]))
return sorted(res, key=lambda x: (x[1], x[0]))
+ _sin = sys.implementation.name
+
+ @unittest.skipIf(hasattr(sys.flags, "nogil"), f"{_sin} has different opcodes")
def testByteCode(self):
+ import dis
# opname, opcode, arg
result_1 = [('LOAD_GLOBAL', 116, 0),
('LOAD_ATTR', 106, 1),
@@ -92,7 +98,7 @@ class InvestigateOpcodesTest(unittest.TestCase):
('LOAD_CONST', 100, 0),
('RETURN_VALUE', 83, None)]
- if sys.version_info[:2] >= (3, 11):
+ if sys.version_info[:2] == (3, 11):
# Note: Python 3.11 is a bit more complex because it can optimize itself.
# Opcodes are a bit different, and a hidden second code object is used.
# We investigate this a bit, because we want to be warned when things change.
@@ -131,7 +137,7 @@ class InvestigateOpcodesTest(unittest.TestCase):
for _ in range(times):
f()
- code_quicken(self.probe_function2, QUICKENING_WARMUP_DELAY-1)
+ code_quicken(self.probe_function2, QUICKENING_WARMUP_DELAY - 1)
self.assertEqual(self.read_code(self.probe_function2, adaptive=True), result_2)
self.assertEqual(self.get_sizes(self.probe_function2, adaptive=True), sizes_2)
@@ -156,6 +162,21 @@ class InvestigateOpcodesTest(unittest.TestCase):
self.assertEqual(self.read_code(self.probe_function2, adaptive=True), result_3)
self.assertEqual(self.get_sizes(self.probe_function2, adaptive=True), sizes_3)
+ if sys.version_info[:2] >= (3, 12):
+
+ result_1 = [('RESUME', 151, 0),
+ ('LOAD_GLOBAL', 116, 0),
+ ('LOAD_ATTR', 106, 2),
+ ('STORE_FAST', 125, 1),
+ ('RETURN_CONST', 121, 0)]
+
+ result_2 = [('RESUME', 151, 0),
+ ('LOAD_GLOBAL', 116, 1),
+ ('LOAD_ATTR', 106, 2),
+ ('CALL', 171, 0),
+ ('STORE_FAST', 125, 1),
+ ('RETURN_CONST', 121, 0)]
+
self.assertEqual(self.read_code(self.probe_function1), result_1)
self.assertEqual(self.read_code(self.probe_function2), result_2)
diff --git a/sources/pyside6/tests/pysidetest/flagstest.h b/sources/pyside6/tests/pysidetest/flagstest.h
index 9058561f6..b5c73c9bd 100644
--- a/sources/pyside6/tests/pysidetest/flagstest.h
+++ b/sources/pyside6/tests/pysidetest/flagstest.h
@@ -23,8 +23,10 @@ class PYSIDETEST_API ClassForEnum : public QObject
{
Q_OBJECT
public:
+ Q_DISABLE_COPY_MOVE(ClassForEnum)
+
ClassForEnum(FlagsNamespace::Options opt = FlagsNamespace::Option::NoOptions);
- virtual ~ClassForEnum();
+ virtual ~ClassForEnum() override;
};
} // namespace FlagsNamespace
diff --git a/sources/pyside6/tests/pysidetest/hiddenobject.cpp b/sources/pyside6/tests/pysidetest/hiddenobject.cpp
index bba0de2ee..d4feabb66 100644
--- a/sources/pyside6/tests/pysidetest/hiddenobject.cpp
+++ b/sources/pyside6/tests/pysidetest/hiddenobject.cpp
@@ -8,7 +8,7 @@ void HiddenObject::callMe()
m_called = true;
}
-bool HiddenObject::wasCalled()
+bool HiddenObject::wasCalled() const
{
return m_called;
}
diff --git a/sources/pyside6/tests/pysidetest/hiddenobject.h b/sources/pyside6/tests/pysidetest/hiddenobject.h
index e3d0abbef..f399be985 100644
--- a/sources/pyside6/tests/pysidetest/hiddenobject.h
+++ b/sources/pyside6/tests/pysidetest/hiddenobject.h
@@ -13,12 +13,12 @@ class HiddenObject : public QObject
{
Q_OBJECT
public:
- HiddenObject() : m_called(false) {}
+ HiddenObject() noexcept = default;
Q_INVOKABLE void callMe();
public Q_SLOTS:
- bool wasCalled();
+ bool wasCalled() const;
private:
- bool m_called;
+ bool m_called = false;
};
// Return a instance of HiddenObject
diff --git a/sources/pyside6/tests/pysidetest/homonymoussignalandmethod_test.py b/sources/pyside6/tests/pysidetest/homonymoussignalandmethod_test.py
index 52c65e541..b58232a1b 100644
--- a/sources/pyside6/tests/pysidetest/homonymoussignalandmethod_test.py
+++ b/sources/pyside6/tests/pysidetest/homonymoussignalandmethod_test.py
@@ -99,8 +99,8 @@ class HomonymousMultipleInheritanceTest(unittest.TestCase):
def testHomonymousMultipleInheritance(self):
c = C()
- self.assertEqual(c.method(), "M::method") # okay
- self.assertEqual(c.signal(), "M::signal") # problem on PySide6 6.2.2
+ self.assertEqual(c.method(), "M::method") # okay
+ self.assertEqual(c.signal(), "M::signal") # problem on PySide6 6.2.2
self.assertEqual(type(c.signal), SignalInstance)
diff --git a/sources/pyside6/tests/pysidetest/multiple_inheritance_test.py b/sources/pyside6/tests/pysidetest/multiple_inheritance_test.py
new file mode 100644
index 000000000..49550ba55
--- /dev/null
+++ b/sources/pyside6/tests/pysidetest/multiple_inheritance_test.py
@@ -0,0 +1,189 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from helper.usesqapplication import UsesQApplication
+from PySide6 import QtCore, QtGui, QtWidgets
+from PySide6.QtWidgets import QMainWindow, QLabel, QWidget
+
+
+def xprint(*args, **kw):
+ if "-v" in sys.argv:
+ print(*args, **kw)
+
+
+# This is the original testcase of PYSIDE-1564
+class Age(object):
+ def __init__(self, age=0, **kwds):
+ super().__init__(**kwds)
+
+ self.age = age
+
+
+class Person(QtCore.QObject, Age):
+ def __init__(self, name, **kwds):
+ super().__init__(**kwds)
+
+ self.name = name
+
+
+class OriginalMultipleInheritanceTest(unittest.TestCase):
+
+ def testIt(self):
+ xprint()
+ p = Person("Joe", age=38)
+ xprint(f"p.age = {p.age}")
+ # This would crash if MI does not work.
+
+# More tests follow:
+
+
+# mro ('C', 'A', 'QObject', 'Object', 'B', 'object')
+class A(QtCore.QObject):
+ def __init__(self, anna=77, **kw):
+ xprint(f'A: before init kw = {kw}')
+ super().__init__(**kw)
+ xprint('A: after init')
+
+
+class B:
+ def __init__(self, otto=6, age=7, **kw):
+ xprint(f'B: before init kw = {kw}')
+ if "killme" in kw:
+ raise AssertionError("asdf")
+ super().__init__(**kw)
+ self.age = age
+ xprint('B: after init')
+
+
+class C(A, B):
+ def __init__(self, **kw):
+ xprint(f'C: before init kw = {kw}')
+ super().__init__(**kw)
+ xprint('C: after init')
+
+
+# mro ('F', 'D', 'QCursor', 'E', 'QLabel', 'QFrame', 'QWidget', 'QObject',
+# 'QPaintDevice', 'Object', 'object')
+class D(QtGui.QCursor):
+ def __init__(self, anna=77, **kw):
+ xprint(f'D: before init kw = {kw}')
+ super().__init__(**kw)
+ xprint('D: after init')
+
+
+class E:
+ def __init__(self, age=7, **kw):
+ xprint(f'E: before init kw = {kw}')
+ super().__init__(**kw)
+ self.age = age
+ xprint('E: after init')
+
+
+class F(D, E, QtWidgets.QLabel):
+ def __init__(self, **kw):
+ xprint(f'F: before init kw = {kw}')
+ super().__init__(**kw)
+ xprint('F: after init')
+
+
+# mro ('I', 'G', 'QTextDocument', 'H', 'QLabel', 'QFrame', 'QWidget', 'QObject',
+# 'QPaintDevice', 'Object', 'object')
+# Similar, but this time we want to reach `H` without support from `super`.
+class G(QtGui.QTextDocument):
+ pass
+
+
+class H:
+ def __init__(self, age=7, **kw):
+ xprint(f'H: before init kw = {kw}')
+ super().__init__(**kw)
+ self.age = age
+ xprint('H: after init')
+
+
+class II(G, H, QtWidgets.QLabel):
+ pass
+
+
+# PYSIDE-2294: Friedemann's test adapted.
+# We need to ignore positional args in mixin classes.
+class Ui_X_MainWindow(object): # Emulating uic
+ def setupUi(self, MainWindow):
+ MainWindow.resize(400, 300)
+ self.lbl = QLabel(self)
+
+
+class MainWindow(QMainWindow, Ui_X_MainWindow):
+ def __init__(self, parent=None):
+ super().__init__(parent)
+ self.setupUi(self)
+
+
+class AdditionalMultipleInheritanceTest(UsesQApplication):
+
+ def testABC(self):
+ xprint()
+ res = C(otto=3, anna=5)
+ self.assertEqual(res.age, 7)
+ xprint()
+ with self.assertRaises(AssertionError):
+ res = C(killme=42)
+ xprint()
+
+ def testDEF(self):
+ xprint()
+ res = F(anna=5)
+ self.assertEqual(res.age, 7)
+ xprint()
+
+ def testGHI(self):
+ xprint()
+ res = II(age=7)
+ self.assertEqual(res.age, 7)
+ xprint()
+
+ def testParentDoesNotCrash(self):
+ # This crashed with
+ # TypeError: object.__init__() takes exactly one argument (the instance to initialize)
+ MainWindow()
+
+
+# PYSIDE-2654: Additional missing init test.
+# This must work if no __init__ is defined (Ui_Form)
+class Ui_Form(object):
+ pass
+
+
+class Mixin:
+ def __init__(self, **kwargs) -> None:
+ super().__init__(**kwargs)
+
+
+class Card(Mixin, QWidget):
+ def __init__(self, parent=None) -> None:
+ super().__init__(parent=parent)
+
+
+class Demo(Card, Ui_Form):
+ def __init__(self) -> None:
+ super().__init__()
+
+
+class MissingInitFunctionTest(UsesQApplication):
+ def testMissing(self):
+ Demo()
+ # Tests if this works. Would crash without the extra
+ # check for object.__init__
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/sources/pyside6/tests/pysidetest/pyenum_relax_options_test.py b/sources/pyside6/tests/pysidetest/pyenum_relax_options_test.py
index 0dcec5a4c..625f9cdc5 100644
--- a/sources/pyside6/tests/pysidetest/pyenum_relax_options_test.py
+++ b/sources/pyside6/tests/pysidetest/pyenum_relax_options_test.py
@@ -49,46 +49,52 @@ def runtest(program):
finally:
os.unlink(fp.name)
+
def testprog2(option):
return runtest(dedent(f"""
- sys.pyside63_option_python_enum = {option}
+ sys.pyside6_option_python_enum = {option}
from PySide6 import QtCore
from enum import IntEnum
assert(issubclass(QtCore.Qt.DateFormat, IntEnum))
"""))
+
def testprog4(option):
return runtest(dedent(f"""
- sys.pyside63_option_python_enum = {option}
+ sys.pyside6_option_python_enum = {option}
from PySide6 import QtCore
QtCore.QtDebugMsg
"""))
+
def testprog8_16(option):
# this test needs flag 16, or the effect would be hidden by forgiving mode
return runtest(dedent(f"""
- sys.pyside63_option_python_enum = {option}
+ sys.pyside6_option_python_enum = {option}
from PySide6 import QtCore
QtCore.Qt.AlignTop
"""))
+
def testprog32(option):
return runtest(dedent(f"""
- sys.pyside63_option_python_enum = {option}
+ sys.pyside6_option_python_enum = {option}
from PySide6 import QtCore
QtCore.Qt.Alignment
"""))
+
def testprog64(option):
return runtest(dedent(f"""
- sys.pyside63_option_python_enum = {option}
+ sys.pyside6_option_python_enum = {option}
from PySide6 import QtCore
QtCore.Qt.AlignmentFlag()
"""))
+
def testprog128(option):
return runtest(dedent(f"""
- sys.pyside63_option_python_enum = {option}
+ sys.pyside6_option_python_enum = {option}
from PySide6 import QtCore
QtCore.Qt.Key(1234567)
"""))
@@ -110,8 +116,8 @@ class TestPyEnumRelaxOption(unittest.TestCase):
self.assertTrue(testprog4(12))
def test_localDefault(self):
- self.assertTrue(testprog8_16(8+16))
- self.assertFalse(testprog8_16(0+16))
+ self.assertTrue(testprog8_16(8 + 16))
+ self.assertFalse(testprog8_16(0 + 16))
def test_fakeRenames(self):
self.assertTrue(testprog32(1))
diff --git a/sources/pyside6/tests/pysidetest/pysidetest_global.h b/sources/pyside6/tests/pysidetest/pysidetest_global.h
index 461b6f56f..6f784dc58 100644
--- a/sources/pyside6/tests/pysidetest/pysidetest_global.h
+++ b/sources/pyside6/tests/pysidetest/pysidetest_global.h
@@ -11,5 +11,6 @@
#include "flagstest.h"
#include "hiddenobject.h"
#include "sharedpointertestbench.h"
+#include "testqvariantenum.h"
#endif // PYSIDETEST_GLOBAL_H
diff --git a/sources/pyside6/tests/pysidetest/qvariant_test.py b/sources/pyside6/tests/pysidetest/qvariant_test.py
index 5addb00e0..faefc8169 100644
--- a/sources/pyside6/tests/pysidetest/qvariant_test.py
+++ b/sources/pyside6/tests/pysidetest/qvariant_test.py
@@ -1,6 +1,7 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+import enum
import os
import sys
import unittest
@@ -10,13 +11,25 @@ sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
from init_paths import init_test_paths
init_test_paths(True)
-from testbinding import TestObject
+from testbinding import TestObject, TestQVariantEnum
from PySide6.QtCore import Qt, QKeyCombination
from PySide6.QtGui import QKeySequence, QAction
from helper.usesqapplication import UsesQApplication
+class PyTestQVariantEnum(TestQVariantEnum):
+ def __init__(self, var_enum):
+ super().__init__(var_enum)
+
+ def getRValEnum(self):
+ return Qt.Orientation.Vertical
+
+ def channelingEnum(self, rval_enum):
+ return (isinstance(rval_enum, enum.Enum)
+ and rval_enum == Qt.Orientation.Vertical)
+
+
class QVariantTest(UsesQApplication):
def testQKeySequenceQVariantOperator(self):
@@ -24,16 +37,30 @@ class QVariantTest(UsesQApplication):
ks = QKeySequence(Qt.ShiftModifier, Qt.ControlModifier, Qt.Key_P, Qt.Key_R)
self.assertEqual(TestObject.checkType(ks), 4107)
- # PYSIDE-1735: Test the new way to address QKeyCombination after moving IntEnum to Enum
- @unittest.skipUnless(sys.pyside63_option_python_enum, "only implemented for new enums")
def testQKeySequenceMoreVariations(self):
QAction().setShortcut(Qt.CTRL | Qt.Key_B)
QAction().setShortcut(Qt.CTRL | Qt.ALT | Qt.Key_B)
QAction().setShortcut(Qt.CTRL | Qt.AltModifier | Qt.Key_B)
QAction().setShortcut(QKeySequence(QKeyCombination(Qt.CTRL | Qt.Key_B)))
QKeySequence(Qt.CTRL | Qt.Key_Q)
- # Issues a warning but works as well
- QKeySequence(Qt.CTRL + Qt.Key_Q)
+
+ def testEnum(self):
+ # Testing C++ class
+ testqvariant = TestQVariantEnum(Qt.CheckState.Checked)
+ self.assertEqual(testqvariant.getLValEnum(), Qt.CheckState.Checked)
+ self.assertIsInstance(testqvariant.getLValEnum(), enum.Enum)
+ # in the case where we return a QVariant of C++ enum, it returns a
+ # QVariant(int) to Python unless explicitly handled manually by Shiboken
+ self.assertEqual(testqvariant.getRValEnum(), 1)
+ self.assertEqual(testqvariant.isEnumChanneled(), False)
+
+ # Testing Python child class
+ pytestqvariant = PyTestQVariantEnum(Qt.CheckState.Checked)
+ self.assertEqual(pytestqvariant.isEnumChanneled(), True)
+ # check toInt() conversion works for PyObjectWrapper
+ self.assertEqual(PyTestQVariantEnum.getNumberFromQVarEnum(Qt.Orientation.Vertical), 2)
+ # check toInt() conversion for IntEnum
+ self.assertEqual(PyTestQVariantEnum.getNumberFromQVarEnum(Qt.GestureType.TapGesture), 1)
if __name__ == '__main__':
diff --git a/sources/pyside6/tests/pysidetest/repr_test.py b/sources/pyside6/tests/pysidetest/repr_test.py
index 01cc36b37..863f17657 100644
--- a/sources/pyside6/tests/pysidetest/repr_test.py
+++ b/sources/pyside6/tests/pysidetest/repr_test.py
@@ -49,6 +49,15 @@ class QObjectDerivedReprTest(unittest.TestCase):
# __repr__ should use the operator<<(QDebug,...) implementation
self.assertEqual(str(t), "TestObject2WithNamespace(injected_repr)")
+ def testLatin1StringField(self):
+ self.assertEqual(TestObject.LATIN1_TEST_FIELD, "test")
+
+ def testLatin1Setter(self):
+ to = TestObject(123)
+ value = "test"
+ to.setQLatin1String(value)
+ self.assertEqual(to.qLatin1String(), value)
+
if __name__ == '__main__':
unittest.main()
diff --git a/sources/pyside6/tests/pysidetest/signalinstance_equality_test.py b/sources/pyside6/tests/pysidetest/signalinstance_equality_test.py
index 732420c4d..5faaa38d4 100644
--- a/sources/pyside6/tests/pysidetest/signalinstance_equality_test.py
+++ b/sources/pyside6/tests/pysidetest/signalinstance_equality_test.py
@@ -12,7 +12,7 @@ init_test_paths(False)
from helper.usesqapplication import UsesQApplication
-from PySide6.QtCore import QFile, QObject, QTimer, Signal, Slot
+from PySide6.QtCore import QFile, QObject, QTimer, Signal, SignalInstance, Slot
from PySide6.QtWidgets import QSlider
@@ -41,6 +41,17 @@ class TestSignalInstance(unittest.TestCase):
o = D()
self.assertTrue(o.custom_signal == o.custom_signal)
+ # additional tests of old errors from 2010 or so
+ def test_uninitialized_SignalInstance(self):
+ # This will no longer crash
+ print(SignalInstance())
+ with self.assertRaises(RuntimeError):
+ SignalInstance().connect(lambda: None)
+ with self.assertRaises(RuntimeError):
+ SignalInstance().disconnect()
+ with self.assertRaises(RuntimeError):
+ SignalInstance().emit()
+
class MyWidget(QSlider):
valueChanged = Signal(tuple)
diff --git a/sources/pyside6/tests/pysidetest/signalwithdefaultvalue_test.py b/sources/pyside6/tests/pysidetest/signalwithdefaultvalue_test.py
index cf09b2964..744b8c503 100644
--- a/sources/pyside6/tests/pysidetest/signalwithdefaultvalue_test.py
+++ b/sources/pyside6/tests/pysidetest/signalwithdefaultvalue_test.py
@@ -13,7 +13,7 @@ from init_paths import init_test_paths
init_test_paths(True)
from testbinding import TestObject
-from PySide6.QtCore import QObject, SIGNAL
+from PySide6.QtCore import Qt
'''Tests the behaviour of signals with default values.'''
@@ -56,6 +56,17 @@ class SignalWithDefaultValueTest(unittest.TestCase):
self.assertTrue(self.void_called)
self.assertTrue(self.bool_called)
+ def testFlagsSignal(self):
+ test_value = Qt.AlignmentFlag.AlignLeft | Qt.AlignmentFlag.AlignBottom
+
+ def callbackAlignmentFlags(alignment):
+ self.alignment_flags_called = alignment
+
+ self.obj.flagsSignal.connect(callbackAlignmentFlags)
+ self.obj.emitFlagsSignal(test_value)
+ self.assertTrue(self.alignment_flags_called)
+ self.assertEqual(self.alignment_flags_called, test_value)
+
def testConnectOldStyleEmitVoidSignal(self):
def callbackVoid():
self.void_called = True
@@ -83,4 +94,3 @@ class SignalWithDefaultValueTest(unittest.TestCase):
if __name__ == '__main__':
unittest.main()
-
diff --git a/sources/pyside6/tests/pysidetest/snake_case_sub.py b/sources/pyside6/tests/pysidetest/snake_case_sub.py
index 5056d50bb..4a482c35a 100644
--- a/sources/pyside6/tests/pysidetest/snake_case_sub.py
+++ b/sources/pyside6/tests/pysidetest/snake_case_sub.py
@@ -16,6 +16,7 @@ PYSIDE-2029: Tests that snake_case is isolated from imported modules
from PySide6.QtWidgets import QWidget
+
def test_no_snake_case():
print(__name__)
widget = QWidget()
diff --git a/sources/pyside6/tests/pysidetest/snake_case_test.py b/sources/pyside6/tests/pysidetest/snake_case_test.py
index aaa3d3f2a..14e035773 100644
--- a/sources/pyside6/tests/pysidetest/snake_case_test.py
+++ b/sources/pyside6/tests/pysidetest/snake_case_test.py
@@ -13,14 +13,17 @@ init_test_paths(False)
"""
PYSIDE-2029: Tests that snake_case is isolated from imported modules
"""
+is_pypy = hasattr(sys, "pypy_version_info")
from PySide6.QtCore import QSize
from PySide6.QtWidgets import QWidget, QSpinBox
-from __feature__ import snake_case
+if not is_pypy:
+ from __feature__ import snake_case
from helper.usesqapplication import UsesQApplication
import snake_case_sub
+@unittest.skipIf(is_pypy, "__feature__ cannot yet be used with PyPy")
class SnakeCaseNoPropagateTest(UsesQApplication):
def testSnakeCase(self):
@@ -30,5 +33,6 @@ class SnakeCaseNoPropagateTest(UsesQApplication):
snake_case_sub.test_no_snake_case()
+
if __name__ == '__main__':
unittest.main()
diff --git a/sources/pyside6/tests/pysidetest/testobject.cpp b/sources/pyside6/tests/pysidetest/testobject.cpp
index 2233bad62..fe4ec98f7 100644
--- a/sources/pyside6/tests/pysidetest/testobject.cpp
+++ b/sources/pyside6/tests/pysidetest/testobject.cpp
@@ -30,6 +30,26 @@ void TestObject::emitSignalWithTypedefValue(int value)
emit signalWithTypedefValue(TypedefValue(value));
}
+void TestObject::emitSignalWithContainerTypedefValue(const IntList &il)
+{
+ emit signalWithContainerTypedefValue(il);
+}
+
+void TestObject::emitFlagsSignal(Qt::Alignment alignment)
+{
+ emit flagsSignal(alignment);
+}
+
+void TestObject::setQLatin1String(QLatin1String v)
+{
+ m_qLatin1String = v;
+}
+
+QString TestObject::qLatin1String() const
+{
+ return m_qLatin1String;
+}
+
QDebug operator<<(QDebug dbg, TestObject& testObject)
{
QDebugStateSaver saver(dbg);
diff --git a/sources/pyside6/tests/pysidetest/testobject.h b/sources/pyside6/tests/pysidetest/testobject.h
index 88652bcca..a095a382e 100644
--- a/sources/pyside6/tests/pysidetest/testobject.h
+++ b/sources/pyside6/tests/pysidetest/testobject.h
@@ -8,12 +8,15 @@
#include <QtWidgets/QApplication>
+#include <QtCore/QList>
#include <QtCore/QObject>
#include <QtCore/QMetaType>
#include <QtCore/QVariant>
QT_FORWARD_DECLARE_CLASS(QDebug)
+using IntList = QList<int>;
+
class IntValue
{
public:
@@ -23,16 +26,16 @@ public:
int value;
};
-typedef IntValue TypedefValue;
+using TypedefValue = IntValue;
class PYSIDETEST_API TestObject : public QObject
{
Q_OBJECT
public:
- static void createApp() { int argc=0; new QApplication(argc, 0); };
+ static void createApp() { int argc=0; new QApplication(argc, nullptr); };
static int checkType(const QVariant& var) { return var.metaType().id(); }
- TestObject(int idValue, QObject* parent = 0) : QObject(parent), m_idValue(idValue) {}
+ TestObject(int idValue, QObject* parent = nullptr) : QObject(parent), m_idValue(idValue) {}
int idValue() const { return m_idValue; }
static int staticMethodDouble(int value) { return value * 2; }
void addChild(QObject* c) { m_children.append(c); emit childrenChanged(m_children); }
@@ -44,6 +47,14 @@ public:
void emitSignalWithDefaultValue_bool();
void emitSignalWithTypedefValue(int value);
+ void emitSignalWithContainerTypedefValue(const IntList &il);
+
+ void emitFlagsSignal(Qt::Alignment alignment);
+
+ static constexpr auto LATIN1_TEST_FIELD = QLatin1StringView("test");
+
+ void setQLatin1String(QLatin1String v);
+ QString qLatin1String() const;
signals:
void idValue(int newValue);
@@ -52,16 +63,18 @@ signals:
void childrenChanged(const QList<QObject*>&);
void signalWithDefaultValue(bool value = false);
void signalWithTypedefValue(TypedefValue value);
+ void signalWithContainerTypedefValue(const IntList &il);
+ void flagsSignal(Qt::Alignment alignment);
private:
int m_idValue;
QList<QObject*> m_children;
+ QString m_qLatin1String;
};
PYSIDETEST_API QDebug operator<<(QDebug dbg, TestObject &testObject);
-typedef int PySideInt;
-
+using PySideInt = int;
namespace PySideCPP {
@@ -100,8 +113,7 @@ namespace PySideCPP2 {
enum Enum1 { Option1 = 1, Option2 = 2 };
-
-typedef long PySideLong;
+using PySideLong = long;
class PYSIDETEST_API TestObjectWithoutNamespace : public QObject
{
diff --git a/sources/pyside6/tests/pysidetest/testqvariantenum.cpp b/sources/pyside6/tests/pysidetest/testqvariantenum.cpp
new file mode 100644
index 000000000..7135e422a
--- /dev/null
+++ b/sources/pyside6/tests/pysidetest/testqvariantenum.cpp
@@ -0,0 +1,29 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#include "testqvariantenum.h"
+
+QVariant TestQVariantEnum::getLValEnum() const
+{
+ return this->m_enum;
+}
+
+QVariant TestQVariantEnum::getRValEnum() const
+{
+ return QVariant(Qt::Orientation::Horizontal);
+}
+
+int TestQVariantEnum::getNumberFromQVarEnum(QVariant variantEnum)
+{
+ return variantEnum.toInt();
+}
+
+bool TestQVariantEnum::channelingEnum([[maybe_unused]] QVariant rvalEnum) const
+{
+ return false;
+}
+
+bool TestQVariantEnum::isEnumChanneled() const
+{
+ return this->channelingEnum(this->getRValEnum());
+}
diff --git a/sources/pyside6/tests/pysidetest/testqvariantenum.h b/sources/pyside6/tests/pysidetest/testqvariantenum.h
new file mode 100644
index 000000000..4b729e3dd
--- /dev/null
+++ b/sources/pyside6/tests/pysidetest/testqvariantenum.h
@@ -0,0 +1,35 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef TESTQVARIANT_H
+#define TESTQVARIANT_H
+
+#include "pysidetest_macros.h"
+
+#include <QtCore/QVariant>
+
+class PYSIDETEST_API TestQVariantEnum
+{
+public:
+ TestQVariantEnum(QVariant lvalue_enum) : m_enum(lvalue_enum) {}
+ QVariant getLValEnum() const;
+ static int getNumberFromQVarEnum(QVariant variantEnum = QVariant());
+ bool isEnumChanneled() const;
+ virtual QVariant getRValEnum() const;
+ virtual bool channelingEnum(QVariant rvalEnum) const;
+ virtual ~TestQVariantEnum() = default;
+private:
+ QVariant m_enum;
+};
+
+class PYSIDETEST_API QVariantHolder // modeled after Q3DParameter, test QVariant conversion
+{
+public:
+ void setValue(QVariant v) { m_variant = v; }
+ QVariant value() const { return m_variant; }
+
+private:
+ QVariant m_variant;
+};
+
+#endif // TESTQVARIANT_H
diff --git a/sources/pyside6/tests/pysidetest/testview.cpp b/sources/pyside6/tests/pysidetest/testview.cpp
index ade60682f..362239112 100644
--- a/sources/pyside6/tests/pysidetest/testview.cpp
+++ b/sources/pyside6/tests/pysidetest/testview.cpp
@@ -18,7 +18,7 @@ TestView::getData()
QWidget*
TestView::getEditorWidgetFromItemDelegate() const
{
- if (!m_delegate)
+ if (m_delegate == nullptr)
return nullptr;
QModelIndex index;
diff --git a/sources/pyside6/tests/pysidetest/testview.h b/sources/pyside6/tests/pysidetest/testview.h
index ee9ca9ce0..746def83e 100644
--- a/sources/pyside6/tests/pysidetest/testview.h
+++ b/sources/pyside6/tests/pysidetest/testview.h
@@ -18,7 +18,8 @@ class PYSIDETEST_API TestView : public QObject
{
Q_OBJECT
public:
- TestView(QAbstractListModel* model, QObject* parent = 0) : QObject(parent), m_model(model) {}
+ TestView(QAbstractListModel* model, QObject* parent = nullptr) :
+ QObject(parent), m_model(model) {}
QAbstractListModel* model() { return m_model; }
QVariant getData();
@@ -27,7 +28,7 @@ public:
private:
QAbstractListModel* m_model;
- QAbstractItemDelegate* m_delegate;
+ QAbstractItemDelegate* m_delegate = nullptr;
};
#endif // TESTVIEW_H
diff --git a/sources/pyside6/tests/pysidetest/true_property_test.py b/sources/pyside6/tests/pysidetest/true_property_test.py
index 671cc4571..62f6505dc 100644
--- a/sources/pyside6/tests/pysidetest/true_property_test.py
+++ b/sources/pyside6/tests/pysidetest/true_property_test.py
@@ -13,13 +13,16 @@ init_test_paths(False)
"""
PYSIDE-2042: Tests true_property with inheritance
"""
+is_pypy = hasattr(sys, "pypy_version_info")
from PySide6.QtCore import QSize
from PySide6.QtWidgets import QWidget, QSpinBox
-from __feature__ import true_property
+if not is_pypy:
+ from __feature__ import true_property
from helper.usesqapplication import UsesQApplication
+@unittest.skipIf(is_pypy, "__feature__ cannot yet be used with PyPy")
class TruePropertyInheritanceTest(UsesQApplication):
def testTrueProperty(self):
@@ -33,6 +36,23 @@ class TruePropertyInheritanceTest(UsesQApplication):
check = spin_box.sizeHint
self.assertEqual(type(check), QSize)
+ def testHiddenMethods(self):
+ # PYSIDE-1889: setVisible is no longer a meta function but comes from the Property
+ widget = QWidget()
+ self.assertTrue("visible" in QWidget.__dict__)
+ self.assertFalse("isVisible" in QWidget.__dict__)
+ self.assertFalse("setVisible" in QWidget.__dict__)
+ self.assertTrue(hasattr(widget, "isVisible"))
+ self.assertTrue(hasattr(widget, "setVisible"))
+ self.assertEqual(widget.isVisible, QWidget.visible.fget)
+ self.assertEqual(widget.setVisible, QWidget.visible.fset)
+
+ # This works with inheritance as well:
+ class SubClass(QWidget):
+ pass
+ sub_widget = SubClass()
+ self.assertEqual(sub_widget.isVisible, QWidget.visible.fget)
+
if __name__ == '__main__':
unittest.main()
diff --git a/sources/pyside6/tests/pysidetest/typedef_signal_test.py b/sources/pyside6/tests/pysidetest/typedef_signal_test.py
index dfe5311e8..d0bdc880b 100644
--- a/sources/pyside6/tests/pysidetest/typedef_signal_test.py
+++ b/sources/pyside6/tests/pysidetest/typedef_signal_test.py
@@ -10,7 +10,7 @@ sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
from init_paths import init_test_paths
init_test_paths(True)
-from PySide6.QtCore import QObject
+from PySide6.QtCore import QObject, Slot
from testbinding import TestObject
@@ -23,6 +23,10 @@ class Receiver(QObject):
def slot(self, value):
self.received = value
+ @Slot("IntList")
+ def containerSlot(self, value):
+ self.received = value
+
class TypedefSignal(unittest.TestCase):
@@ -34,6 +38,15 @@ class TypedefSignal(unittest.TestCase):
obj.emitSignalWithTypedefValue(2)
self.assertEqual(receiver.received.value, 2)
+ def testContainerTypedef(self):
+ obj = TestObject(0)
+ receiver = Receiver()
+
+ test_list = [1, 2]
+ obj.signalWithContainerTypedefValue.connect(receiver.containerSlot)
+ obj.emitSignalWithContainerTypedefValue(test_list)
+ self.assertEqual(receiver.received, test_list)
+
if __name__ == '__main__':
unittest.main()
diff --git a/sources/pyside6/tests/pysidetest/typesystem_pysidetest.xml b/sources/pyside6/tests/pysidetest/typesystem_pysidetest.xml
index 7f1170466..592d90a83 100644
--- a/sources/pyside6/tests/pysidetest/typesystem_pysidetest.xml
+++ b/sources/pyside6/tests/pysidetest/typesystem_pysidetest.xml
@@ -63,6 +63,8 @@
</modify-function>
</object-type>
+ <value-type name="TestQVariantEnum"/>
+
<namespace-type name="FlagsNamespace" visible="no">
<enum-type name="Option" flags="Options"/>
<object-type name="ClassForEnum" />
@@ -70,15 +72,9 @@
<object-type name="SharedPointerTestbench"/>
+ <value-type name="QVariantHolder"/>
+
<smart-pointer-type name="QSharedPointer" type="shared" getter="data"
reset-method="reset"/>
- <suppress-warning text="type 'QPyTextObject' is specified in typesystem, but not defined. This could potentially lead to compilation errors." />
- <!-- Qt5: I never really understood this warning. Probably it is because there
- is no way to instantiate the class. Anyway, why must this class emit this warning?
- I am not a C++ warrior, so I'd prefer if it would say "it is ok if you see this warning!".
- Well, maybe somebody will enlighten me, and I'll change this comment.
- I'd actually prefer an implementation that avoids generating this message, but I still failed
- doing so :-(
- -->
</typesystem>