diff options
Diffstat (limited to 'sources/shiboken6/tests/smartbinding')
9 files changed, 725 insertions, 0 deletions
diff --git a/sources/shiboken6/tests/smartbinding/CMakeLists.txt b/sources/shiboken6/tests/smartbinding/CMakeLists.txt new file mode 100644 index 000000000..594744840 --- /dev/null +++ b/sources/shiboken6/tests/smartbinding/CMakeLists.txt @@ -0,0 +1,65 @@ +# Copyright (C) 2023 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +project(smart) + +set(smart_TYPESYSTEM +${CMAKE_CURRENT_SOURCE_DIR}/typesystem_smart.xml +) + +set(smart_SRC +${CMAKE_CURRENT_BINARY_DIR}/smart/smart_module_wrapper.cpp +${CMAKE_CURRENT_BINARY_DIR}/smart/obj_wrapper.cpp +${CMAKE_CURRENT_BINARY_DIR}/smart/integer_wrapper.cpp +${CMAKE_CURRENT_BINARY_DIR}/smart/sharedptr_obj_wrapper.cpp +${CMAKE_CURRENT_BINARY_DIR}/smart/sharedptr_integer_wrapper.cpp +${CMAKE_CURRENT_BINARY_DIR}/smart/registry_wrapper.cpp +${CMAKE_CURRENT_BINARY_DIR}/smart/smart_integer2_wrapper.cpp +${CMAKE_CURRENT_BINARY_DIR}/smart/sharedptr_integer2_wrapper.cpp +${CMAKE_CURRENT_BINARY_DIR}/smart/stdsharedptrtestbench_wrapper.cpp +${CMAKE_CURRENT_BINARY_DIR}/smart/stdsharedptrvirtualmethodtester_wrapper.cpp +${CMAKE_CURRENT_BINARY_DIR}/smart/std_shared_ptr_double_wrapper.cpp +${CMAKE_CURRENT_BINARY_DIR}/smart/std_shared_ptr_integer_wrapper.cpp +${CMAKE_CURRENT_BINARY_DIR}/smart/std_shared_ptr_int_wrapper.cpp +${CMAKE_CURRENT_BINARY_DIR}/smart/std_shared_ptr_std_string_wrapper.cpp +${CMAKE_CURRENT_BINARY_DIR}/smart/std_wrapper.cpp +${CMAKE_CURRENT_BINARY_DIR}/smart/std_optional_int_wrapper.cpp +${CMAKE_CURRENT_BINARY_DIR}/smart/std_optional_integer_wrapper.cpp +${CMAKE_CURRENT_BINARY_DIR}/smart/std_unique_ptr_integer_wrapper.cpp +${CMAKE_CURRENT_BINARY_DIR}/smart/std_unique_ptr_integer2_wrapper.cpp +${CMAKE_CURRENT_BINARY_DIR}/smart/std_unique_ptr_int_wrapper.cpp +${CMAKE_CURRENT_BINARY_DIR}/smart/stdoptionaltestbench_wrapper.cpp +${CMAKE_CURRENT_BINARY_DIR}/smart/stduniqueptrtestbench_wrapper.cpp +${CMAKE_CURRENT_BINARY_DIR}/smart/stduniqueptrvirtualmethodtester_wrapper.cpp +${CMAKE_CURRENT_BINARY_DIR}/smart/test_wrapper.cpp +) + +configure_file("${CMAKE_CURRENT_SOURCE_DIR}/smart-binding.txt.in" + "${CMAKE_CURRENT_BINARY_DIR}/smart-binding.txt" @ONLY) + +shiboken_get_tool_shell_wrapper(shiboken tool_wrapper) + +add_custom_command( + OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/mjb_rejected_classes.log" + BYPRODUCTS ${smart_SRC} + COMMAND + ${tool_wrapper} + $<TARGET_FILE:Shiboken6::shiboken6> + --project-file=${CMAKE_CURRENT_BINARY_DIR}/smart-binding.txt + ${GENERATOR_EXTRA_FLAGS} + DEPENDS ${smart_TYPESYSTEM} ${CMAKE_CURRENT_SOURCE_DIR}/global.h Shiboken6::shiboken6 + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + COMMENT "Running generator for 'smart' test binding..." +) + +add_library(smart MODULE ${smart_SRC}) +target_include_directories(smart PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) +target_link_libraries(smart PUBLIC libsmart libshiboken) +set_property(TARGET smart PROPERTY PREFIX "") +set_property(TARGET smart PROPERTY OUTPUT_NAME "smart${PYTHON_EXTENSION_SUFFIX}") + +if(WIN32) + set_property(TARGET smart PROPERTY SUFFIX ".pyd") +endif() + +create_generator_target(smart) diff --git a/sources/shiboken6/tests/smartbinding/global.h b/sources/shiboken6/tests/smartbinding/global.h new file mode 100644 index 000000000..5bec15063 --- /dev/null +++ b/sources/shiboken6/tests/smartbinding/global.h @@ -0,0 +1,4 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include "smart.h" diff --git a/sources/shiboken6/tests/smartbinding/smart-binding.txt.in b/sources/shiboken6/tests/smartbinding/smart-binding.txt.in new file mode 100644 index 000000000..a2c73c6bf --- /dev/null +++ b/sources/shiboken6/tests/smartbinding/smart-binding.txt.in @@ -0,0 +1,16 @@ +[generator-project] + +generator-set = shiboken + +header-file = @CMAKE_CURRENT_SOURCE_DIR@/global.h +typesystem-file = @smart_TYPESYSTEM@ + +output-directory = @CMAKE_CURRENT_BINARY_DIR@ + +include-path = @libsmart_SOURCE_DIR@ + +typesystem-path = @CMAKE_CURRENT_SOURCE_DIR@ + +enable-parent-ctor-heuristic +use-isnull-as-nb_nonzero +lean-headers diff --git a/sources/shiboken6/tests/smartbinding/smart_pointer_test.py b/sources/shiboken6/tests/smartbinding/smart_pointer_test.py new file mode 100644 index 000000000..8d4272558 --- /dev/null +++ b/sources/shiboken6/tests/smartbinding/smart_pointer_test.py @@ -0,0 +1,302 @@ +#!/usr/bin/env python +# 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 gc +import os +import sys +import unittest + +from pathlib import Path +sys.path.append(os.fspath(Path(__file__).resolve().parents[1])) +from shiboken_paths import init_paths +init_paths() +from copy import copy +from smart import (Obj, Registry, Integer, SharedPtr_Integer, std) + + +def objCount(): + return Registry.getInstance().countObjects() + + +def integerCount(): + return Registry.getInstance().countIntegers() + + +def integerFromValue(v): + result = Integer() + result.setValue(v) + return result + + +class SmartPointerTests(unittest.TestCase): + + def setUp(self): + super().setUp() + if os.environ.get("VERBOSE"): + Registry.getInstance().setVerbose(True) + + def testObjSmartPointer(self): + # Create Obj. + o = Obj() + # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion + gc.collect() + self.assertEqual(objCount(), 1) + + # Create a shared pointer to an Obj together with an Obj. + ptrToObj = o.createSharedPtrObj() + self.assertEqual(objCount(), 2) + + # Delete the old Obj. + o = None + # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion + gc.collect() + self.assertEqual(objCount(), 1) + + # Get a wrapper to the Obj inside of the shared pointer, object count + # should not change. + obj = ptrToObj.data() + self.assertEqual(objCount(), 1) + obj.m_integer = 50 + self.assertEqual(obj.m_integer, 50) + + # Set and get a member value via shared pointer (like operator->). + ptrToObj.m_integer = 100 + self.assertEqual(ptrToObj.m_integer, 100) + + # Get inner PyObject via shared pointer (like operator->) and set + # value in it. + ptrToObj.m_internalInteger.m_int = 200 + self.assertEqual(ptrToObj.m_internalInteger.m_int, 200) + + # Pass smart pointer as argument to a method, return value is the value + # of m_integer of passed Obj inside the smart pointer. + result = ptrToObj.takeSharedPtrToObj(ptrToObj) + self.assertEqual(result, 100) + + # Pass an Integer as an argument that returns itself. + result = ptrToObj.takeInteger(ptrToObj.m_internalInteger) + self.assertEqual(integerCount(), 2) + result = None + if integerCount() > 1: + gc.collect() + print('Running garbage collector for reference test', + file=sys.stderr) + self.assertEqual(integerCount(), 1) + + # Make a copy of the shared pointer, object count should not change. + ptrToObj2 = copy(ptrToObj) + self.assertEqual(objCount(), 1) + + # Delete the first shared pointer, object count should not change + # because the second one still has a reference. + del ptrToObj + # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion + gc.collect() + self.assertEqual(objCount(), 1) + + # Delete the second smart pointer, object should be deleted. + del ptrToObj2 + # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion + gc.collect() + self.assertEqual(objCount(), 0) + self.assertEqual(integerCount(), 0) + + def testIntegerSmartPointer(self): + # Create Obj. + o = Obj() + # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion + gc.collect() + self.assertEqual(objCount(), 1) + + # Create a shared pointer to an Integer together with an Integer. + ptrToInteger = o.createSharedPtrInteger() + self.assertEqual(objCount(), 1) + self.assertEqual(integerCount(), 2) + + # Get a wrapper to the Integer inside of the shared pointer, integer + # count should not change. + integer = ptrToInteger.data() + self.assertEqual(integerCount(), 2) + integer.m_int = 50 + self.assertEqual(integer.m_int, 50) + + # Set and get a member value via shared pointer (like operator->). + ptrToInteger.setValue(150) + self.assertEqual(ptrToInteger.value(), 150) + + # Set and get a member field via shared pointer (like operator->). + ptrToInteger.m_int = 100 + self.assertEqual(ptrToInteger.m_int, 100) + + # Pass smart pointer as argument to a method, return value is the + # value of m_int of passed Integer inside the smart pointer. + result = o.takeSharedPtrToInteger(ptrToInteger) + self.assertEqual(result, 100) + + # Make a copy of the shared pointer, integer count should not change. + ptrToInteger2 = copy(ptrToInteger) + self.assertEqual(integerCount(), 2) + + # Delete the first shared pointer, integer count should not change + # because the second one still has a reference. + del ptrToInteger + # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion + gc.collect() + self.assertEqual(integerCount(), 2) + + # Delete the second smart pointer, integer should be deleted. + del ptrToInteger2 + # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion + gc.collect() + self.assertEqual(objCount(), 1) + self.assertEqual(integerCount(), 1) + + # Delete the original object which was used to create the integer. + del o + # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion + gc.collect() + self.assertEqual(objCount(), 0) + self.assertEqual(integerCount(), 0) + + def testConstIntegerSmartPointer(self): + # Create Obj. + o = Obj() + ptrToConstInteger = o.createSharedPtrConstInteger() + self.assertEqual(ptrToConstInteger.m_int, 456) + result = o.takeSharedPtrToConstInteger(ptrToConstInteger) + self.assertEqual(result, 456) + self.assertEqual(ptrToConstInteger.value(), 456) + + def testSmartPointersWithNamespace(self): + # Create the main object + o = Obj() + # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion + gc.collect() + self.assertEqual(objCount(), 1) + + # Create a shared pointer to an Integer together with an Integer. + ptrToInteger = o.createSharedPtrInteger2() + self.assertEqual(objCount(), 1) + self.assertEqual(integerCount(), 2) + + integer = ptrToInteger.data() + self.assertTrue(integer) + + def testListOfSmartPointers(self): + # Create the main object + o = Obj() + + # Create a list of shared objects + ptrToObjList = o.createSharedPtrObjList(10) + self.assertEqual(len(ptrToObjList), 10) + # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion + gc.collect() + self.assertEqual(objCount(), 11) + + # Remove one from the list + ptrToObjList.pop() + self.assertEqual(len(ptrToObjList), 9) + # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion + gc.collect() + # PYSIDE-535: Why do I need to do it twice, here? + gc.collect() + self.assertEqual(objCount(), 10) + + # clear and delete all objects in the list + del ptrToObjList[:] # Python 2.7 lists have no clear method + # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion + gc.collect() + self.assertEqual(len(ptrToObjList), 0) + self.assertEqual(objCount(), 1) + + def testInvalidParameter(self): + # Create Obj. + o = Obj() + # Create a shared pointer to an Obj together with an Obj. + ptrToObj = o.createSharedPtrObj() + try: + ptrToObj.typo + self.assertFail() + except AttributeError as error: + self.assertEqual(error.args[0], "'smart.SharedPtr_Obj' object has no attribute 'typo'") + + def testSmartPointerConversions(self): + # Create Obj. + o = Obj() + # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion + gc.collect() + self.assertEqual(objCount(), 1) + self.assertEqual(integerCount(), 1) + + # Create a shared pointer to an Integer2 + integer2 = o.createSharedPtrInteger2() + # User defined name + self.assertEqual(type(integer2).__name__, "SmartInteger2Ptr") + self.assertTrue("smart.Test.SmartInteger2Ptr" in repr(type(integer2))) + self.assertEqual(integer2.value(), 456) + + # pass Smart<Integer2> to a function that accepts Smart<Integer> + r = o.takeSharedPtrToInteger(integer2) + self.assertEqual(r, integer2.value()) + + def testSmartPointerValueComparison(self): + """Test a pointee class with comparison operators.""" + four = Obj.createSharedPtrInteger(4) + four2 = Obj.createSharedPtrInteger(4) + five = Obj.createSharedPtrInteger(5) + self.assertTrue(four == four) + self.assertTrue(four == four2) + self.assertFalse(four != four) + self.assertFalse(four != four2) + self.assertFalse(four < four) + self.assertTrue(four <= four) + self.assertFalse(four > four) + self.assertTrue(four >= four) + self.assertFalse(four == five) + self.assertTrue(four != five) + self.assertTrue(four < five) + self.assertTrue(four <= five) + self.assertFalse(four > five) + self.assertFalse(four >= five) + self.assertTrue(five > four) + + self.assertRaises(NotImplementedError, + lambda: Obj.createNullSharedPtrInteger() == four) + + def testSmartPointerObjectComparison(self): + """Test a pointee class without comparison operators.""" + o1 = Obj.createSharedPtrObj() + o2 = Obj.createSharedPtrObj() + self.assertTrue(o1 == o1) + self.assertFalse(o1 != o1) + self.assertFalse(o1 == o2) + self.assertTrue(o1 != o2) + + def testOperatorNbBool(self): + null_ptr = Obj.createNullSharedPtrInteger() + self.assertFalse(null_ptr) + zero = Obj.createSharedPtrInteger(0) + self.assertTrue(zero) + + def testParameterNone(self): + o = Obj() + null_ptr = Obj.createNullSharedPtrInteger() + o.takeSharedPtrToInteger(null_ptr) + o.takeSharedPtrToIntegerByConstRef(null_ptr) + o.takeSharedPtrToInteger(None) + o.takeSharedPtrToIntegerByConstRef(None) + + def testConstruction(self): + p1 = SharedPtr_Integer(integerFromValue(42)) + self.assertEqual(p1.value(), 42) + + p2 = std.shared_ptr_Integer(integerFromValue(42)) + self.assertEqual(p2.value(), 42) + p2.reset(integerFromValue(43)) + self.assertEqual(p2.value(), 43) + gc.collect() + + +if __name__ == '__main__': + unittest.main() diff --git a/sources/shiboken6/tests/smartbinding/smartbinding.pyproject b/sources/shiboken6/tests/smartbinding/smartbinding.pyproject new file mode 100644 index 000000000..d0855ef82 --- /dev/null +++ b/sources/shiboken6/tests/smartbinding/smartbinding.pyproject @@ -0,0 +1,7 @@ +{ + "files": ["smart_pointer_test.py", + "std_optional_test.py", + "std_shared_ptr_test.py", + "std_unique_ptr_test.py", + "typesystem_smart.xml"] +} diff --git a/sources/shiboken6/tests/smartbinding/std_optional_test.py b/sources/shiboken6/tests/smartbinding/std_optional_test.py new file mode 100644 index 000000000..bee573548 --- /dev/null +++ b/sources/shiboken6/tests/smartbinding/std_optional_test.py @@ -0,0 +1,69 @@ +#!/usr/bin/env python +# 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 os +import sys +import unittest + +from pathlib import Path +sys.path.append(os.fspath(Path(__file__).resolve().parents[1])) +from shiboken_paths import init_paths +init_paths() +from smart import Integer, StdOptionalTestBench, std + + +def call_func_on_optional(o): + o.printInteger() + + +def integer_from_value(v): + result = Integer() + result.setValue(v) + return result + + +class StdOptionalTests(unittest.TestCase): + + def testCInt(self): + b = StdOptionalTestBench() + ci = b.optionalInt() + self.assertFalse(ci.has_value()) + b.setOptionalIntValue(42) + ci = b.optionalInt() + self.assertTrue(ci.has_value()) + self.assertEqual(ci.value(), 42) + b.setOptionalInt(ci) + ci = b.optionalInt() + self.assertTrue(ci.has_value()) + self.assertEqual(ci.value(), 42) + + ci = std.optional_int(43) + self.assertEqual(ci.value(), 43) + + def testInteger(self): + b = StdOptionalTestBench() + i = b.optionalInteger() + self.assertFalse(i.has_value()) + self.assertFalse(i) + # Must not throw a C++ exception + self.assertRaises(AttributeError, call_func_on_optional, i) + + b.setOptionalIntegerValue(integer_from_value(42)) + i = b.optionalInteger() + self.assertTrue(i.has_value()) + self.assertEqual(i.value().value(), 42) + i.printInteger() + print(i) + b.setOptionalInteger(i) + i = b.optionalInteger() + self.assertTrue(i.has_value()) + self.assertEqual(i.value().value(), 42) + call_func_on_optional(i) + + i = std.optional_Integer(integer_from_value(43)) + self.assertEqual(i.value().value(), 43) + + +if __name__ == '__main__': + unittest.main() diff --git a/sources/shiboken6/tests/smartbinding/std_shared_ptr_test.py b/sources/shiboken6/tests/smartbinding/std_shared_ptr_test.py new file mode 100644 index 000000000..a37a307a5 --- /dev/null +++ b/sources/shiboken6/tests/smartbinding/std_shared_ptr_test.py @@ -0,0 +1,87 @@ +#!/usr/bin/env python +# 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 os +import sys +import unittest + +from pathlib import Path +sys.path.append(os.fspath(Path(__file__).resolve().parents[1])) +from shiboken_paths import init_paths +init_paths() +from smart import Integer, StdDoublePtr, StdSharedPtrTestBench, StdSharedPtrVirtualMethodTester, std + + +def call_func_on_ptr(ptr): + ptr.printInteger() + + +class VirtualTester(StdSharedPtrVirtualMethodTester): + + def doModifyInteger(self, p): + p.setValue(p.value() * 2) + return p + + +class StdSharedPtrTests(unittest.TestCase): + def testInteger(self): + p = StdSharedPtrTestBench.createInteger() + # PYSIDE-2462: Ensure Integer's __dir__ entries in the pointer's + self.assertTrue("printInteger" in dir(p)) + StdSharedPtrTestBench.printInteger(p) + self.assertTrue(p) + call_func_on_ptr(p) + + np = StdSharedPtrTestBench.createNullInteger() + StdSharedPtrTestBench.printInteger(np) + self.assertFalse(np) + self.assertRaises(AttributeError, call_func_on_ptr, np) + + iv = Integer() + iv.setValue(42) + np = std.shared_ptr_Integer(iv) + self.assertEqual(np.value(), 42) + + def testInt(self): + np = StdSharedPtrTestBench.createNullInt() + StdSharedPtrTestBench.printInt(np) + self.assertFalse(np) + p = StdSharedPtrTestBench.createInt() + StdSharedPtrTestBench.printInt(p) + ip = std.StdIntPtr(42) + StdSharedPtrTestBench.printInt(ip) + + def testDouble(self): + np = StdSharedPtrTestBench.createNullDouble() + StdSharedPtrTestBench.printDouble(np) + self.assertFalse(np) + p = StdSharedPtrTestBench.createDouble(67) + StdSharedPtrTestBench.printDouble(p) + dp = StdDoublePtr(42) + StdSharedPtrTestBench.printDouble(dp) + + def testString(self): + np = StdSharedPtrTestBench.createNullString() + StdSharedPtrTestBench.printString(np) + self.assertFalse(np) + p = StdSharedPtrTestBench.createString("bla") + StdSharedPtrTestBench.printString(p) + + def testVirtuals(self): + """Test whether code generating virtual function overrides is generated + correctly.""" + p = StdSharedPtrTestBench.createInteger() + p.setValue(42) + v = StdSharedPtrVirtualMethodTester() + r = v.callModifyInteger(p) # Base implementation increments + self.assertEqual(r.value(), 43) + + p.setValue(42) + v = VirtualTester() + r = v.callModifyInteger(p) # Derived implementation doubles + self.assertEqual(r.value(), 84) + + +if __name__ == '__main__': + unittest.main() diff --git a/sources/shiboken6/tests/smartbinding/std_unique_ptr_test.py b/sources/shiboken6/tests/smartbinding/std_unique_ptr_test.py new file mode 100644 index 000000000..9c7ef2f01 --- /dev/null +++ b/sources/shiboken6/tests/smartbinding/std_unique_ptr_test.py @@ -0,0 +1,94 @@ +#!/usr/bin/env python +# 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 os +import sys +import unittest + +from pathlib import Path +sys.path.append(os.fspath(Path(__file__).resolve().parents[1])) +from shiboken_paths import init_paths +init_paths() +from smart import Integer, Integer2, StdUniquePtrTestBench, StdUniquePtrVirtualMethodTester, std + + +def call_func_on_ptr(ptr): + ptr.printInteger() + + +class VirtualTester(StdUniquePtrVirtualMethodTester): + + def doCreateInteger(self, v): + iv = Integer() # Construct from pointee + iv.setValue(2 * v) + return std.unique_ptr_Integer(iv) + + def doModifyIntegerByRef(self, p): + return 2 * p.value() + + def doModifyIntegerByValue(self, p): + return 2 * p.value() + + +class StdUniquePtrTests(unittest.TestCase): + def testInteger(self): + p = StdUniquePtrTestBench.createInteger() + StdUniquePtrTestBench.printInteger(p) # unique_ptr by ref + self.assertTrue(p) + + call_func_on_ptr(p) + self.assertTrue(p) + + StdUniquePtrTestBench.takeInteger(p) # unique_ptr by value, takes pointee + self.assertFalse(p) + + np = StdUniquePtrTestBench.createNullInteger() + StdUniquePtrTestBench.printInteger(np) + self.assertFalse(np) + self.assertRaises(AttributeError, call_func_on_ptr, np) + + iv = Integer() # Construct from pointee + iv.setValue(42) + np = std.unique_ptr_Integer(iv) + self.assertEqual(np.value(), 42) + + def test_derived(self): + iv2 = Integer2() # Construct from pointee + iv2.setValue(42) + p = std.unique_ptr_Smart_Integer2(iv2) + self.assertEqual(p.value(), 42) + StdUniquePtrTestBench.printInteger2(p) # unique_ptr by ref + self.assertTrue(p) + StdUniquePtrTestBench.printInteger(p) # conversion + # FIXME: This fails, pointer is moved in value conversion + # self.assertTrue(p) + + def testInt(self): + p = StdUniquePtrTestBench.createInt() # unique_ptr by ref + StdUniquePtrTestBench.printInt(p) + StdUniquePtrTestBench.takeInt(p) # unique_ptr by value, takes pointee + self.assertFalse(p) + + np = StdUniquePtrTestBench.createNullInt() + StdUniquePtrTestBench.printInt(np) + self.assertFalse(np) + + def testVirtuals(self): + """Test whether code generating virtual function overrides is generated + correctly.""" + p = StdUniquePtrTestBench.createInteger() + p.setValue(42) + v = StdUniquePtrVirtualMethodTester() + self.assertTrue(v.testCreateInteger(42, 42)) + self.assertTrue(v.testModifyIntegerByRef(42, 43)) # Default implementation increments + self.assertTrue(v.testModifyIntegerValue(42, 43)) + + v = VirtualTester() # Reimplemented methods double values + self.assertTrue(v.testCreateInteger(42, 84)) + self.assertTrue(v.testModifyIntegerByRef(42, 84)) + self.assertTrue(v.testModifyIntegerValue(42, 84)) + + +if __name__ == '__main__': + unittest.main() diff --git a/sources/shiboken6/tests/smartbinding/typesystem_smart.xml b/sources/shiboken6/tests/smartbinding/typesystem_smart.xml new file mode 100644 index 000000000..e479e4ddf --- /dev/null +++ b/sources/shiboken6/tests/smartbinding/typesystem_smart.xml @@ -0,0 +1,81 @@ +<?xml version="1.0" encoding="UTF-8"?> +<typesystem package="smart"> + <rejection class="*" argument-type="^std::nullptr_t&?$"/> + + <template name="cpplist_to_pylist_convertion"> + PyObject *%out = PyList_New(int(%in.size())); + int idx = 0; + for (const auto &cppItem : %in) + PyList_SET_ITEM(%out, idx++, %CONVERTTOPYTHON[%INTYPE_0](cppItem)); + return %out; + </template> + <template name="pyseq_to_cpplist_convertion"> + Shiboken::AutoDecRef seq(PySequence_Fast(%in, 0)); + for (int i = 0, size = PySequence_Fast_GET_SIZE(seq.object()); i < size; ++i) { + PyObject* pyItem = PySequence_Fast_GET_ITEM(seq.object(), i); + %OUTTYPE_0 cppItem = %CONVERTTOCPP[%OUTTYPE_0](pyItem); + %out.push_back(cppItem); + } + </template> + + <!-- Used in tests to check what C++ objects are allocated. --> + <object-type name="Registry" /> + + <!-- Current limitation: shared pointer python objects can only be instantiated from API usage, + like when they are returned as a result of a method, or passed as arguments. It is not + possible to explicitly instantiate a new shared pointer in python e.g. o = SharedPtr_Foo() + won't work. + --> + <smart-pointer-type name="SharedPtr" type="shared" getter="data" ref-count-method="useCount" + null-check-method="isNull" + instantiations="Integer,Smart::Integer2=Test::SmartInteger2Ptr,Obj"/> + + <object-type name="Obj" /> + <value-type name="Integer" /> + <namespace-type name="Smart" generate="no"> + <value-type name="Integer2" /> + </namespace-type> + <!-- Just used to silence the warnings that shiboken doens't know what to do with this type --> + <custom-type name="RefData" /> + + <value-type name="StdOptionalTestBench"/> + + <system-include file-name="memory"/> + + <namespace-type name="std"> + <include file-name="memory" location="global"/> + <modify-function signature="^.*$" remove="all"/> + <enum-type name="pointer_safety"/> + <smart-pointer-type name="shared_ptr" type="shared" getter="get" + value-check-method="operator bool" + ref-count-method="use_count" + reset-method="reset" + instantiations="Integer,int=StdIntPtr,double=::StdDoublePtr,std::string"> + <include file-name="memory" location="global"/> + </smart-pointer-type> + + <smart-pointer-type name="unique_ptr" type="unique" getter="get" + value-check-method="operator bool" + reset-method="reset" + instantiations="Integer,Smart::Integer2,int"> + <include file-name="memory" location="global"/> + </smart-pointer-type> + + <smart-pointer-type name="optional" type="value-handle" getter="value" + value-check-method="has_value" + instantiations="Integer,int"> + <include file-name="optional" location="global"/> + </smart-pointer-type> + + </namespace-type> + <object-type name="StdSharedPtrTestBench"/> + <object-type name="StdSharedPtrVirtualMethodTester"/> + + <object-type name="StdUniquePtrTestBench"/> + <object-type name="StdUniquePtrVirtualMethodTester"/> + + <namespace-type name="Test"> + <enum-type name="DummyEnum"/> + </namespace-type> + +</typesystem> |