diff options
author | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2021-11-23 13:44:23 +0100 |
---|---|---|
committer | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2021-11-25 08:55:30 +0100 |
commit | 8452e19e4b2ce7320aa72f6bc814f039c4874e34 (patch) | |
tree | 4576b342899e7e5090dc16c7c641e811458b7067 | |
parent | 875bb91cc542103d2f0ad777452d5ac8ed960471 (diff) |
shiboken6: Handle None as a shared pointer parameter
Add checks for None to the copy converters.
Task-number: PYSIDE-454
Change-Id: I03954189e26572d248e22118954115bf8281b0f9
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Christian Tismer <tismer@stackless.com>
(cherry picked from commit 6c8c0142a99aa0c170998b3449ea20e5a526d80d)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
4 files changed, 44 insertions, 8 deletions
diff --git a/sources/shiboken6/generator/shiboken/cppgenerator.cpp b/sources/shiboken6/generator/shiboken/cppgenerator.cpp index 7f8158128..31aa665ae 100644 --- a/sources/shiboken6/generator/shiboken/cppgenerator.cpp +++ b/sources/shiboken6/generator/shiboken/cppgenerator.cpp @@ -1567,18 +1567,31 @@ return result;)"; c.clear(); QString pyInVariable = QLatin1String("pyIn"); - QString wrappedCPtrExpression; - if (!classContext.forSmartPointer()) - wrappedCPtrExpression = cpythonWrapperCPtr(metaClass->typeEntry(), pyInVariable); - else - wrappedCPtrExpression = cpythonWrapperCPtr(classContext.preciseType(), pyInVariable); + const QString outPtr = u"reinterpret_cast<"_qs + typeName + u" *>(cppOut)"_qs; + if (!classContext.forSmartPointer()) { + c << '*' << outPtr << " = *" + << cpythonWrapperCPtr(metaClass->typeEntry(), pyInVariable) << ';'; + } else { + auto *ste = static_cast<const SmartPointerTypeEntry *>(metaClass->typeEntry()); + const QString resetMethod = ste->resetMethod(); + c << "auto *ptr = " << outPtr << ";\n"; + c << "if (" << pyInVariable << " == Py_None)\n" << indent; + if (resetMethod.isEmpty()) + c << "*ptr = {};\n"; + else + c << "ptr->" << resetMethod << "();\n"; + c << outdent << "else\n" << indent + << "*ptr = *" + << cpythonWrapperCPtr(classContext.preciseType(), pyInVariable) << ';'; + } - c << "*reinterpret_cast<" << typeName << " *>(cppOut) = *" - << wrappedCPtrExpression << ';'; writePythonToCppFunction(s, c.toString(), sourceTypeName, targetTypeName); // "Is convertible" function for the Python object to C++ value copy conversion. - writeIsPythonConvertibleToCppFunction(s, sourceTypeName, targetTypeName, pyTypeCheck); + QString copyTypeCheck = pyTypeCheck; + if (classContext.forSmartPointer()) + copyTypeCheck.prepend(pyInVariable + u" == Py_None || "_qs); + writeIsPythonConvertibleToCppFunction(s, sourceTypeName, targetTypeName, copyTypeCheck); s << '\n'; // User provided implicit conversions. diff --git a/sources/shiboken6/tests/libsmart/smart.cpp b/sources/shiboken6/tests/libsmart/smart.cpp index f5d318e59..f33d2f835 100644 --- a/sources/shiboken6/tests/libsmart/smart.cpp +++ b/sources/shiboken6/tests/libsmart/smart.cpp @@ -133,6 +133,20 @@ int Obj::takeSharedPtrToObj(SharedPtr<Obj> pObj) int Obj::takeSharedPtrToInteger(SharedPtr<Integer> pInt) { + if (pInt.isNull()) { + std::cout << "SharedPtr<Integer>(nullptr) passed!\n"; + return -1; + } + pInt->printInteger(); + return pInt->value(); +} + +int Obj::takeSharedPtrToIntegerByConstRef(const SharedPtr<Integer> &pInt) +{ + if (pInt.isNull()) { + std::cout << "SharedPtr<Integer>(nullptr) passed!\n"; + return -1; + } pInt->printInteger(); return pInt->value(); } diff --git a/sources/shiboken6/tests/libsmart/smart_obj.h b/sources/shiboken6/tests/libsmart/smart_obj.h index 579f3db4a..58611815c 100644 --- a/sources/shiboken6/tests/libsmart/smart_obj.h +++ b/sources/shiboken6/tests/libsmart/smart_obj.h @@ -54,6 +54,7 @@ public: SharedPtr<Smart::Integer2> giveSharedPtrToInteger2(); int takeSharedPtrToObj(SharedPtr<Obj> pObj); int takeSharedPtrToInteger(SharedPtr<Integer> pInt); + int takeSharedPtrToIntegerByConstRef(const SharedPtr<Integer> &pInt); static SharedPtr<Integer> createSharedPtrToInteger(int value); static SharedPtr<Integer> createNullSharedPtrToInteger(); diff --git a/sources/shiboken6/tests/smartbinding/smart_pointer_test.py b/sources/shiboken6/tests/smartbinding/smart_pointer_test.py index a9ea91be6..484248ee6 100644 --- a/sources/shiboken6/tests/smartbinding/smart_pointer_test.py +++ b/sources/shiboken6/tests/smartbinding/smart_pointer_test.py @@ -245,6 +245,14 @@ class SmartPointerTests(unittest.TestCase): zero = Obj.createSharedPtrToInteger(0) self.assertTrue(zero) + def testParameterNone(self): + o = Obj() + null_ptr = Obj.createNullSharedPtrToInteger() + o.takeSharedPtrToInteger(null_ptr) + o.takeSharedPtrToIntegerByConstRef(null_ptr) + o.takeSharedPtrToInteger(None) + o.takeSharedPtrToIntegerByConstRef(None) + if __name__ == '__main__': unittest.main() |