diff options
author | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2021-09-14 09:47:44 +0200 |
---|---|---|
committer | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2021-09-14 11:04:42 +0200 |
commit | 87bce5e6bb10ed04a124c628e4794bfdb24d448b (patch) | |
tree | 2fd0cf7afa5ab2118f03abc6acec092bbf4e4d20 | |
parent | e55c87131a66e1cd11b13663b66582412cd38788 (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.cpp | 29 | ||||
-rw-r--r-- | sources/shiboken6/tests/samplebinding/typesystem_sample.xml | 2 |
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)) |