aboutsummaryrefslogtreecommitdiffstats
path: root/sources/shiboken6/generator/shiboken
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@qt.io>2023-09-19 15:02:53 +0200
committerFriedemann Kleint <Friedemann.Kleint@qt.io>2023-10-02 10:32:12 +0200
commit25a64e5eaddcb403095c2d9f32ba90a0d7c7b340 (patch)
treee286a14532e0067df53a77755718535f24943b77 /sources/shiboken6/generator/shiboken
parent1961d9ad766e59a9d72dfa2eb2317ba34e9e377d (diff)
Add a __repr__ function for smart pointers
Add a generic repr function to the string utilities of libshiboken. Add a new module sbksmartpointer with a specialized repr function adding pointee information to libshiboken. Generate code to call it into the smart pointer code. Pick-to: 6.6 Task-number: PYSIDE-2462 Change-Id: Ie7b8956051bc1b7ef817c15d26deb1dc3099fd30 Reviewed-by: Shyamnath Premnadh <Shyamnath.Premnadh@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Diffstat (limited to 'sources/shiboken6/generator/shiboken')
-rw-r--r--sources/shiboken6/generator/shiboken/cppgenerator.cpp33
-rw-r--r--sources/shiboken6/generator/shiboken/cppgenerator.h4
-rw-r--r--sources/shiboken6/generator/shiboken/cppgenerator_smartpointer.cpp33
3 files changed, 54 insertions, 16 deletions
diff --git a/sources/shiboken6/generator/shiboken/cppgenerator.cpp b/sources/shiboken6/generator/shiboken/cppgenerator.cpp
index 95eb61f9a..9a84c97ab 100644
--- a/sources/shiboken6/generator/shiboken/cppgenerator.cpp
+++ b/sources/shiboken6/generator/shiboken/cppgenerator.cpp
@@ -4289,8 +4289,9 @@ void CppGenerator::writeClassDefinition(TextStream &s,
if (generateRichComparison(classContext))
tp_richcompare = cpythonBaseName(metaClass) + u"_richcompare"_s;
+ const bool isSmartPointer = classContext.forSmartPointer();
QString tp_getset;
- if (shouldGenerateGetSetList(metaClass) && !classContext.forSmartPointer())
+ if (shouldGenerateGetSetList(metaClass) && !isSmartPointer)
tp_getset = cpythonGettersSettersDefinitionName(metaClass);
// search for special functions
@@ -4304,10 +4305,11 @@ void CppGenerator::writeClassDefinition(TextStream &s,
it.value() = cpythonFunctionName(func);
}
if (m_tpFuncs.value(REPR_FUNCTION).isEmpty()
- && metaClass->hasToStringCapability()) {
- m_tpFuncs[REPR_FUNCTION] = writeReprFunction(s,
- classContext,
- metaClass->toStringCapabilityIndirections());
+ && (isSmartPointer || metaClass->hasToStringCapability())) {
+ const QString name = isSmartPointer
+ ? writeSmartPointerReprFunction(s, classContext)
+ : writeReprFunction(s, classContext, metaClass->toStringCapabilityIndirections());
+ m_tpFuncs[REPR_FUNCTION] = name;
}
// class or some ancestor has multiple inheritance
@@ -6499,14 +6501,20 @@ void CppGenerator::writeIndexError(TextStream &s, const QString &errorMsg,
<< errorReturn << outdent << "}\n";
}
+QString CppGenerator::writeReprFunctionHeader(TextStream &s, const GeneratorContext &context)
+{
+ QString funcName = cpythonBaseName(context.metaClass()) + REPR_FUNCTION;
+ s << "extern \"C\"\n{\n"
+ << "static PyObject *" << funcName << "(PyObject *self)\n{\n" << indent;
+ return funcName;
+}
+
QString CppGenerator::writeReprFunction(TextStream &s,
const GeneratorContext &context,
uint indirections)
{
const auto metaClass = context.metaClass();
- QString funcName = cpythonBaseName(metaClass) + REPR_FUNCTION;
- s << "extern \"C\"\n{\n"
- << "static PyObject *" << funcName << "(PyObject *self)\n{\n" << indent;
+ QString funcName = writeReprFunctionHeader(s, context);
writeCppSelfDefinition(s, context);
s << R"(QBuffer buffer;
buffer.open(QBuffer::ReadWrite);
@@ -6529,7 +6537,12 @@ if (idx >= 0)
<< "return Shiboken::String::fromFormat(\"<%s.%s at %p>\","
" Shiboken::String::toCString(mod), str.constData(), self);\n"
<< outdent
- << "return Shiboken::String::fromFormat(\"<%s at %p>\", str.constData(), self);\n"
- << outdent << "}\n} // extern C\n\n";
+ << "return Shiboken::String::fromFormat(\"<%s at %p>\", str.constData(), self);\n";
+ writeReprFunctionFooter(s);
return funcName;
}
+
+void CppGenerator::writeReprFunctionFooter(TextStream &s)
+{
+ s << outdent << "}\n} // extern C\n\n";
+}
diff --git a/sources/shiboken6/generator/shiboken/cppgenerator.h b/sources/shiboken6/generator/shiboken/cppgenerator.h
index d66cfb90b..62e7a4309 100644
--- a/sources/shiboken6/generator/shiboken/cppgenerator.h
+++ b/sources/shiboken6/generator/shiboken/cppgenerator.h
@@ -507,9 +507,13 @@ private:
static void writeIndexError(TextStream &s, const QString &errorMsg,
ErrorReturn errorReturn);
+ static QString writeReprFunctionHeader(TextStream &s, const GeneratorContext &context);
static QString writeReprFunction(TextStream &s,
const GeneratorContext &context,
uint indirections);
+ static QString writeSmartPointerReprFunction(TextStream &s,
+ const GeneratorContext &context);
+ static void writeReprFunctionFooter(TextStream &s);
static void writePyMethodDefs(TextStream &s, const QString &className,
const QString &methodsDefinitions);
diff --git a/sources/shiboken6/generator/shiboken/cppgenerator_smartpointer.cpp b/sources/shiboken6/generator/shiboken/cppgenerator_smartpointer.cpp
index ea65733e2..834345991 100644
--- a/sources/shiboken6/generator/shiboken/cppgenerator_smartpointer.cpp
+++ b/sources/shiboken6/generator/shiboken/cppgenerator_smartpointer.cpp
@@ -29,6 +29,19 @@ static QString smartPointerGetter(const GeneratorContext &context)
return std::static_pointer_cast<const SmartPointerTypeEntry>(te)->getter();
}
+struct callGetter
+{
+ explicit callGetter(const GeneratorContext &context) : m_context(context) {}
+
+ const GeneratorContext &m_context;
+};
+
+TextStream &operator<<(TextStream &str, const callGetter &c)
+{
+ str << "PyObject_CallMethod(self, \"" << smartPointerGetter(c.m_context) << "\", 0)";
+ return str;
+}
+
// Helpers to collect all smart pointer pointee base classes
static AbstractMetaClassCList
findSmartPointeeBaseClasses(const ApiExtractorResult &api,
@@ -102,6 +115,7 @@ void CppGenerator::generateSmartPointerClass(TextStream &s, const GeneratorConte
IncludeGroup includes{u"Extra includes"_s, typeEntry->extraIncludes()};
if (hasPointeeClass)
includes.append(classContext.pointeeClass()->typeEntry()->include());
+ includes.includes.append({Include::IncludePath, u"sbksmartpointer.h"_s});
generateIncludes(s, classContext, {includes});
s << '\n';
@@ -390,9 +404,7 @@ void CppGenerator::writeSmartPointerSetattroFunction(TextStream &s,
Q_ASSERT(context.forSmartPointer());
writeSetattroDefinition(s, context.metaClass());
s << smartPtrComment
- << "if (auto *rawObj = PyObject_CallMethod(self, \""
- << smartPointerGetter(context)
- << "\", 0)) {\n" << indent
+ << "if (auto *rawObj = " << callGetter(context) << ") {\n" << indent
<< "if (PyObject_HasAttr(rawObj, name) != 0)\n" << indent
<< "return PyObject_GenericSetAttr(rawObj, name, value);\n" << outdent
<< "Py_DECREF(rawObj);\n" << outdent
@@ -428,9 +440,7 @@ return nullptr;
// This generates the code which dispatches access to member functions
// and fields from the smart pointer to its pointee.
s << smartPtrComment
- << "if (auto *rawObj = PyObject_CallMethod(self, \""
- << smartPointerGetter(context)
- << "\", 0)) {\n" << indent
+ << "if (auto *rawObj = " << callGetter(context) << ") {\n" << indent
<< "if (auto *attribute = PyObject_GetAttr(rawObj, name))\n"
<< indent << "tmp = attribute;\n" << outdent
<< "Py_DECREF(rawObj);\n" << outdent
@@ -444,3 +454,14 @@ PyErr_Format(PyExc_AttributeError,
<< "}\n"
<< "return tmp;\n" << outdent << "}\n\n";
}
+
+QString CppGenerator::writeSmartPointerReprFunction(TextStream &s,
+ const GeneratorContext &context)
+{
+ const auto metaClass = context.metaClass();
+ QString funcName = writeReprFunctionHeader(s, context);
+ s << "Shiboken::AutoDecRef pointee(" << callGetter(context) << ");\n"
+ << "return Shiboken::SmartPointer::repr(self, pointee);\n";
+ writeReprFunctionFooter(s);
+ return funcName;
+}