aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@qt.io>2021-11-23 13:44:23 +0100
committerFriedemann Kleint <Friedemann.Kleint@qt.io>2021-11-25 08:55:30 +0100
commit8452e19e4b2ce7320aa72f6bc814f039c4874e34 (patch)
tree4576b342899e7e5090dc16c7c641e811458b7067
parent875bb91cc542103d2f0ad777452d5ac8ed960471 (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>
-rw-r--r--sources/shiboken6/generator/shiboken/cppgenerator.cpp29
-rw-r--r--sources/shiboken6/tests/libsmart/smart.cpp14
-rw-r--r--sources/shiboken6/tests/libsmart/smart_obj.h1
-rw-r--r--sources/shiboken6/tests/smartbinding/smart_pointer_test.py8
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()