aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@qt.io>2021-09-14 09:47:44 +0200
committerFriedemann Kleint <Friedemann.Kleint@qt.io>2021-09-14 11:04:42 +0200
commit87bce5e6bb10ed04a124c628e4794bfdb24d448b (patch)
tree2fd0cf7afa5ab2118f03abc6acec092bbf4e4d20
parente55c87131a66e1cd11b13663b66582412cd38788 (diff)
Fix build for non-limited API
e55c87131a66e1cd11b13663b66582412cd38788 broke the build for the non-limited API due to removing a C-style cast from a code snippet: %0 = PyBytes_GET_SIZE((PyObject *)%PYARG_0); in the overridden method of a C++ wrapper class. PyBytes_GET_SIZE(op) is defined to use PyVarObject*)(op)), which does not work when passing an AutoDecRef instance which is used for pyResult in that case. To fix this, make the placeholder a smarter; append .object() unless the code snippet invokes a member function itself. [ChangeLog][shiboken6] The replacement of %PYARG_0 in C++ wrapper classes (native) has been improved and no longer requires adding casts to PyObject *. Change-Id: Ia31b28d568603f96c93e564e5ef7554cb2468b04 Reviewed-by: Christian Tismer <tismer@stackless.com>
-rw-r--r--sources/shiboken6/generator/shiboken/shibokengenerator.cpp29
-rw-r--r--sources/shiboken6/tests/samplebinding/typesystem_sample.xml2
2 files changed, 29 insertions, 2 deletions
diff --git a/sources/shiboken6/generator/shiboken/shibokengenerator.cpp b/sources/shiboken6/generator/shiboken/shibokengenerator.cpp
index 8a24e8327..60d7a5a2c 100644
--- a/sources/shiboken6/generator/shiboken/shibokengenerator.cpp
+++ b/sources/shiboken6/generator/shiboken/shibokengenerator.cpp
@@ -1615,6 +1615,33 @@ void ShibokenGenerator::writeCodeSnips(TextStream &s,
s << "// Begin code injection\n" << code << "// End of code injection\n\n";
}
+static void replacePyArg0(TypeSystem::Language language, QString *code)
+{
+ static const QString pyArg0 = u"%PYARG_0"_qs;
+ static const QString pyReturn = QLatin1String(PYTHON_RETURN_VAR);
+
+ if (!code->contains(pyArg0))
+ return;
+ if (language != TypeSystem::NativeCode) {
+ code->replace(pyArg0, pyReturn);
+ return;
+ }
+
+ // pyResult is an AutoDecRef in overridden methods of wrapper classes which
+ // has a cast operator for PyObject *. This may however not work in all
+ // situations (fex _PyVarObject_CAST(op) defined as ((PyVarObject*)(op))).
+ // Append ".object()" unless it is followed by a '.' indicating explicit
+ // AutoDecRef member invocation.
+ static const QString pyObject = pyReturn + u".object()"_qs;
+ qsizetype pos{};
+ while ( (pos = code->indexOf(pyArg0)) >= 0) {
+ const auto next = pos + pyArg0.size();
+ const bool memberInvocation = next < code->size() && code->at(next) == u'.';
+ code->replace(pos, pyArg0.size(),
+ memberInvocation ? pyReturn : pyObject);
+ }
+}
+
void ShibokenGenerator::writeCodeSnips(TextStream &s,
const CodeSnipList &codeSnips,
TypeSystem::CodeSnipPosition position,
@@ -1635,7 +1662,7 @@ void ShibokenGenerator::writeCodeSnips(TextStream &s,
}
// Replace %PYARG_# variables.
- code.replace(QLatin1String("%PYARG_0"), QLatin1String(PYTHON_RETURN_VAR));
+ replacePyArg0(language, &code);
static const QRegularExpression pyArgsRegex(QStringLiteral("%PYARG_(\\d+)"));
Q_ASSERT(pyArgsRegex.isValid());
diff --git a/sources/shiboken6/tests/samplebinding/typesystem_sample.xml b/sources/shiboken6/tests/samplebinding/typesystem_sample.xml
index bc5052e49..95c51938e 100644
--- a/sources/shiboken6/tests/samplebinding/typesystem_sample.xml
+++ b/sources/shiboken6/tests/samplebinding/typesystem_sample.xml
@@ -1445,7 +1445,7 @@
PyTuple_SET_ITEM(%PYARG_0, 3, %CONVERTTOPYTHON[int](a3));
</template>
<template name="fix_native_return_int*,int*,int*,int*">
- PyObject* _obj = %PYARG_0.object();
+ PyObject* _obj = %PYARG_0;
if (!PySequence_Check(_obj)
|| PySequence_Fast_GET_SIZE(_obj) != 4
|| !PyNumber_Check(PySequence_Fast_GET_ITEM(_obj, 0))