diff options
author | Friedemann Kleint <[email protected]> | 2025-05-26 15:49:20 +0200 |
---|---|---|
committer | Friedemann Kleint <[email protected]> | 2025-06-06 15:54:28 +0200 |
commit | 2365c9bec8d03fe00b9153848adc6a474c3ff945 (patch) | |
tree | 0e895850e1d18c9d24d9135dfc94acaa7a12c34f | |
parent | 8d335e046e9ac16737cdf28bde197d6684002205 (diff) |
shiboken6: Generalize the target-to-native container conversion for smart pointers
- Introduce a helper processTypeCheckCodeSnip()
- Observe the "check" attribute which was previously ignored
- Replace variable %OUTTYPE_[n] in the type check, too
Task-number: PYSIDE-3107
Change-Id: I6b96529831d63c5423d218166932ee7d9ba69405
Reviewed-by: Cristian Maureira-Fredes <[email protected]>
4 files changed, 33 insertions, 17 deletions
diff --git a/sources/shiboken6/generator/shiboken/cppgenerator.cpp b/sources/shiboken6/generator/shiboken/cppgenerator.cpp index f392eef38..29603bd97 100644 --- a/sources/shiboken6/generator/shiboken/cppgenerator.cpp +++ b/sources/shiboken6/generator/shiboken/cppgenerator.cpp @@ -3606,8 +3606,7 @@ void CppGenerator::writePythonToCppConversionFunctions(TextStream &s, typeCheck = u"PyObject_TypeCheck(%in, "_s + cpythonTypeNameExt(toNative.sourceType()) + u')'; } - typeCheck.replace(u"%in"_s, u"pyIn"_s); - processCodeSnip(typeCheck, targetType->qualifiedCppName()); + processTypeCheckCodeSnip(typeCheck, targetType->qualifiedCppName()); writeIsPythonConvertibleToCppFunction(s, sourceTypeName, targetTypeName, typeCheck); } @@ -3623,18 +3622,31 @@ void CppGenerator::writePythonToCppConversionFunctions(TextStream &s, } void CppGenerator::writePythonToCppConversionFunction(TextStream &s, - const AbstractMetaType &containerType, + const AbstractMetaType &templateType, const TargetToNativeConversion &conv) const { + // Python to C++ convertible check function. + QString typeName = fixedCppTypeName(templateType); + // Check fallback is too broad for containers that need elements of same type + QString typeCheck = templateType.isContainer() + ? conv.sourceTypeCheck() : conv.sourceTypeCheckFallback(); + if (typeCheck.isEmpty()) { + typeCheck = cpythonCheckFunction(templateType); + if (typeCheck.isEmpty()) + typeCheck = u"false"_s; + else + typeCheck = typeCheck + u"pyIn)"_s; + } + // Python to C++ conversion function. - QString cppTypeName = getFullTypeNameWithoutModifiers(containerType); + QString cppTypeName = getFullTypeNameWithoutModifiers(templateType); QString code = conv.conversion(); const QString line = u"auto &cppOutRef = *reinterpret_cast<"_s + cppTypeName + u" *>(cppOut);"_s; CodeSnipAbstract::prependCode(&code, line); - for (qsizetype i = 0; i < containerType.instantiations().size(); ++i) { - const AbstractMetaType &type = containerType.instantiations().at(i); - QString typeName = getFullTypeName(type); + for (qsizetype i = 0; i < templateType.instantiations().size(); ++i) { + const AbstractMetaType &type = templateType.instantiations().at(i); + QString instTypeName = getFullTypeName(type); // Containers of opaque containers are not handled here. const auto generatorArg = GeneratorArgument::fromMetaType(type); if (generatorArg.indirections > 0 && !type.generateOpaqueContainer()) { @@ -3648,23 +3660,19 @@ void CppGenerator::writePythonToCppConversionFunction(TextStream &s, rightCode.replace(varName, u'*' + varName); code.replace(pos, code.size() - pos, rightCode); } - typeName.append(u" *"_s); + instTypeName.append(" *"_L1); } - code.replace(u"%OUTTYPE_"_s + QString::number(i), typeName); + const QString var = "%OUTTYPE_"_L1 + QString::number(i); + code.replace(var, instTypeName); + typeCheck.replace(var, instTypeName); } code.replace(u"%OUTTYPE"_s, cppTypeName); code.replace(u"%in"_s, u"pyIn"_s); code.replace(u"%out"_s, u"cppOutRef"_s); - QString typeName = fixedCppTypeName(containerType); const QString &sourceTypeName = conv.sourceTypeName(); writePythonToCppFunction(s, code, sourceTypeName, typeName); - // Python to C++ convertible check function. - QString typeCheck = cpythonCheckFunction(containerType); - if (typeCheck.isEmpty()) - typeCheck = u"false"_s; - else - typeCheck = typeCheck + u"pyIn)"_s; + processTypeCheckCodeSnip(typeCheck, typeName); // needs %OUTTYPE_[n] writeIsPythonConvertibleToCppFunction(s, sourceTypeName, typeName, typeCheck); s << '\n'; } diff --git a/sources/shiboken6/generator/shiboken/cppgenerator.h b/sources/shiboken6/generator/shiboken/cppgenerator.h index 441a9f781..1a192f8fd 100644 --- a/sources/shiboken6/generator/shiboken/cppgenerator.h +++ b/sources/shiboken6/generator/shiboken/cppgenerator.h @@ -370,7 +370,7 @@ private: const AbstractMetaType &templateType) const; void writePythonToCppConversionFunction(TextStream &s, - const AbstractMetaType &containerType, + const AbstractMetaType &templateType, const TargetToNativeConversion &conv) const; static void writeAddPythonToCppConversion(TextStream &s, const QString &converterVar, diff --git a/sources/shiboken6/generator/shiboken/shibokengenerator.cpp b/sources/shiboken6/generator/shiboken/shibokengenerator.cpp index 5c67f20f0..872076754 100644 --- a/sources/shiboken6/generator/shiboken/shibokengenerator.cpp +++ b/sources/shiboken6/generator/shiboken/shibokengenerator.cpp @@ -1387,6 +1387,12 @@ void ShibokenGenerator::processClassCodeSnip(QString &code, const GeneratorConte processCodeSnip(code, context.effectiveClassName()); } +void ShibokenGenerator::processTypeCheckCodeSnip(QString &code, const QString &context) const +{ + code.replace("%in"_L1, "pyIn"_L1); + processCodeSnip(code, context); +} + void ShibokenGenerator::processCodeSnip(QString &code) const { // replace "toPython" converters diff --git a/sources/shiboken6/generator/shiboken/shibokengenerator.h b/sources/shiboken6/generator/shiboken/shibokengenerator.h index 045581ed6..c0f388871 100644 --- a/sources/shiboken6/generator/shiboken/shibokengenerator.h +++ b/sources/shiboken6/generator/shiboken/shibokengenerator.h @@ -161,6 +161,8 @@ protected: void processCodeSnip(QString &code) const; void processCodeSnip(QString &code, const QString &context) const; void processClassCodeSnip(QString &code, const GeneratorContext &context) const; + /// Replaces variables in a custom conversion type check snippet + void processTypeCheckCodeSnip(QString &code, const QString &context) const; /** * Verifies if any of the function's code injections makes a call |