aboutsummaryrefslogtreecommitdiffstats
path: root/sources/shiboken2
diff options
context:
space:
mode:
Diffstat (limited to 'sources/shiboken2')
-rw-r--r--sources/shiboken2/ApiExtractor/abstractmetalang.h5
-rw-r--r--sources/shiboken2/ApiExtractor/doxygenparser.cpp3
-rw-r--r--sources/shiboken2/ApiExtractor/qtdocparser.cpp3
-rw-r--r--sources/shiboken2/doc/CMakeLists.txt3
-rw-r--r--sources/shiboken2/generator/indentor.h14
-rw-r--r--sources/shiboken2/generator/qtdoc/qtdocgenerator.cpp22
-rw-r--r--sources/shiboken2/generator/shiboken2/cppgenerator.cpp185
-rw-r--r--sources/shiboken2/generator/shiboken2/headergenerator.cpp6
-rw-r--r--sources/shiboken2/generator/shiboken2/shibokengenerator.cpp3
-rw-r--r--sources/shiboken2/libshiboken/sbkstaticstrings.cpp2
-rw-r--r--sources/shiboken2/libshiboken/sbkstaticstrings.h2
-rw-r--r--sources/shiboken2/libshiboken/signature/signature.cpp3
-rw-r--r--sources/shiboken2/libshiboken/signature/signature_helper.cpp73
-rw-r--r--sources/shiboken2/libshiboken/signature/signature_p.h1
-rw-r--r--sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/parser.py5
-rw-r--r--sources/shiboken2/tests/libother/otherobjecttype.cpp2
-rw-r--r--sources/shiboken2/tests/libother/otherobjecttype.h3
-rw-r--r--sources/shiboken2/tests/libsample/removednamespaces.h10
-rw-r--r--sources/shiboken2/tests/libsample/samplenamespace.h19
-rw-r--r--sources/shiboken2/tests/libsample/virtualmethods.h4
-rw-r--r--sources/shiboken2/tests/samplebinding/CMakeLists.txt2
-rw-r--r--sources/shiboken2/tests/samplebinding/enumfromremovednamespace_test.py20
-rw-r--r--sources/shiboken2/tests/samplebinding/namespace_test.py20
-rw-r--r--sources/shiboken2/tests/samplebinding/typesystem_sample.xml6
24 files changed, 227 insertions, 189 deletions
diff --git a/sources/shiboken2/ApiExtractor/abstractmetalang.h b/sources/shiboken2/ApiExtractor/abstractmetalang.h
index 466464807..648c792b3 100644
--- a/sources/shiboken2/ApiExtractor/abstractmetalang.h
+++ b/sources/shiboken2/ApiExtractor/abstractmetalang.h
@@ -1413,10 +1413,7 @@ public:
AbstractMetaField *findField(const QString &name) const;
- AbstractMetaEnumList enums() const
- {
- return m_enums;
- }
+ const AbstractMetaEnumList &enums() const { return m_enums; }
void setEnums(const AbstractMetaEnumList &enums)
{
m_enums = enums;
diff --git a/sources/shiboken2/ApiExtractor/doxygenparser.cpp b/sources/shiboken2/ApiExtractor/doxygenparser.cpp
index da6e32fba..cf152720e 100644
--- a/sources/shiboken2/ApiExtractor/doxygenparser.cpp
+++ b/sources/shiboken2/ApiExtractor/doxygenparser.cpp
@@ -199,8 +199,7 @@ void DoxygenParser::fillDocumentation(AbstractMetaClass* metaClass)
}
//Enums
- const AbstractMetaEnumList &enums = metaClass->enums();
- for (AbstractMetaEnum *meta_enum : enums) {
+ for (AbstractMetaEnum *meta_enum : metaClass->enums()) {
QString query = QLatin1String("/doxygen/compounddef/sectiondef/memberdef[@kind=\"enum\"]/name[text()=\"")
+ meta_enum->name() + QLatin1String("\"]/..");
QString doc = getDocumentation(xquery, query, DocModificationList());
diff --git a/sources/shiboken2/ApiExtractor/qtdocparser.cpp b/sources/shiboken2/ApiExtractor/qtdocparser.cpp
index 40c04a403..d439b3fd5 100644
--- a/sources/shiboken2/ApiExtractor/qtdocparser.cpp
+++ b/sources/shiboken2/ApiExtractor/qtdocparser.cpp
@@ -285,8 +285,7 @@ void QtDocParser::fillDocumentation(AbstractMetaClass* metaClass)
}
#endif
// Enums
- const AbstractMetaEnumList &enums = metaClass->enums();
- for (AbstractMetaEnum *meta_enum : enums) {
+ for (AbstractMetaEnum *meta_enum : metaClass->enums()) {
query.clear();
QTextStream(&query) << classQuery << "/enum[@name=\""
<< meta_enum->name() << "\"]/description";
diff --git a/sources/shiboken2/doc/CMakeLists.txt b/sources/shiboken2/doc/CMakeLists.txt
index 399dbba7a..5f59bfbf0 100644
--- a/sources/shiboken2/doc/CMakeLists.txt
+++ b/sources/shiboken2/doc/CMakeLists.txt
@@ -1,5 +1,8 @@
cmake_minimum_required(VERSION 3.16)
+if(FULLDOCSBUILD EQUAL 0)
+ project(shiboken2_doc)
+endif()
find_program(SPHINX sphinx-build DOC "Path to sphinx-build binary.")
if (SPHINX)
diff --git a/sources/shiboken2/generator/indentor.h b/sources/shiboken2/generator/indentor.h
index 111259f12..3dcec85b6 100644
--- a/sources/shiboken2/generator/indentor.h
+++ b/sources/shiboken2/generator/indentor.h
@@ -82,4 +82,18 @@ inline QTextStream &operator <<(QTextStream &s, const IndentorBase<tabWidth> &in
return s;
}
+template <int tabWidth>
+const char *indent(IndentorBase<tabWidth> &indentor)
+{
+ ++indentor.indent;
+ return "";
+}
+
+template <int tabWidth>
+const char *outdent(IndentorBase<tabWidth> &indentor)
+{
+ --indentor.indent;
+ return "";
+}
+
#endif // GENERATOR_H
diff --git a/sources/shiboken2/generator/qtdoc/qtdocgenerator.cpp b/sources/shiboken2/generator/qtdoc/qtdocgenerator.cpp
index 1a7c195b4..282da6eca 100644
--- a/sources/shiboken2/generator/qtdoc/qtdocgenerator.cpp
+++ b/sources/shiboken2/generator/qtdoc/qtdocgenerator.cpp
@@ -1762,8 +1762,7 @@ void QtDocGenerator::writeEnums(QTextStream& s, const AbstractMetaClass* cppClas
{
static const QString section_title = QLatin1String(".. attribute:: ");
- const AbstractMetaEnumList &enums = cppClass->enums();
- for (AbstractMetaEnum *en : enums) {
+ for (AbstractMetaEnum *en : cppClass->enums()) {
s << section_title << cppClass->fullName() << '.' << en->name() << Qt::endl << Qt::endl;
writeFormattedText(s, en->documentation().value(), cppClass);
const auto version = versionOf(en->typeEntry());
@@ -2248,18 +2247,13 @@ void QtDocGenerator::writeModuleDocumentation()
writeFancyToc(s, it.value());
- s << INDENT << ".. container:: hide\n\n";
- {
- Indentation indentation(INDENT);
- s << INDENT << ".. toctree::\n";
- Indentation deeperIndentation(INDENT);
- s << INDENT << ":maxdepth: 1\n\n";
- for (const QString &className : qAsConst(it.value()))
- s << INDENT << className << Qt::endl;
- s << Qt::endl << Qt::endl;
- }
-
- s << "Detailed Description\n--------------------\n\n";
+ s << INDENT << ".. container:: hide\n\n" << indent(INDENT)
+ << INDENT << ".. toctree::\n" << indent(INDENT)
+ << INDENT << ":maxdepth: 1\n\n";
+ for (const QString &className : qAsConst(it.value()))
+ s << INDENT << className << Qt::endl;
+ s << "\n\n" << outdent(INDENT) << outdent(INDENT)
+ << "Detailed Description\n--------------------\n\n";
// module doc is always wrong and C++istic, so go straight to the extra directory!
QFile moduleDoc(m_extraSectionDir + QLatin1Char('/') + moduleName.mid(lastIndex + 1) + QLatin1String(".rst"));
diff --git a/sources/shiboken2/generator/shiboken2/cppgenerator.cpp b/sources/shiboken2/generator/shiboken2/cppgenerator.cpp
index 75633c072..8e9b480cc 100644
--- a/sources/shiboken2/generator/shiboken2/cppgenerator.cpp
+++ b/sources/shiboken2/generator/shiboken2/cppgenerator.cpp
@@ -1011,11 +1011,8 @@ void CppGenerator::writeVirtualMethodNative(QTextStream &s,
s << INDENT << "Shiboken::GilState gil;\n";
// Get out of virtual method call if someone already threw an error.
- s << INDENT << "if (PyErr_Occurred())\n";
- {
- Indentation indentation(INDENT);
- s << INDENT << returnStatement << '\n';
- }
+ s << INDENT << "if (PyErr_Occurred())\n" << indent(INDENT)
+ << INDENT << returnStatement << '\n' << outdent(INDENT);
//PYSIDE-1019: Add info about properties.
int propFlag = 0;
@@ -1035,16 +1032,13 @@ void CppGenerator::writeVirtualMethodNative(QTextStream &s,
s << INDENT << "static const char *funcName = \"" << propStr << funcName << "\";\n";
s << INDENT << "Shiboken::AutoDecRef " << PYTHON_OVERRIDE_VAR
<< "(Shiboken::BindingManager::instance().getOverride(this, nameCache, funcName));\n";
- s << INDENT << "if (" << PYTHON_OVERRIDE_VAR << ".isNull()) {\n";
- {
- Indentation indentation(INDENT);
- s << INDENT << "gil.release();\n";
- if (useOverrideCaching(func->ownerClass()))
- s << INDENT << "m_PyMethodCache[" << cacheIndex << "] = true;\n";
- writeVirtualMethodCppCall(s, func, funcName, snips, lastArg, retType,
- returnStatement);
- }
- s << INDENT << "}\n\n"; //WS
+ s << INDENT << "if (" << PYTHON_OVERRIDE_VAR << ".isNull()) {\n"
+ << indent(INDENT) << INDENT << "gil.release();\n";
+ if (useOverrideCaching(func->ownerClass()))
+ s << INDENT << "m_PyMethodCache[" << cacheIndex << "] = true;\n";
+ writeVirtualMethodCppCall(s, func, funcName, snips, lastArg, retType,
+ returnStatement);
+ s << outdent(INDENT) << INDENT << "}\n\n"; //WS
writeConversionRule(s, func, TypeSystem::TargetLangCode);
@@ -1193,15 +1187,14 @@ void CppGenerator::writeVirtualMethodNative(QTextStream &s,
}
if (invalidateReturn) {
- s << INDENT << "if (invalidateArg0)\n";
- Indentation indentation(INDENT);
- s << INDENT << "Shiboken::Object::releaseOwnership(" << PYTHON_RETURN_VAR << ".object());\n";
+ s << INDENT << "if (invalidateArg0)\n" << indent(INDENT)
+ << INDENT << "Shiboken::Object::releaseOwnership(" << PYTHON_RETURN_VAR
+ << ".object());\n" << outdent(INDENT);
}
for (int argIndex : qAsConst(invalidateArgs)) {
- s << INDENT << "if (invalidateArg" << argIndex << ")\n";
- Indentation indentation(INDENT);
- s << INDENT << "Shiboken::Object::invalidate(PyTuple_GET_ITEM(" << PYTHON_ARGS << ", ";
- s << (argIndex - 1) << "));\n";
+ s << INDENT << "if (invalidateArg" << argIndex << ")\n" << indent(INDENT)
+ << INDENT << "Shiboken::Object::invalidate(PyTuple_GET_ITEM(" << PYTHON_ARGS
+ << ", " << (argIndex - 1) << "));\n" << outdent(INDENT);
}
@@ -1861,30 +1854,20 @@ void CppGenerator::writeConstructorWrapper(QTextStream &s, const AbstractMetaFun
}
if (metaClass->isAbstract()) {
- s << INDENT << "if (type == myType) {\n";
- {
- Indentation indent(INDENT);
- s << INDENT << "PyErr_SetString(PyExc_NotImplementedError,\n";
- {
- Indentation indentation(INDENT);
- s << INDENT << "\"'" << metaClass->qualifiedCppName();
- }
- s << "' represents a C++ abstract class and cannot be instantiated\");\n";
- s << INDENT << returnStatement(m_currentErrorCode) << Qt::endl;
- }
- s << INDENT<< "}\n\n";
+ s << INDENT << "if (type == myType) {\n" << indent(INDENT)
+ << INDENT << "PyErr_SetString(PyExc_NotImplementedError,\n" << indent(INDENT)
+ << INDENT << "\"'" << metaClass->qualifiedCppName()
+ << "' represents a C++ abstract class and cannot be instantiated\");\n" << outdent(INDENT)
+ << INDENT << returnStatement(m_currentErrorCode) << '\n' << outdent(INDENT)
+ << INDENT<< "}\n\n";
}
if (metaClass->baseClassNames().size() > 1) {
- if (!metaClass->isAbstract()) {
- s << INDENT << "if (type != myType) {\n";
- }
- {
- Indentation indentation(INDENT);
- s << INDENT << "Shiboken::ObjectType::copyMultipleInheritance(type, myType);\n";
- }
if (!metaClass->isAbstract())
- s << INDENT<< "}\n\n";
+ s << INDENT << "if (type != myType)\n" << indent(INDENT);
+ s << INDENT << "Shiboken::ObjectType::copyMultipleInheritance(type, myType);\n";
+ if (!metaClass->isAbstract())
+ s << outdent(INDENT) << '\n';
}
writeMethodWrapperPreamble(s, overloadData, classContext);
@@ -1931,11 +1914,9 @@ void CppGenerator::writeConstructorWrapper(QTextStream &s, const AbstractMetaFun
s << Qt::endl << INDENT << "// QObject setup\n";
s << INDENT << "PySide::Signal::updateSourceObject(self);\n";
s << INDENT << "metaObject = cptr->metaObject(); // <- init python qt properties\n";
- s << INDENT << "if (kwds && !PySide::fillQtProperties(self, metaObject, kwds, argNames, " << argNamesSet.count() << "))\n";
- {
- Indentation indentation(INDENT);
- s << INDENT << returnStatement(m_currentErrorCode) << Qt::endl;
- }
+ s << INDENT << "if (kwds && !PySide::fillQtProperties(self, metaObject, kwds, argNames, "
+ << argNamesSet.count() << "))\n" << indent(INDENT)
+ << INDENT << returnStatement(m_currentErrorCode) << '\n' << outdent(INDENT);
}
// Constructor code injections, position=end
@@ -2203,7 +2184,8 @@ void CppGenerator::writeCppSelfDefinition(QTextStream &s,
Q_ASSERT(!(cppSelfAsReference && hasStaticOverload));
const AbstractMetaClass *metaClass = context.metaClass();
- bool useWrapperClass = avoidProtectedHack() && metaClass->hasProtectedMembers();
+ bool useWrapperClass = avoidProtectedHack() && metaClass->hasProtectedMembers()
+ && !metaClass->attributes().testFlag(AbstractMetaAttributes::FinalCppClass);
Q_ASSERT(!useWrapperClass || context.useWrapper());
QString className;
if (!context.forSmartPointer()) {
@@ -2919,14 +2901,11 @@ void CppGenerator::writeSingleFunctionCall(QTextStream &s,
int numRemovedArgs = OverloadData::numberOfRemovedArguments(func);
- s << INDENT << "if (!PyErr_Occurred()) {\n";
- {
- Indentation indentation(INDENT);
- writeMethodCall(s, func, context, func->arguments().size() - numRemovedArgs);
- if (!func->isConstructor())
- writeNoneReturn(s, func, overloadData.hasNonVoidReturnType());
- }
- s << INDENT << "}\n";
+ s << INDENT << "if (!PyErr_Occurred()) {\n" << indent(INDENT);
+ writeMethodCall(s, func, context, func->arguments().size() - numRemovedArgs);
+ if (!func->isConstructor())
+ writeNoneReturn(s, func, overloadData.hasNonVoidReturnType());
+ s << outdent(INDENT) << INDENT << "}\n";
}
QString CppGenerator::cppToPythonFunctionName(const QString &sourceTypeName, QString targetTypeName)
@@ -3506,14 +3485,16 @@ void CppGenerator::writeMethodCall(QTextStream &s, const AbstractMetaFunction *f
+ QLatin1String(" *>(") + QLatin1String(CPP_SELF_VAR) + QLatin1Char(')');
if (func->isConstant()) {
if (avoidProtectedHack()) {
+ auto ownerClass = func->ownerClass();
mc << "const_cast<const ::";
- if (func->ownerClass()->hasProtectedMembers()) {
+ if (ownerClass->hasProtectedMembers()
+ && !ownerClass->attributes().testFlag(AbstractMetaAttributes::FinalCppClass)) {
// PYSIDE-500: Need a special wrapper cast when inherited
- const QString selfWrapCast = func->ownerClass() == func->implementingClass()
+ const QString selfWrapCast = ownerClass == func->implementingClass()
? QLatin1String(CPP_SELF_VAR)
- : QLatin1String("reinterpret_cast<") + wrapperName(func->ownerClass())
+ : QLatin1String("reinterpret_cast<") + wrapperName(ownerClass)
+ QLatin1String(" *>(") + QLatin1String(CPP_SELF_VAR) + QLatin1Char(')');
- mc << wrapperName(func->ownerClass());
+ mc << wrapperName(ownerClass);
mc << " *>(" << selfWrapCast << ")->";
}
else {
@@ -4555,26 +4536,20 @@ void CppGenerator::writeSetterFunctionPreamble(QTextStream &s, const QString &na
writeCppSelfDefinition(s, context);
- s << INDENT << "if (pyIn == " << NULL_PTR << ") {\n";
- {
- Indentation indent(INDENT);
- s << INDENT << "PyErr_SetString(PyExc_TypeError, \"'";
- s << name << "' may not be deleted\");\n";
- s << INDENT << "return -1;\n";
- }
- s << INDENT << "}\n";
+ s << INDENT << "if (pyIn == " << NULL_PTR << ") {\n" << indent(INDENT)
+ << INDENT << "PyErr_SetString(PyExc_TypeError, \"'"
+ << name << "' may not be deleted\");\n"
+ << INDENT << "return -1;\n"
+ << outdent(INDENT) << INDENT << "}\n";
s << INDENT << "PythonToCppFunc " << PYTHON_TO_CPP_VAR << "{nullptr};\n";
s << INDENT << "if (!";
writeTypeCheck(s, type, QLatin1String("pyIn"), isNumber(type->typeEntry()));
- s << ") {\n";
- {
- Indentation indent(INDENT);
- s << INDENT << "PyErr_SetString(PyExc_TypeError, \"wrong type attributed to '";
- s << name << "', '" << type->name() << "' or convertible type expected\");\n";
- s << INDENT << "return -1;\n";
- }
- s << INDENT<< "}\n\n";
+ s << ") {\n" << indent(INDENT)
+ << INDENT << "PyErr_SetString(PyExc_TypeError, \"wrong type attributed to '"
+ << name << "', '" << type->name() << "' or convertible type expected\");\n"
+ << INDENT << "return -1;\n"
+ << outdent(INDENT) << INDENT<< "}\n\n";
}
void CppGenerator::writeSetterFunction(QTextStream &s,
@@ -5430,8 +5405,7 @@ void CppGenerator::writeInitQtMetaTypeFunctionBody(QTextStream &s, const Generat
}
}
- const AbstractMetaEnumList &enums = metaClass->enums();
- for (AbstractMetaEnum *metaEnum : enums) {
+ for (AbstractMetaEnum *metaEnum : metaClass->enums()) {
if (!metaEnum->isPrivate() && !metaEnum->isAnonymous()) {
for (const QString &name : qAsConst(nameVariants))
s << INDENT << "qRegisterMetaType< ::" << metaEnum->typeEntry()->qualifiedCppName() << " >(\"" << name << "::" << metaEnum->name() << "\");\n";
@@ -5752,7 +5726,7 @@ bool CppGenerator::finishGeneration()
QString signaturesString;
QTextStream signatureStream(&signaturesString);
- Indentation indent(INDENT);
+ Indentation indentation(INDENT);
const auto functionGroups = getGlobalFunctionGroups();
for (auto it = functionGroups.cbegin(), end = functionGroups.cend(); it != end; ++it) {
@@ -5877,19 +5851,13 @@ bool CppGenerator::finishGeneration()
s << "void cleanTypesAttributes(void) {\n";
s << INDENT << "if (PY_VERSION_HEX >= 0x03000000 && PY_VERSION_HEX < 0x03060000)\n";
s << INDENT << " return; // PYSIDE-953: testbinding crashes in Python 3.5 when hasattr touches types!\n";
- s << INDENT << "for (int i = 0, imax = SBK_" << moduleName() << "_IDX_COUNT; i < imax; i++) {\n";
- {
- Indentation indentation(INDENT);
- s << INDENT << "PyObject *pyType = reinterpret_cast<PyObject *>(" << cppApiVariableName() << "[i]);\n";
- s << INDENT << "Shiboken::AutoDecRef attrName(Py_BuildValue(\"s\", \"staticMetaObject\"));\n";
- s << INDENT << "if (pyType && PyObject_HasAttr(pyType, attrName))\n";
- {
- Indentation indentation(INDENT);
- s << INDENT << "PyObject_SetAttr(pyType, attrName, Py_None);\n";
- }
- }
- s << INDENT << "}\n";
- s << "}\n";
+ s << INDENT << "for (int i = 0, imax = SBK_" << moduleName()
+ << "_IDX_COUNT; i < imax; i++) {\n" << indent(INDENT)
+ << INDENT << "PyObject *pyType = reinterpret_cast<PyObject *>(" << cppApiVariableName() << "[i]);\n"
+ << INDENT << "Shiboken::AutoDecRef attrName(Py_BuildValue(\"s\", \"staticMetaObject\"));\n"
+ << INDENT << "if (pyType && PyObject_HasAttr(pyType, attrName))\n" << indent(INDENT)
+ << INDENT << "PyObject_SetAttr(pyType, attrName, Py_None);\n" << outdent(INDENT)
+ << outdent(INDENT) << INDENT << "}\n" << "}\n";
}
s << "// Global functions ";
@@ -6003,19 +5971,15 @@ bool CppGenerator::finishGeneration()
writeCodeSnips(s, snips, TypeSystem::CodeSnipPositionBeginning, TypeSystem::TargetLangCode);
for (const QString &requiredModule : requiredModules) {
- s << INDENT << "{\n";
- {
- Indentation indentation(INDENT);
- s << INDENT << "Shiboken::AutoDecRef requiredModule(Shiboken::Module::import(\"" << requiredModule << "\"));\n";
- s << INDENT << "if (requiredModule.isNull())\n";
- {
- Indentation indentation(INDENT);
- s << INDENT << "return SBK_MODULE_INIT_ERROR;\n";
- }
- s << INDENT << cppApiVariableName(requiredModule) << " = Shiboken::Module::getTypes(requiredModule);\n";
- s << INDENT << convertersVariableName(requiredModule) << " = Shiboken::Module::getTypeConverters(requiredModule);\n";
- }
- s << INDENT << "}\n\n";
+ s << INDENT << "{\n" << indent(INDENT)
+ << INDENT << "Shiboken::AutoDecRef requiredModule(Shiboken::Module::import(\"" << requiredModule << "\"));\n"
+ << INDENT << "if (requiredModule.isNull())\n" << indent(INDENT)
+ << INDENT << "return SBK_MODULE_INIT_ERROR;\n" << outdent(INDENT)
+ << INDENT << cppApiVariableName(requiredModule)
+ << " = Shiboken::Module::getTypes(requiredModule);\n"
+ << INDENT << convertersVariableName(requiredModule)
+ << " = Shiboken::Module::getTypeConverters(requiredModule);\n" << outdent(INDENT)
+ << INDENT << "}\n\n";
}
int maxTypeIndex = getMaxTypeIndex() + instantiatedSmartPointers().size();
@@ -6088,13 +6052,10 @@ bool CppGenerator::finishGeneration()
s << INDENT << "Shiboken::Module::registerTypes(module, " << cppApiVariableName() << ");\n";
s << INDENT << "Shiboken::Module::registerTypeConverters(module, " << convertersVariableName() << ");\n";
- s << Qt::endl << INDENT << "if (PyErr_Occurred()) {\n";
- {
- Indentation indentation(INDENT);
- s << INDENT << "PyErr_Print();\n";
- s << INDENT << "Py_FatalError(\"can't initialize module " << moduleName() << "\");\n";
- }
- s << INDENT << "}\n";
+ s << '\n' << INDENT << "if (PyErr_Occurred()) {\n" << indent(INDENT)
+ << INDENT << "PyErr_Print();\n"
+ << INDENT << "Py_FatalError(\"can't initialize module " << moduleName() << "\");\n"
+ << outdent(INDENT) << INDENT << "}\n";
// module inject-code target/end
if (!snips.isEmpty())
diff --git a/sources/shiboken2/generator/shiboken2/headergenerator.cpp b/sources/shiboken2/generator/shiboken2/headergenerator.cpp
index 7826e350a..1fdd89af8 100644
--- a/sources/shiboken2/generator/shiboken2/headergenerator.cpp
+++ b/sources/shiboken2/generator/shiboken2/headergenerator.cpp
@@ -343,8 +343,7 @@ void HeaderGenerator::writeTypeIndexValueLines(QTextStream &s, const AbstractMet
if (!typeEntry->generateCode() || !NamespaceTypeEntry::isVisibleScope(typeEntry))
return;
writeTypeIndexValueLine(s, metaClass->typeEntry());
- const AbstractMetaEnumList &enums = metaClass->enums();
- for (const AbstractMetaEnum *metaEnum : enums) {
+ for (const AbstractMetaEnum *metaEnum : metaClass->enums()) {
if (metaEnum->isPrivate())
continue;
writeTypeIndexValueLine(s, metaEnum->typeEntry());
@@ -503,8 +502,7 @@ bool HeaderGenerator::finishGeneration()
const TypeEntry *classType = metaClass->typeEntry();
includes << classType->include();
- const AbstractMetaEnumList &enums = metaClass->enums();
- for (const AbstractMetaEnum *cppEnum : enums) {
+ for (const AbstractMetaEnum *cppEnum : metaClass->enums()) {
if (cppEnum->isAnonymous() || cppEnum->isPrivate())
continue;
EnumTypeEntry *enumType = cppEnum->typeEntry();
diff --git a/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp b/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp
index 825965b92..1f91609bd 100644
--- a/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp
+++ b/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp
@@ -339,8 +339,7 @@ void ShibokenGenerator::lookForEnumsInClassesNotToBeGenerated(AbstractMetaEnumLi
Q_ASSERT(metaClass);
// if a scope is not to be generated, collect its enums into the parent scope
if (!NamespaceTypeEntry::isVisibleScope(metaClass->typeEntry())) {
- const AbstractMetaEnumList &enums = metaClass->enums();
- for (AbstractMetaEnum *metaEnum : enums) {
+ for (AbstractMetaEnum *metaEnum : metaClass->enums()) {
if (!metaEnum->isPrivate() && metaEnum->typeEntry()->generateCode()
&& !enumList.contains(metaEnum)) {
enumList.append(metaEnum);
diff --git a/sources/shiboken2/libshiboken/sbkstaticstrings.cpp b/sources/shiboken2/libshiboken/sbkstaticstrings.cpp
index 672be4009..5559d58d6 100644
--- a/sources/shiboken2/libshiboken/sbkstaticstrings.cpp
+++ b/sources/shiboken2/libshiboken/sbkstaticstrings.cpp
@@ -56,6 +56,8 @@ STATIC_STRING_IMPL(dumps, "dumps")
STATIC_STRING_IMPL(fget, "fget")
STATIC_STRING_IMPL(fset, "fset")
STATIC_STRING_IMPL(loads, "loads")
+STATIC_STRING_IMPL(multi, "multi")
+STATIC_STRING_IMPL(name, "name")
STATIC_STRING_IMPL(result, "result")
STATIC_STRING_IMPL(value, "value")
STATIC_STRING_IMPL(values, "values")
diff --git a/sources/shiboken2/libshiboken/sbkstaticstrings.h b/sources/shiboken2/libshiboken/sbkstaticstrings.h
index 09e22b395..b72fa989b 100644
--- a/sources/shiboken2/libshiboken/sbkstaticstrings.h
+++ b/sources/shiboken2/libshiboken/sbkstaticstrings.h
@@ -55,6 +55,8 @@ LIBSHIBOKEN_API PyObject *fset();
LIBSHIBOKEN_API PyObject *f_code();
LIBSHIBOKEN_API PyObject *f_lineno();
LIBSHIBOKEN_API PyObject *loads();
+LIBSHIBOKEN_API PyObject *multi();
+LIBSHIBOKEN_API PyObject *name();
LIBSHIBOKEN_API PyObject *result();
LIBSHIBOKEN_API PyObject *value();
LIBSHIBOKEN_API PyObject *values();
diff --git a/sources/shiboken2/libshiboken/signature/signature.cpp b/sources/shiboken2/libshiboken/signature/signature.cpp
index 76a71b00b..085d751aa 100644
--- a/sources/shiboken2/libshiboken/signature/signature.cpp
+++ b/sources/shiboken2/libshiboken/signature/signature.cpp
@@ -343,6 +343,9 @@ PyObject *PySide_BuildSignatureProps(PyObject *type_key)
empty_dict = PyDict_New();
return empty_dict;
}
+ // PYSIDE-1019: Build snake case versions of the functions.
+ if (insert_snake_case_variants(dict) < 0)
+ return nullptr;
// We replace the arguments by the result dict.
if (PyDict_SetItem(pyside_globals->arg_dict, type_key, dict) < 0)
return nullptr;
diff --git a/sources/shiboken2/libshiboken/signature/signature_helper.cpp b/sources/shiboken2/libshiboken/signature/signature_helper.cpp
index 7e92a9861..2b360c786 100644
--- a/sources/shiboken2/libshiboken/signature/signature_helper.cpp
+++ b/sources/shiboken2/libshiboken/signature/signature_helper.cpp
@@ -150,6 +150,28 @@ static PyObject *compute_name_key(PyObject *ob)
return Py_BuildValue("(OO)", type_key.object(), func_name.object());
}
+static PyObject *_func_with_new_name(PyTypeObject *type,
+ PyMethodDef *meth,
+ const char *new_name)
+{
+ /*
+ * Create a function with a lower case name.
+ * Note: This is similar to feature_select's methodWithNewName,
+ * but does not create a descriptor.
+ * XXX Maybe we can get rid of this, completely?
+ */
+ auto obtype = reinterpret_cast<PyObject *>(type);
+ int len = strlen(new_name);
+ auto name = new char[len + 1];
+ strcpy(name, new_name);
+ auto new_meth = new PyMethodDef;
+ new_meth->ml_name = name;
+ new_meth->ml_meth = meth->ml_meth;
+ new_meth->ml_flags = meth->ml_flags;
+ new_meth->ml_doc = meth->ml_doc;
+ return PyCFunction_NewEx(new_meth, obtype, nullptr);
+}
+
static int build_name_key_to_func(PyObject *obtype)
{
auto *type = reinterpret_cast<PyTypeObject *>(obtype);
@@ -167,6 +189,17 @@ static int build_name_key_to_func(PyObject *obtype)
|| PyDict_SetItem(pyside_globals->map_dict, name_key, func) < 0)
return -1;
}
+ // PYSIDE-1019: Now we repeat the same for snake case names.
+ meth = type->tp_methods;
+ for (; meth->ml_name != nullptr; meth++) {
+ const char *name = String::toCString(String::getSnakeCaseName(meth->ml_name, true));
+ AutoDecRef func(_func_with_new_name(type, meth, name));
+ AutoDecRef func_name(get_funcname(func));
+ AutoDecRef name_key(Py_BuildValue("(OO)", type_key.object(), func_name.object()));
+ if (func.isNull() || name_key.isNull()
+ || PyDict_SetItem(pyside_globals->map_dict, name_key, func) < 0)
+ return -1;
+ }
return 0;
}
@@ -198,6 +231,46 @@ PyObject *name_key_to_func(PyObject *ob)
return ret;
}
+static PyObject *_build_new_entry(PyObject *new_name, PyObject *value)
+{
+ PyObject *new_value = PyDict_Copy(value);
+ PyObject *multi = PyDict_GetItem(value, PyName::multi());
+ if (multi != nullptr && Py_TYPE(multi) == &PyList_Type) {
+ ssize_t len = PyList_Size(multi);
+ AutoDecRef list(PyList_New(len));
+ if (list.isNull())
+ return nullptr;
+ for (int idx = 0; idx < len; ++idx) {
+ auto multi_entry = PyList_GetItem(multi, idx);
+ auto dup = PyDict_Copy(multi_entry);
+ if (PyDict_SetItem(dup, PyName::name(), new_name) < 0)
+ return nullptr;
+ if (PyList_SetItem(list, idx, dup) < 0)
+ return nullptr;
+ }
+ if (PyDict_SetItem(new_value, PyName::multi(), list) < 0)
+ return nullptr;
+ } else {
+ if (PyDict_SetItem(new_value, PyName::name(), new_name) < 0)
+ return nullptr;
+ }
+ return new_value;
+}
+
+int insert_snake_case_variants(PyObject *dict)
+{
+ AutoDecRef snake_dict(PyDict_New());
+ PyObject *key, *value;
+ Py_ssize_t pos = 0;
+ while (PyDict_Next(dict, &pos, &key, &value)) {
+ AutoDecRef name(String::getSnakeCaseName(key, true));
+ AutoDecRef new_value(_build_new_entry(name, value));
+ if (PyDict_SetItem(snake_dict, name, new_value) < 0)
+ return -1;
+ }
+ return PyDict_Merge(dict, snake_dict, 0);
+}
+
PyObject *_get_class_of_cf(PyObject *ob_cf)
{
PyObject *selftype = PyCFunction_GET_SELF(ob_cf);
diff --git a/sources/shiboken2/libshiboken/signature/signature_p.h b/sources/shiboken2/libshiboken/signature/signature_p.h
index 9444f3e9b..ef7846472 100644
--- a/sources/shiboken2/libshiboken/signature/signature_p.h
+++ b/sources/shiboken2/libshiboken/signature/signature_p.h
@@ -95,6 +95,7 @@ PyObject *pyside_tp_get___doc__(PyObject *tp);
PyObject *_get_qualname(PyObject *ob);
int add_more_getsets(PyTypeObject *type, PyGetSetDef *gsp, PyObject **doc_descr);
PyObject *name_key_to_func(PyObject *ob);
+int insert_snake_case_variants(PyObject *dict);
PyObject *_get_class_of_cf(PyObject *ob_cf);
PyObject *_get_class_of_sm(PyObject *ob_sm);
PyObject *_get_class_of_descr(PyObject *ob);
diff --git a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/parser.py b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/parser.py
index 8a814114a..20c791cc1 100644
--- a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/parser.py
+++ b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/parser.py
@@ -349,7 +349,6 @@ def calculate_props(line):
props.annotations = annotations
props.varnames = varnames = tuple(tup[0] for tup in arglist)
funcname = parsed.funcname
- props.fullname = funcname
shortname = funcname[funcname.rindex(".")+1:]
props.name = shortname
props.multi = parsed.multi
@@ -366,7 +365,6 @@ def fix_variables(props, line):
if retvar and isinstance(retvar, (ResultVariable, ArrayLikeVariable)):
# Special case: a ResultVariable which is the result will always be an array!
annos["return"] = retvar = typing.List[retvar.type]
- fullname = props.fullname
varnames = list(props.varnames)
defaults = list(props.defaults)
diff = len(varnames) - len(defaults)
@@ -456,8 +454,7 @@ def pyside_type_init(type_key, sig_strings):
multi_props.append(props)
if multi > 0:
continue
- fullname = props.pop("fullname")
- multi_props = {"multi": multi_props, "fullname": fullname}
+ multi_props = {"multi": multi_props}
ret[shortname] = multi_props
dprint(multi_props)
multi_props = []
diff --git a/sources/shiboken2/tests/libother/otherobjecttype.cpp b/sources/shiboken2/tests/libother/otherobjecttype.cpp
index 1f782ecd8..c7778e7c9 100644
--- a/sources/shiboken2/tests/libother/otherobjecttype.cpp
+++ b/sources/shiboken2/tests/libother/otherobjecttype.cpp
@@ -40,7 +40,7 @@ int OtherObjectType::enumAsInt(SampleNamespace::SomeClass::PublicScopedEnum valu
return static_cast<int>(value);
}
-int OtherObjectType::enumAsIntForInvisibleNamespace(Invisible::EnumOnNamespace value)
+int OtherObjectType::enumAsIntForInvisibleNamespace(RemovedNamespace1::RemovedNamespace1_Enum value)
{
return static_cast<int>(value);
}
diff --git a/sources/shiboken2/tests/libother/otherobjecttype.h b/sources/shiboken2/tests/libother/otherobjecttype.h
index efd394347..a9362c370 100644
--- a/sources/shiboken2/tests/libother/otherobjecttype.h
+++ b/sources/shiboken2/tests/libother/otherobjecttype.h
@@ -36,13 +36,14 @@
#include "objecttype.h"
#include "collector.h"
#include "samplenamespace.h"
+#include "removednamespaces.h"
class LIBOTHER_API OtherObjectType : public ObjectType
{
public:
static int enumAsInt(SampleNamespace::SomeClass::PublicScopedEnum value);
- static int enumAsIntForInvisibleNamespace(Invisible::EnumOnNamespace value);
+ static int enumAsIntForInvisibleNamespace(RemovedNamespace1::RemovedNamespace1_Enum value);
};
diff --git a/sources/shiboken2/tests/libsample/removednamespaces.h b/sources/shiboken2/tests/libsample/removednamespaces.h
index c9732f8a6..9ad798bf7 100644
--- a/sources/shiboken2/tests/libsample/removednamespaces.h
+++ b/sources/shiboken2/tests/libsample/removednamespaces.h
@@ -34,10 +34,18 @@
namespace RemovedNamespace1
{
-enum RemovedNamespace1_Enum { RemovedNamespace1_Enum_Value0 };
+enum RemovedNamespace1_Enum { RemovedNamespace1_Enum_Value0 = 0,
+ RemovedNamespace1_Enum_Value1 = 1 };
enum { RemovedNamespace1_AnonymousEnum_Value0 };
+struct ObjectOnInvisibleNamespace
+{
+ bool exists() const { return true; }
+ static int toInt(RemovedNamespace1_Enum e) { return static_cast<int>(e); }
+ static ObjectOnInvisibleNamespace consume(const ObjectOnInvisibleNamespace &other) { return other; }
+};
+
namespace RemovedNamespace2
{
diff --git a/sources/shiboken2/tests/libsample/samplenamespace.h b/sources/shiboken2/tests/libsample/samplenamespace.h
index 0d418de16..5fe269c5e 100644
--- a/sources/shiboken2/tests/libsample/samplenamespace.h
+++ b/sources/shiboken2/tests/libsample/samplenamespace.h
@@ -41,25 +41,6 @@ enum {
AnonymousGlobalEnum_Value1
};
-// Invisible namespace
-namespace Invisible
-{
-
-enum EnumOnNamespace {
- Option1 = 1,
- Option2 = 2,
- Option3 = 3
-};
-
-struct ObjectOnInvisibleNamespace
-{
- bool exists() const { return true; }
- static int toInt(EnumOnNamespace e) { return static_cast<int>(e); }
- static ObjectOnInvisibleNamespace consume(const ObjectOnInvisibleNamespace &other) { return other; }
-};
-
-};
-
namespace SampleNamespace
{
diff --git a/sources/shiboken2/tests/libsample/virtualmethods.h b/sources/shiboken2/tests/libsample/virtualmethods.h
index 4937fab0d..4b2d25805 100644
--- a/sources/shiboken2/tests/libsample/virtualmethods.h
+++ b/sources/shiboken2/tests/libsample/virtualmethods.h
@@ -108,6 +108,10 @@ public:
virtual const Str & returnConstRef() const;
+protected:
+ // PYSIDE-1388: Protected hack with final classes (see VirtualFinalDaughter).
+ void protectedMethod() {}
+
private:
Str m_name;
int m_left;
diff --git a/sources/shiboken2/tests/samplebinding/CMakeLists.txt b/sources/shiboken2/tests/samplebinding/CMakeLists.txt
index ad52565ad..6bbfdb5bc 100644
--- a/sources/shiboken2/tests/samplebinding/CMakeLists.txt
+++ b/sources/shiboken2/tests/samplebinding/CMakeLists.txt
@@ -97,6 +97,7 @@ ${CMAKE_CURRENT_BINARY_DIR}/sample/rectf_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/sample/reference_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/sample/referentmodelindex_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/sample/toberenamedvalue_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/removednamespace1_objectoninvisiblenamespace_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/sample/renameduser_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/sample/sample_module_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/sample/sample_wrapper.cpp
@@ -127,7 +128,6 @@ ${CMAKE_CURRENT_BINARY_DIR}/sample/filter_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/sample/data_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/sample/intersection_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/sample/union_wrapper.cpp
-${CMAKE_CURRENT_BINARY_DIR}/sample/invisible_objectoninvisiblenamespace_wrapper.cpp
)
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/sample-binding.txt.in"
diff --git a/sources/shiboken2/tests/samplebinding/enumfromremovednamespace_test.py b/sources/shiboken2/tests/samplebinding/enumfromremovednamespace_test.py
index 4b0866c4e..168a609dc 100644
--- a/sources/shiboken2/tests/samplebinding/enumfromremovednamespace_test.py
+++ b/sources/shiboken2/tests/samplebinding/enumfromremovednamespace_test.py
@@ -38,15 +38,33 @@ from shiboken_paths import init_paths
init_paths()
import sample
+from shiboken_test_helper import objectFullname
+
class TestEnumFromRemovedNamespace(unittest.TestCase):
def testEnumPromotedToGlobal(self):
sample.RemovedNamespace1_Enum
- sample.RemovedNamespace1_Enum_Value0
+ self.assertEqual(sample.RemovedNamespace1_Enum_Value0, 0)
+ self.assertEqual(sample.RemovedNamespace1_Enum_Value1, 1)
sample.RemovedNamespace1_AnonymousEnum_Value0
sample.RemovedNamespace2_Enum
sample.RemovedNamespace2_Enum_Value0
+ def testNames(self):
+ # Test if invisible namespace does not appear on type name
+ self.assertEqual(objectFullname(sample.RemovedNamespace1_Enum),
+ "sample.RemovedNamespace1_Enum")
+ self.assertEqual(objectFullname(sample.ObjectOnInvisibleNamespace),
+ "sample.ObjectOnInvisibleNamespace")
+
+ # Function arguments
+ signature = sample.ObjectOnInvisibleNamespace.toInt.__signature__
+ self.assertEqual(objectFullname(signature.parameters['e'].annotation),
+ "sample.RemovedNamespace1_Enum")
+ signature = sample.ObjectOnInvisibleNamespace.consume.__signature__
+ self.assertEqual(objectFullname(signature.parameters['other'].annotation),
+ "sample.ObjectOnInvisibleNamespace")
+
def testEnumPromotedToUpperNamespace(self):
sample.UnremovedNamespace
sample.UnremovedNamespace.RemovedNamespace3_Enum
diff --git a/sources/shiboken2/tests/samplebinding/namespace_test.py b/sources/shiboken2/tests/samplebinding/namespace_test.py
index 8171e0e43..807e7bfc9 100644
--- a/sources/shiboken2/tests/samplebinding/namespace_test.py
+++ b/sources/shiboken2/tests/samplebinding/namespace_test.py
@@ -43,20 +43,15 @@ from sample import *
from shiboken_test_helper import objectFullname
+# For tests of invisible namespaces, see
+# enumfromremovednamespace_test.py / removednamespaces.h
+
+
class TestVariablesUnderNamespace(unittest.TestCase):
def testIt(self):
self.assertEqual(SampleNamespace.variableInNamespace, 42)
-class TestEnumUnderNamespace(unittest.TestCase):
- def testInvisibleNamespace(self):
- o1 = EnumOnNamespace.Option1
- self.assertEqual(o1, 1)
- def testTpNames(self):
- self.assertEqual(objectFullname(EnumOnNamespace), "sample.EnumOnNamespace")
- self.assertEqual(str(EnumOnNamespace.Option1),
- "sample.EnumOnNamespace.Option1")
-
class TestClassesUnderNamespace(unittest.TestCase):
def testIt(self):
c1 = SampleNamespace.SomeClass()
@@ -87,14 +82,7 @@ class TestClassesUnderNamespace(unittest.TestCase):
"sample.SampleNamespace.InValue")
self.assertEqual(objectFullname(SampleNamespace.enumAsInt.__signature__.parameters['value'].annotation),
"sample.SampleNamespace.SomeClass.PublicScopedEnum")
- self.assertEqual(objectFullname(ObjectOnInvisibleNamespace.toInt.__signature__.parameters['e'].annotation),
- "sample.EnumOnNamespace")
- # Test if enum on namespace that was marked as not gerenated does not appear on type name
- self.assertEqual(objectFullname(ObjectOnInvisibleNamespace),
- "sample.ObjectOnInvisibleNamespace")
- self.assertEqual(objectFullname(ObjectOnInvisibleNamespace.consume.__signature__.parameters['other'].annotation),
- "sample.ObjectOnInvisibleNamespace")
if __name__ == '__main__':
unittest.main()
diff --git a/sources/shiboken2/tests/samplebinding/typesystem_sample.xml b/sources/shiboken2/tests/samplebinding/typesystem_sample.xml
index fdddb80f2..e4963721b 100644
--- a/sources/shiboken2/tests/samplebinding/typesystem_sample.xml
+++ b/sources/shiboken2/tests/samplebinding/typesystem_sample.xml
@@ -536,11 +536,6 @@
<enum-type identified-by-value="AnonymousGlobalEnum_Value0"/>
- <namespace-type name="Invisible" visible="no">
- <enum-type name="EnumOnNamespace" />
- <value-type name="ObjectOnInvisibleNamespace" />
- </namespace-type>
-
<namespace-type name="SampleNamespace">
<enum-type name="Option"/>
<enum-type name="InValue"/>
@@ -603,6 +598,7 @@
<namespace-type name="RemovedNamespace1" visible='false'>
<enum-type name="RemovedNamespace1_Enum" />
+ <value-type name="ObjectOnInvisibleNamespace" />
<namespace-type name="RemovedNamespace2" visible='false'>
<enum-type name="RemovedNamespace2_Enum" />
</namespace-type>