aboutsummaryrefslogtreecommitdiffstats
path: root/sources/shiboken2
diff options
context:
space:
mode:
Diffstat (limited to 'sources/shiboken2')
-rw-r--r--sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp7
-rw-r--r--sources/shiboken2/ApiExtractor/abstractmetalang.cpp12
-rw-r--r--sources/shiboken2/ApiExtractor/abstractmetalang.h8
-rw-r--r--sources/shiboken2/ApiExtractor/qtdocparser.cpp36
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testmodifydocumentation.cpp7
-rw-r--r--sources/shiboken2/CMakeLists.txt29
-rw-r--r--sources/shiboken2/doc/typesystem_codeinjection.rst20
-rw-r--r--sources/shiboken2/doc/typesystem_conversionrule.rst4
-rw-r--r--sources/shiboken2/doc/typesystem_variables.rst12
-rw-r--r--sources/shiboken2/generator/qtdoc/qtdocgenerator.cpp33
-rw-r--r--sources/shiboken2/generator/shiboken2/cppgenerator.cpp59
-rw-r--r--sources/shiboken2/generator/shiboken2/cppgenerator.h3
-rw-r--r--sources/shiboken2/libshiboken/CMakeLists.txt24
-rw-r--r--sources/shiboken2/libshiboken/embed/embedding_generator.py22
-rw-r--r--sources/shiboken2/libshiboken/sbkarrayconverter.cpp1
-rw-r--r--sources/shiboken2/libshiboken/shibokenbuffer.cpp23
-rw-r--r--sources/shiboken2/libshiboken/shibokenbuffer.h8
-rw-r--r--sources/shiboken2/libshiboken/signature/signature.cpp2
-rw-r--r--sources/shiboken2/shiboken_version.py2
-rw-r--r--sources/shiboken2/shibokenmodule/CMakeLists.txt37
-rw-r--r--sources/shiboken2/shibokenmodule/files.dir/shibokensupport/feature.py (renamed from sources/shiboken2/shibokenmodule/files.dir/shibokensupport/__feature__.py)0
-rw-r--r--sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/lib/enum_sig.py2
-rw-r--r--sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/loader.py27
-rw-r--r--sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/mapping.py4
-rw-r--r--sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/parser.py16
25 files changed, 277 insertions, 121 deletions
diff --git a/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp b/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp
index 05f9cf203..d7ae45ae3 100644
--- a/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp
+++ b/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp
@@ -3088,8 +3088,11 @@ AbstractMetaClassList AbstractMetaBuilderPrivate::classesTopologicalSorted(const
// Member fields need to be initialized
const AbstractMetaFieldList &fields = clazz->fields();
for (AbstractMetaField *field : fields) {
- addClassDependency(field->type()->typeEntry(), clazz, classIndex,
- map, &graph);
+ auto typeEntry = field->type()->typeEntry();
+ if (typeEntry->isEnum()) // Enum defined in class?
+ typeEntry = typeEntry->parent();
+ if (typeEntry != nullptr)
+ addClassDependency(typeEntry, clazz, classIndex, map, &graph);
}
}
diff --git a/sources/shiboken2/ApiExtractor/abstractmetalang.cpp b/sources/shiboken2/ApiExtractor/abstractmetalang.cpp
index f1f01e02c..723a13164 100644
--- a/sources/shiboken2/ApiExtractor/abstractmetalang.cpp
+++ b/sources/shiboken2/ApiExtractor/abstractmetalang.cpp
@@ -2123,6 +2123,12 @@ AbstractMetaField *AbstractMetaClass::findField(const QString &name) const
return AbstractMetaField::find(m_fields, name);
}
+bool AbstractMetaClass::hasStaticFields() const
+{
+ return std::any_of(m_fields.cbegin(), m_fields.cend(),
+ [](const AbstractMetaField *f) { return f->isStatic(); });
+}
+
AbstractMetaEnum *AbstractMetaClass::findEnum(const QString &enumName)
{
if (AbstractMetaEnum *e = findByName(m_enums, enumName))
@@ -2171,6 +2177,11 @@ void AbstractMetaClass::getFunctionsFromInvisibleNamespacesToBeGenerated(Abstrac
}
}
+QString AbstractMetaClass::fullName() const
+{
+ return package() + QLatin1Char('.') + m_typeEntry->targetLangName();
+}
+
static void addExtraIncludeForType(AbstractMetaClass *metaClass, const AbstractMetaType *type)
{
if (!type)
@@ -2742,4 +2753,3 @@ QString AbstractMetaEnum::package() const
{
return m_typeEntry->targetLangPackage();
}
-
diff --git a/sources/shiboken2/ApiExtractor/abstractmetalang.h b/sources/shiboken2/ApiExtractor/abstractmetalang.h
index c100c63a1..8a0363f4c 100644
--- a/sources/shiboken2/ApiExtractor/abstractmetalang.h
+++ b/sources/shiboken2/ApiExtractor/abstractmetalang.h
@@ -84,6 +84,7 @@ public:
Format fmt = Documentation::Native);
bool isEmpty() const;
+ bool hasBrief() const { return m_data.contains(Brief); }
QString value(Type t = Documentation::Detailed) const;
void setValue(const QString& value, Type t = Documentation::Detailed,
@@ -1424,6 +1425,8 @@ public:
AbstractMetaField *findField(const QString &name) const;
+ bool hasStaticFields() const;
+
const AbstractMetaEnumList &enums() const { return m_enums; }
void setEnums(const AbstractMetaEnumList &enums)
{
@@ -1442,10 +1445,7 @@ public:
void getFunctionsFromInvisibleNamespacesToBeGenerated(AbstractMetaFunctionList *funcList) const;
- QString fullName() const
- {
- return package() + QLatin1Char('.') + name();
- }
+ QString fullName() const;
/**
* Retrieves the class name without any namespace/scope information.
diff --git a/sources/shiboken2/ApiExtractor/qtdocparser.cpp b/sources/shiboken2/ApiExtractor/qtdocparser.cpp
index d439b3fd5..1aeab85ed 100644
--- a/sources/shiboken2/ApiExtractor/qtdocparser.cpp
+++ b/sources/shiboken2/ApiExtractor/qtdocparser.cpp
@@ -41,6 +41,9 @@
#include <QtCore/QXmlStreamReader>
#include <QUrl>
+static inline QString briefStartElement() { return QStringLiteral("<brief>"); }
+static inline QString briefEndElement() { return QStringLiteral("</brief>"); }
+
Documentation QtDocParser::retrieveModuleDocumentation()
{
return retrieveModuleDocumentation(packageName());
@@ -206,6 +209,25 @@ QString QtDocParser::queryFunctionDocumentation(const QString &sourceFileName,
return result;
}
+// Extract the <brief> section from a WebXML (class) documentation and remove it
+// from the source.
+static QString extractBrief(QString *value)
+{
+ const auto briefStart = value->indexOf(briefStartElement());
+ if (briefStart < 0)
+ return {};
+ const auto briefEnd = value->indexOf(briefEndElement(),
+ briefStart + briefStartElement().size());
+ if (briefEnd < briefStart)
+ return {};
+ const auto briefLength = briefEnd + briefEndElement().size() - briefStart;
+ QString briefValue = value->mid(briefStart, briefLength);
+ briefValue.insert(briefValue.size() - briefEndElement().size(),
+ QLatin1String("<rst> More_...</rst>"));
+ value->remove(briefStart, briefLength);
+ return briefValue;
+}
+
void QtDocParser::fillDocumentation(AbstractMetaClass* metaClass)
{
if (!metaClass)
@@ -257,9 +279,17 @@ void QtDocParser::fillDocumentation(AbstractMetaClass* metaClass)
signedModifs.append(docModif);
}
- Documentation doc(getDocumentation(xquery, query, classModifs));
- if (doc.isEmpty())
- qCWarning(lcShibokenDoc, "%s", qPrintable(msgCannotFindDocumentation(sourceFileName, "class", className, query)));
+ QString docString = getDocumentation(xquery, query, classModifs);
+ if (docString.isEmpty()) {
+ qCWarning(lcShibokenDoc, "%s",
+ qPrintable(msgCannotFindDocumentation(sourceFileName, "class", className, query)));
+ }
+ const QString brief = extractBrief(&docString);
+
+ Documentation doc;
+ if (!brief.isEmpty())
+ doc.setValue(brief, Documentation::Brief);
+ doc.setValue(docString);
metaClass->setDocumentation(doc);
//Functions Documentation
diff --git a/sources/shiboken2/ApiExtractor/tests/testmodifydocumentation.cpp b/sources/shiboken2/ApiExtractor/tests/testmodifydocumentation.cpp
index 6acac41d5..cf3982a18 100644
--- a/sources/shiboken2/ApiExtractor/tests/testmodifydocumentation.cpp
+++ b/sources/shiboken2/ApiExtractor/tests/testmodifydocumentation.cpp
@@ -72,13 +72,14 @@ R"(<typesystem package="Foo">
docParser.setDocumentationDataDirectory(tempDir.path());
docParser.fillDocumentation(classA);
- const QString actualDocSimplified = classA->documentation().value().simplified();
+ const Documentation &doc = classA->documentation();
+ const QString actualDocSimplified = doc.value(Documentation::Detailed).simplified();
+ const QString actualBriefSimplified = doc.value(Documentation::Brief).simplified();
QVERIFY(!actualDocSimplified.isEmpty());
const char expectedDoc[] =
R"(<?xml version="1.0"?>
<description>oi
-<brief>Modified Brief</brief>
<para>Paragraph number 1</para>
<para>Paragraph number 2</para>
<para>Some changed contents here</para>
@@ -86,7 +87,7 @@ R"(<?xml version="1.0"?>
)";
const QString expectedDocSimplified = QString::fromLatin1(expectedDoc).simplified();
// Check whether the first modification worked.
- QVERIFY(actualDocSimplified.contains(QLatin1String("Modified Brief")));
+ QVERIFY(actualBriefSimplified.contains(QLatin1String("Modified Brief")));
#ifndef HAVE_LIBXSLT
// QtXmlPatterns is unable to handle para[3] in style sheets,
diff --git a/sources/shiboken2/CMakeLists.txt b/sources/shiboken2/CMakeLists.txt
index 3de5d3223..8b626af09 100644
--- a/sources/shiboken2/CMakeLists.txt
+++ b/sources/shiboken2/CMakeLists.txt
@@ -197,6 +197,35 @@ if(CMAKE_BUILD_TYPE STREQUAL "Debug")
endif()
######################################################################
+## Define the Python files involved in the build process.
+##
+## They are installed into the file system (see shibokenmodule)
+## and embedded into the libshiboken binary through a .zip file.
+######################################################################
+
+set(shiboken_python_files
+ "signature/lib/__init__.py"
+ "signature/lib/enum_sig.py"
+ "signature/lib/tool.py"
+ "signature/__init__.py"
+ "signature/errorhandler.py"
+ "signature/importhandler.py"
+ "signature/layout.py"
+ "signature/loader.py"
+ "signature/mapping.py"
+ "signature/parser.py"
+ "__init__.py"
+ "feature.py"
+ )
+
+if (PYTHON_VERSION_MAJOR LESS 3)
+ list(APPEND shiboken_python_files
+ "backport_inspect.py"
+ "typing27.py"
+ )
+endif()
+
+######################################################################
# Adding sub directories to build
######################################################################
add_subdirectory(ApiExtractor)
diff --git a/sources/shiboken2/doc/typesystem_codeinjection.rst b/sources/shiboken2/doc/typesystem_codeinjection.rst
index b0d5f3851..836609508 100644
--- a/sources/shiboken2/doc/typesystem_codeinjection.rst
+++ b/sources/shiboken2/doc/typesystem_codeinjection.rst
@@ -112,7 +112,8 @@ Below is the example C++ class for whom wrapper code will be generated.
.. code-block:: c++
- class InjectCode {
+ class InjectCode
+ {
public:
InjectCode();
double overloadedMethod(int arg);
@@ -124,6 +125,10 @@ From the C++ class, |project| will generate a ``injectcode_wrapper.cpp`` file
with the binding code. The next section will use a simplified version of the
generated wrapper code with the injection spots marked with comments.
+There are a number of placeholders indicated by a percent sign ``%``, which
+will be expanded when inserting the code. For a list, see
+:ref:`typesystemvariables`.
+
Noteworthy Cases
----------------
@@ -196,7 +201,7 @@ class is polymorphic.
int InjectCodeWrapper::virtualMethod(int arg)
{
- PyObject* method = BindingManager::instance().getOverride(this, "virtualMethod");
+ PyObject *method = BindingManager::instance().getOverride(this, "virtualMethod");
if (!py_override)
return this->InjectCode::virtualMethod(arg);
@@ -228,10 +233,9 @@ own ``beginning`` and ``end`` code injections.
.. code-block:: c++
- static PyObject*
- PyInjectCode_overloadedMethod(PyObject* self, PyObject* arg)
+ static PyObject *PyInjectCode_overloadedMethod(PyObject *self, PyObject *arg)
{
- PyObject* py_result = 0;
+ PyObject* py_result{};
if (PyFloat_Check(arg)) {
double cpp_arg0 = Shiboken::Converter<double >::toCpp(arg);
@@ -250,13 +254,13 @@ own ``beginning`` and ``end`` code injections.
} else goto PyInjectCode_overloadedMethod_TypeError;
if (PyErr_Occurred() || !py_result)
- return 0;
+ return {};
return py_result;
PyInjectCode_overloadedMethod_TypeError:
PyErr_SetString(PyExc_TypeError, "'overloadedMethod()' called with wrong parameters.");
- return 0;
+ return {};
}
@@ -371,7 +375,7 @@ to prevent bad custom code to pass unnoticed.
// INJECT-CODE: <typesystem><inject-code class="target" position="beginning">
// Uses: do something before the module is created.
- PyObject* module = Py_InitModule("MODULENAME", MODULENAME_methods);
+ PyObject *module = Py_InitModule("MODULENAME", MODULENAME_methods);
(... initialization of wrapped classes, namespaces, functions and enums ...)
diff --git a/sources/shiboken2/doc/typesystem_conversionrule.rst b/sources/shiboken2/doc/typesystem_conversionrule.rst
index 27e7a72de..fc87a85c9 100644
--- a/sources/shiboken2/doc/typesystem_conversionrule.rst
+++ b/sources/shiboken2/doc/typesystem_conversionrule.rst
@@ -32,6 +32,10 @@ conversion-rule
</conversion-rule>
</value-type>
+ The code can be inserted directly, via ``add-conversion`` (providing snippet
+ functionality) or via ``insert-template`` (XML template,
+ see :ref:`using-code-templates`).
+
The example above show the structure of a complete conversion rule. Each of the
child tags comprising the conversion rule are described in their own sections
below.
diff --git a/sources/shiboken2/doc/typesystem_variables.rst b/sources/shiboken2/doc/typesystem_variables.rst
index 73d4dd12c..3d4638253 100644
--- a/sources/shiboken2/doc/typesystem_variables.rst
+++ b/sources/shiboken2/doc/typesystem_variables.rst
@@ -1,3 +1,5 @@
+.. _typesystemvariables:
+
*********************
Type System Variables
*********************
@@ -24,9 +26,9 @@ Variables
.. _arg_number:
-**%#**
+**%<number>**
- Replaced by the name of a C++ argument in the position indicated by ``#``.
+ Replaced by the name of a C++ argument in the position indicated by ``<number>``.
The argument counting starts with ``%1``, since ``%0`` represents the return
variable name. If the number indicates a variable that was removed in the
type system description, but there is a default value for it, this value will
@@ -214,13 +216,13 @@ Variables
.. _pyarg:
-**%PYARG_#**
+**%PYARG_<number>**
- Similar to ``%#``, but is replaced by the Python arguments (PyObjects)
+ Similar to ``%<number>``, but is replaced by the Python arguments (PyObjects)
received by the Python wrapper method.
If used in the context of a native code injection, i.e. in a virtual method
- override, ``%PYARG_#`` will be translated to one item of the Python tuple
+ override, ``%PYARG_<number>`` will be translated to one item of the Python tuple
holding the arguments that should be passed to the Python override for this
virtual method.
diff --git a/sources/shiboken2/generator/qtdoc/qtdocgenerator.cpp b/sources/shiboken2/generator/qtdoc/qtdocgenerator.cpp
index 5e75cbf87..d330d8c18 100644
--- a/sources/shiboken2/generator/qtdoc/qtdocgenerator.cpp
+++ b/sources/shiboken2/generator/qtdoc/qtdocgenerator.cpp
@@ -1588,30 +1588,6 @@ static void writeInheritedByList(QTextStream& s, const AbstractMetaClass* metaCl
s << classes.join(QLatin1String(", ")) << Qt::endl << Qt::endl;
}
-// Extract the <brief> section from a WebXML (class) documentation and remove it
-// from the source.
-static bool extractBrief(Documentation *sourceDoc, Documentation *brief)
-{
- if (sourceDoc->format() != Documentation::Native)
- return false;
- QString value = sourceDoc->value();
- const int briefStart = value.indexOf(briefStartElement());
- if (briefStart < 0)
- return false;
- const int briefEnd = value.indexOf(briefEndElement(), briefStart + briefStartElement().size());
- if (briefEnd < briefStart)
- return false;
- const int briefLength = briefEnd + briefEndElement().size() - briefStart;
- brief->setFormat(Documentation::Native);
- QString briefValue = value.mid(briefStart, briefLength);
- briefValue.insert(briefValue.size() - briefEndElement().size(),
- QLatin1String("<rst> More_...</rst>"));
- brief->setValue(briefValue);
- value.remove(briefStart, briefLength);
- sourceDoc->setValue(value);
- return true;
-}
-
void QtDocGenerator::generateClass(QTextStream &s, const GeneratorContext &classContext)
{
const AbstractMetaClass *metaClass = classContext.metaClass();
@@ -1630,9 +1606,8 @@ void QtDocGenerator::generateClass(QTextStream &s, const GeneratorContext &class
s << Pad('*', className.count()) << Qt::endl << Qt::endl;
auto documentation = metaClass->documentation();
- Documentation brief;
- if (extractBrief(&documentation, &brief))
- writeFormattedText(s, brief.value(), metaClass);
+ if (documentation.hasBrief())
+ writeFormattedText(s, documentation.value(Documentation::Brief), metaClass);
s << ".. inheritance-diagram:: " << metaClass->fullName() << Qt::endl
<< " :parts: 2" << Qt::endl << Qt::endl;
@@ -1659,7 +1634,7 @@ void QtDocGenerator::generateClass(QTextStream &s, const GeneratorContext &class
writeInjectDocumentation(s, TypeSystem::DocModificationPrepend, metaClass, nullptr);
if (!writeInjectDocumentation(s, TypeSystem::DocModificationReplace, metaClass, nullptr))
- writeFormattedText(s, documentation.value(), metaClass);
+ writeFormattedText(s, documentation.value(Documentation::Detailed), metaClass);
if (!metaClass->isNamespace())
writeConstructors(s, metaClass);
@@ -1972,7 +1947,7 @@ bool QtDocGenerator::writeInjectDocumentation(QTextStream& s,
continue;
doc.setValue(mod.code(), Documentation::Detailed, fmt);
- writeFormattedText(s, doc.value(), cppClass);
+ writeFormattedText(s, doc, cppClass);
didSomething = true;
}
}
diff --git a/sources/shiboken2/generator/shiboken2/cppgenerator.cpp b/sources/shiboken2/generator/shiboken2/cppgenerator.cpp
index c84557180..9739dfef6 100644
--- a/sources/shiboken2/generator/shiboken2/cppgenerator.cpp
+++ b/sources/shiboken2/generator/shiboken2/cppgenerator.cpp
@@ -762,6 +762,9 @@ void CppGenerator::generateClass(QTextStream &s, const GeneratorContext &classCo
writeConverterFunctions(s, metaClass, classContext);
writeClassRegister(s, metaClass, classContext, signatureStream);
+ if (metaClass->hasStaticFields())
+ writeStaticFieldInitialization(s, metaClass);
+
// class inject-code native/end
if (!metaClass->typeEntry()->codeSnips().isEmpty()) {
writeClassCodeSnips(s, metaClass->typeEntry()->codeSnips(),
@@ -5281,6 +5284,12 @@ QString CppGenerator::getSimpleClassInitFunctionName(const AbstractMetaClass *me
return initFunctionName;
}
+QString CppGenerator::getSimpleClassStaticFieldsInitFunctionName(const AbstractMetaClass *metaClass) const
+{
+ return QLatin1String("init_") + getSimpleClassInitFunctionName(metaClass)
+ + QLatin1String("StaticFields");
+}
+
QString CppGenerator::getInitFunctionName(const GeneratorContext &context) const
{
return !context.forSmartPointer()
@@ -5483,18 +5492,6 @@ void CppGenerator::writeClassRegister(QTextStream &s,
if (metaClass->hasSignals())
writeSignalInitialization(s, metaClass);
- // Write static fields
- const AbstractMetaFieldList &fields = metaClass->fields();
- for (const AbstractMetaField *field : fields) {
- if (!field->isStatic())
- continue;
- s << INDENT << QLatin1String("PyDict_SetItemString(reinterpret_cast<PyTypeObject *>(") + cpythonTypeName(metaClass) + QLatin1String(")->tp_dict, \"");
- s << field->name() << "\", ";
- writeToPythonConversion(s, field->type(), metaClass, metaClass->qualifiedCppName() + QLatin1String("::") + field->name());
- s << ");\n";
- }
- s << Qt::endl;
-
// class inject-code target/end
if (!classTypeEntry->codeSnips().isEmpty()) {
s << Qt::endl;
@@ -5524,6 +5521,29 @@ void CppGenerator::writeClassRegister(QTextStream &s,
s << "}\n";
}
+void CppGenerator::writeStaticFieldInitialization(QTextStream &s,
+ const AbstractMetaClass *metaClass)
+{
+ s << "\nvoid " << getSimpleClassStaticFieldsInitFunctionName(metaClass)
+ << "()\n{\n" << INDENT << "auto dict = reinterpret_cast<PyTypeObject *>("
+ << cpythonTypeName(metaClass) << ")->tp_dict;\n";
+ const auto &fields = metaClass->fields();
+ for (const AbstractMetaField *field : fields) {
+ if (field->isStatic()) {
+ QString cppName = field->originalName();
+ if (cppName.isEmpty())
+ cppName = field->name();
+ const QString name = field->enclosingClass()->qualifiedCppName()
+ + QLatin1String("::") + cppName;
+ s << INDENT << "PyDict_SetItemString(dict, \"" << field->name()
+ << "\",\n" << INDENT << " ";
+ writeToPythonConversion(s, field->type(), metaClass, name);
+ s << ");\n";
+ }
+ }
+ s << "\n}\n";
+}
+
void CppGenerator::writeInitQtMetaTypeFunctionBody(QTextStream &s, const GeneratorContext &context) const
{
const AbstractMetaClass *metaClass = context.metaClass();
@@ -5934,11 +5954,18 @@ bool CppGenerator::finishGeneration()
}
const AbstractMetaClassList lst = classesTopologicalSorted(additionalDependencies);
+ QVector<const AbstractMetaClass *> classesWithStaticFields;
+
for (const AbstractMetaClass *cls : lst){
if (shouldGenerate(cls)) {
writeInitFunc(s_classInitDecl, s_classPythonDefines, INDENT,
getSimpleClassInitFunctionName(cls),
cls->typeEntry()->targetLangEnclosingEntry());
+ if (cls->hasStaticFields()) {
+ s_classInitDecl << "void "
+ << getSimpleClassStaticFieldsInitFunctionName(cls) << "();\n";
+ classesWithStaticFields.append(cls);
+ }
}
}
@@ -6240,6 +6267,14 @@ bool CppGenerator::finishGeneration()
s << INDENT << "Shiboken::Module::registerTypes(module, " << cppApiVariableName() << ");\n";
s << INDENT << "Shiboken::Module::registerTypeConverters(module, " << convertersVariableName() << ");\n";
+ // Static fields are registered last since they may use converter functions
+ // of the previously registered types (PYSIDE-1529).
+ if (!classesWithStaticFields.isEmpty()) {
+ s << "\n// Static field initialization\n";
+ for (auto cls : qAsConst(classesWithStaticFields))
+ s << getSimpleClassStaticFieldsInitFunctionName(cls) << "();\n";
+ }
+
s << '\n' << INDENT << "if (PyErr_Occurred()) {\n" << indent(INDENT)
<< INDENT << "PyErr_Print();\n"
<< INDENT << "Py_FatalError(\"can't initialize module " << moduleName() << "\");\n"
diff --git a/sources/shiboken2/generator/shiboken2/cppgenerator.h b/sources/shiboken2/generator/shiboken2/cppgenerator.h
index 25bb51ef5..64396d61f 100644
--- a/sources/shiboken2/generator/shiboken2/cppgenerator.h
+++ b/sources/shiboken2/generator/shiboken2/cppgenerator.h
@@ -257,6 +257,7 @@ private:
QString getInitFunctionName(const GeneratorContext &context) const;
QString getSimpleClassInitFunctionName(const AbstractMetaClass *metaClass) const;
+ QString getSimpleClassStaticFieldsInitFunctionName(const AbstractMetaClass *metaClass) const;
void writeSignatureStrings(QTextStream &s, QTextStream &signatureStream,
const QString &arrayName,
@@ -265,6 +266,8 @@ private:
const AbstractMetaClass *metaClass,
const GeneratorContext &classContext,
QTextStream &signatureStream);
+ void writeStaticFieldInitialization(QTextStream &s,
+ const AbstractMetaClass *metaClass);
void writeClassDefinition(QTextStream &s,
const AbstractMetaClass *metaClass,
const GeneratorContext &classContext);
diff --git a/sources/shiboken2/libshiboken/CMakeLists.txt b/sources/shiboken2/libshiboken/CMakeLists.txt
index 45b41fd13..96effd280 100644
--- a/sources/shiboken2/libshiboken/CMakeLists.txt
+++ b/sources/shiboken2/libshiboken/CMakeLists.txt
@@ -29,13 +29,35 @@ configure_file("${CMAKE_CURRENT_SOURCE_DIR}/sbkversion.h.in"
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/embed/signature_bootstrap.py"
"${CMAKE_CURRENT_BINARY_DIR}/embed/signature_bootstrap.py" @ONLY)
+# Variable from enclosing scope.
+# list(TRANSFORM shiboken_python_files
+# PREPEND "${CMAKE_CURRENT_SOURCE_DIR}/../shibokenmodule/files.dir/shibokensupport/"
+# OUTPUT_VARIABLE embedded_shiboken_files)
+# Replacement for CMake version < 3.12:
+set(embedded_shiboken_files "")
+foreach(item IN LISTS shiboken_python_files)
+ list(APPEND embedded_shiboken_files
+ "${CMAKE_CURRENT_SOURCE_DIR}/../shibokenmodule/files.dir/shibokensupport/${item}")
+endforeach()
+
+if (QUIET_BUILD)
+ set(embedding_option "--quiet")
+else()
+ set(embedding_option "")
+endif()
+
add_custom_command(
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/embed/signature_bootstrap_inc.h"
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/embed/signature_inc.h"
COMMAND ${PYTHON_EXECUTABLE} -E
"${CMAKE_CURRENT_SOURCE_DIR}/embed/embedding_generator.py"
--cmake-dir "${CMAKE_CURRENT_BINARY_DIR}/embed"
- --limited-api ${PYTHON_LIMITED_API})
+ --limited-api ${PYTHON_LIMITED_API}
+ ${embedding_option}
+ DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/embed/embedding_generator.py"
+ "${CMAKE_CURRENT_SOURCE_DIR}/embed/signature_bootstrap.py"
+ ${embedded_shiboken_files}
+ )
set(libshiboken_MAJOR_VERSION ${shiboken_MAJOR_VERSION})
set(libshiboken_MINOR_VERSION ${shiboken_MINOR_VERSION})
diff --git a/sources/shiboken2/libshiboken/embed/embedding_generator.py b/sources/shiboken2/libshiboken/embed/embedding_generator.py
index 15f63649b..a9a58ee07 100644
--- a/sources/shiboken2/libshiboken/embed/embedding_generator.py
+++ b/sources/shiboken2/libshiboken/embed/embedding_generator.py
@@ -82,7 +82,7 @@ def runpy(cmd, **kw):
subprocess.call([sys.executable, '-E'] + cmd.split(), **kw)
-def create_zipfile(limited_api):
+def create_zipfile(limited_api, quiet):
"""
Collect all Python files, compile them, create a zip file
and make a chunked base64 encoded file from it.
@@ -129,11 +129,28 @@ def create_zipfile(limited_api):
with open(inc_name, "w") as inc:
_embed_file(tmp, inc)
tmp.close()
+
# also generate a simple embeddable .pyc file for signature_bootstrap.pyc
boot_name = "signature_bootstrap.py" if limited_api else "signature_bootstrap.pyc"
with open(boot_name, "rb") as ldr, open("signature_bootstrap_inc.h", "w") as inc:
_embed_bytefile(ldr, inc, limited_api)
os.chdir(cur_dir)
+ if quiet:
+ return
+
+ # have a look at our populated folder unless quiet option
+ def list_files(startpath):
+ for root, dirs, files in os.walk(startpath):
+ level = root.replace(startpath, '').count(os.sep)
+ indent = ' ' * 4 * (level)
+ print('+ {}{}/'.format(indent, os.path.basename(root)))
+ subindent = ' ' * 4 * (level + 1)
+ for f in files:
+ print('+ {}{}'.format(subindent, f))
+
+ print("++++ Current contents of")
+ list_files(work_dir)
+ print("++++")
def _embed_file(fin, fout):
@@ -236,7 +253,8 @@ if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument('--cmake-dir', nargs="?")
parser.add_argument('--limited-api', type=str2bool)
+ parser.add_argument('--quiet', action='store_true')
args = parser.parse_args()
if args.cmake_dir:
work_dir = os.path.abspath(args.cmake_dir)
- create_zipfile(args.limited_api)
+ create_zipfile(args.limited_api, args.quiet)
diff --git a/sources/shiboken2/libshiboken/sbkarrayconverter.cpp b/sources/shiboken2/libshiboken/sbkarrayconverter.cpp
index fd09efdae..b828aa8e0 100644
--- a/sources/shiboken2/libshiboken/sbkarrayconverter.cpp
+++ b/sources/shiboken2/libshiboken/sbkarrayconverter.cpp
@@ -90,7 +90,6 @@ SbkArrayConverter *createArrayConverter(IsArrayConvertibleToCppFunc toCppCheckFu
static PythonToCppFunc unimplementedArrayCheck(PyObject *, int, int)
{
- warning(PyExc_RuntimeWarning, 0, "SbkConverter: Unimplemented C++ array type.");
return nullptr;
}
diff --git a/sources/shiboken2/libshiboken/shibokenbuffer.cpp b/sources/shiboken2/libshiboken/shibokenbuffer.cpp
index dd6e46320..8d44878ac 100644
--- a/sources/shiboken2/libshiboken/shibokenbuffer.cpp
+++ b/sources/shiboken2/libshiboken/shibokenbuffer.cpp
@@ -74,6 +74,29 @@ void *Shiboken::Buffer::getPointer(PyObject *pyObj, Py_ssize_t *size)
return const_cast<void *>(buffer);
}
+void *Shiboken::Buffer::copyData(PyObject *pyObj, Py_ssize_t *sizeIn)
+{
+ void *result = nullptr;
+ Py_ssize_t size = 0;
+
+ Py_buffer view;
+ if (PyObject_GetBuffer(pyObj, &view, PyBUF_ND) == 0) {
+ size = view.len;
+ if (size) {
+ result = std::malloc(size);
+ if (result != nullptr)
+ std::memcpy(result, view.buf, size);
+ else
+ size = 0;
+ }
+ PyBuffer_Release(&view);
+ }
+
+ if (sizeIn != nullptr)
+ *sizeIn = size;
+ return result;
+}
+
PyObject *Shiboken::Buffer::newObject(void *memory, Py_ssize_t size, Type type)
{
if (size == 0)
diff --git a/sources/shiboken2/libshiboken/shibokenbuffer.h b/sources/shiboken2/libshiboken/shibokenbuffer.h
index dc9f8d89f..512d9db4d 100644
--- a/sources/shiboken2/libshiboken/shibokenbuffer.h
+++ b/sources/shiboken2/libshiboken/shibokenbuffer.h
@@ -79,6 +79,14 @@ namespace Buffer
*/
LIBSHIBOKEN_API void *getPointer(PyObject *pyObj, Py_ssize_t *size = nullptr);
+ /**
+ * Returns a copy of the buffer data which should be free'd.
+ *
+ * If the \p pyObj is a non-contiguous buffer a Python error is set.
+ * nullptr is returned for empty buffers.
+ */
+ LIBSHIBOKEN_API void *copyData(PyObject *pyObj, Py_ssize_t *size = nullptr);
+
} // namespace Buffer
} // namespace Shiboken
diff --git a/sources/shiboken2/libshiboken/signature/signature.cpp b/sources/shiboken2/libshiboken/signature/signature.cpp
index 4c251af5b..601df4730 100644
--- a/sources/shiboken2/libshiboken/signature/signature.cpp
+++ b/sources/shiboken2/libshiboken/signature/signature.cpp
@@ -499,7 +499,7 @@ static PyObject *adjustFuncName(const char *func_name)
}
// Finally, generate the correct path expression.
- char _buf[200 + 1] = {};
+ char _buf[250 + 1] = {};
if (is_prop) {
auto _prop_name = String::toCString(prop_name);
if (is_class_prop)
diff --git a/sources/shiboken2/shiboken_version.py b/sources/shiboken2/shiboken_version.py
index 0985e2559..ecc975ddf 100644
--- a/sources/shiboken2/shiboken_version.py
+++ b/sources/shiboken2/shiboken_version.py
@@ -39,7 +39,7 @@
major_version = "5"
minor_version = "15"
-patch_version = "3"
+patch_version = "4"
# For example: "a", "b", "rc"
# (which means "alpha", "beta", "release candidate").
diff --git a/sources/shiboken2/shibokenmodule/CMakeLists.txt b/sources/shiboken2/shibokenmodule/CMakeLists.txt
index b14de5c9e..9b2b58528 100644
--- a/sources/shiboken2/shibokenmodule/CMakeLists.txt
+++ b/sources/shiboken2/shibokenmodule/CMakeLists.txt
@@ -42,37 +42,12 @@ install(FILES "${CMAKE_CURRENT_BINARY_DIR}/_config.py"
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/__init__.py.in"
"${CMAKE_CURRENT_BINARY_DIR}/__init__.py" @ONLY)
-configure_file("${CMAKE_CURRENT_SOURCE_DIR}/files.dir/shibokensupport/__feature__.py"
- "${CMAKE_CURRENT_BINARY_DIR}/files.dir/shibokensupport/__feature__.py" COPYONLY)
-configure_file("${CMAKE_CURRENT_SOURCE_DIR}/files.dir/shibokensupport/__init__.py"
- "${CMAKE_CURRENT_BINARY_DIR}/files.dir/shibokensupport/__init__.py" COPYONLY)
-configure_file("${CMAKE_CURRENT_SOURCE_DIR}/files.dir/shibokensupport/signature/__init__.py"
- "${CMAKE_CURRENT_BINARY_DIR}/files.dir/shibokensupport/signature/__init__.py" COPYONLY)
-configure_file("${CMAKE_CURRENT_SOURCE_DIR}/files.dir/shibokensupport/signature/errorhandler.py"
- "${CMAKE_CURRENT_BINARY_DIR}/files.dir/shibokensupport/signature/errorhandler.py" COPYONLY)
-configure_file("${CMAKE_CURRENT_SOURCE_DIR}/files.dir/shibokensupport/signature/layout.py"
- "${CMAKE_CURRENT_BINARY_DIR}/files.dir/shibokensupport/signature/layout.py" COPYONLY)
-configure_file("${CMAKE_CURRENT_SOURCE_DIR}/files.dir/shibokensupport/signature/loader.py"
- "${CMAKE_CURRENT_BINARY_DIR}/files.dir/shibokensupport/signature/loader.py" COPYONLY)
-configure_file("${CMAKE_CURRENT_SOURCE_DIR}/files.dir/shibokensupport/signature/importhandler.py"
- "${CMAKE_CURRENT_BINARY_DIR}/files.dir/shibokensupport/signature/importhandler.py" COPYONLY)
-configure_file("${CMAKE_CURRENT_SOURCE_DIR}/files.dir/shibokensupport/signature/mapping.py"
- "${CMAKE_CURRENT_BINARY_DIR}/files.dir/shibokensupport/signature/mapping.py" COPYONLY)
-configure_file("${CMAKE_CURRENT_SOURCE_DIR}/files.dir/shibokensupport/signature/parser.py"
- "${CMAKE_CURRENT_BINARY_DIR}/files.dir/shibokensupport/signature/parser.py" COPYONLY)
-configure_file("${CMAKE_CURRENT_SOURCE_DIR}/files.dir/shibokensupport/signature/lib/__init__.py"
- "${CMAKE_CURRENT_BINARY_DIR}/files.dir/shibokensupport/signature/lib/__init__.py" COPYONLY)
-configure_file("${CMAKE_CURRENT_SOURCE_DIR}/files.dir/shibokensupport/signature/lib/enum_sig.py"
- "${CMAKE_CURRENT_BINARY_DIR}/files.dir/shibokensupport/signature/lib/enum_sig.py" COPYONLY)
-configure_file("${CMAKE_CURRENT_SOURCE_DIR}/files.dir/shibokensupport/signature/lib/tool.py"
- "${CMAKE_CURRENT_BINARY_DIR}/files.dir/shibokensupport/signature/lib/tool.py" COPYONLY)
-if (PYTHON_VERSION_MAJOR EQUAL 3)
-else()
- configure_file("${CMAKE_CURRENT_SOURCE_DIR}/files.dir/shibokensupport/backport_inspect.py"
- "${CMAKE_CURRENT_BINARY_DIR}/files.dir/shibokensupport/backport_inspect.py" COPYONLY)
- configure_file("${CMAKE_CURRENT_SOURCE_DIR}/files.dir/shibokensupport/typing27.py"
- "${CMAKE_CURRENT_BINARY_DIR}/files.dir/shibokensupport/typing27.py" COPYONLY)
-endif()
+# Variable from enclosing scope.
+foreach(item IN LISTS shiboken_python_files)
+ configure_file("${CMAKE_CURRENT_SOURCE_DIR}/files.dir/shibokensupport/${item}"
+ "${CMAKE_CURRENT_BINARY_DIR}/files.dir/shibokensupport/${item}" COPYONLY)
+endforeach()
+
install(DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/files.dir"
DESTINATION "${PYTHON_SITE_PACKAGES}/shiboken2")
diff --git a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/__feature__.py b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/feature.py
index ece3d2edb..ece3d2edb 100644
--- a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/__feature__.py
+++ b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/feature.py
diff --git a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/lib/enum_sig.py b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/lib/enum_sig.py
index 21c284f88..088a93aa4 100644
--- a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/lib/enum_sig.py
+++ b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/lib/enum_sig.py
@@ -103,8 +103,6 @@ class ExactEnumerator(object):
self.fmt.class_name = None
for class_name, klass in members:
ret.update(self.klass(class_name, klass))
- if isinstance(klass, EnumMeta):
- raise SystemError("implement enum instances at module level")
for func_name, func in functions:
ret.update(self.function(func_name, func))
return ret
diff --git a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/loader.py b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/loader.py
index a6c3e420d..a509ecf07 100644
--- a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/loader.py
+++ b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/loader.py
@@ -114,7 +114,7 @@ def finish_import(module):
import signature_bootstrap
-from shibokensupport import signature, __feature__
+from shibokensupport import signature, feature as __feature__
signature.get_signature = signature_bootstrap.get_signature
# PYSIDE-1019: Publish the __feature__ dictionary.
__feature__.pyside_feature_dict = signature_bootstrap.pyside_feature_dict
@@ -195,8 +195,9 @@ def move_into_pyside_package():
try:
import PySide2.support
except ModuleNotFoundError:
- PySide2.support = types.ModuleType("PySide2.support")
- put_into_package(PySide2.support, __feature__)
+ # This can happen in the embedding case.
+ put_into_package(PySide2, shibokensupport, "support")
+ put_into_package(PySide2.support, __feature__, "__feature__")
put_into_package(PySide2.support, signature)
put_into_package(PySide2.support.signature, mapping)
put_into_package(PySide2.support.signature, errorhandler)
@@ -220,16 +221,18 @@ from shibokensupport.signature.lib import enum_sig
if "PySide2" in sys.modules:
# We publish everything under "PySide2.support.signature", again.
move_into_pyside_package()
+ # PYSIDE-1502: Make sure that support can be imported.
+ try:
+ import PySide2.support
+ except ModuleNotFoundError as e:
+ print("PySide2.support could not be imported. "
+ "This is a serious configuration error.", file=sys.stderr)
+ raise
# PYSIDE-1019: Modify `__import__` to be `__feature__` aware.
# __feature__ is already in sys.modules, so this is actually no import
- try:
- import PySide2.support.__feature__
- sys.modules["__feature__"] = PySide2.support.__feature__
- PySide2.support.__feature__.original_import = __builtins__["__import__"]
- __builtins__["__import__"] = PySide2.support.__feature__._import
- # Maybe we should optimize that and change `__import__` from C, instead?
- except ModuleNotFoundError:
- print("__feature__ could not be imported. "
- "This is an unsolved PyInstaller problem.", file=sys.stderr)
+ import PySide2.support.__feature__
+ sys.modules["__feature__"] = PySide2.support.__feature__
+ PySide2.support.__feature__.original_import = __builtins__["__import__"]
+ __builtins__["__import__"] = PySide2.support.__feature__._import
# end of file
diff --git a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/mapping.py b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/mapping.py
index 4c9f02dc2..92511df32 100644
--- a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/mapping.py
+++ b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/mapping.py
@@ -351,6 +351,10 @@ type_map.update({
"self" : "self",
})
+# PYSIDE-1538: We need to treat "std::optional" accordingly.
+type_map.update({
+ "std.optional": typing.Optional,
+ })
# The Shiboken Part
def init_Shiboken():
diff --git a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/parser.py b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/parser.py
index 20c791cc1..a1cb58074 100644
--- a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/parser.py
+++ b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/parser.py
@@ -196,7 +196,7 @@ def _resolve_value(thing, valtype, line):
if res is not None:
type_map[thing] = res
return res
- warnings.warn("""pyside_type_init:
+ warnings.warn("""pyside_type_init:_resolve_value
UNRECOGNIZED: {!r}
OFFENDING LINE: {!r}
@@ -277,7 +277,15 @@ def _resolve_type(thing, line, level, var_handler):
pieces.append(to_string(part))
thing = ", ".join(pieces)
result = "{contr}[{thing}]".format(**locals())
- return eval(result, namespace)
+ # PYSIDE-1538: Make sure that the eval does not crash.
+ try:
+ return eval(result, namespace)
+ except Exception as e:
+ warnings.warn("""pyside_type_init:_resolve_type
+
+ UNRECOGNIZED: {!r}
+ OFFENDING LINE: {!r}
+ """.format(result, line), RuntimeWarning)
return _resolve_value(thing, None, line)
@@ -380,7 +388,9 @@ def fix_variables(props, line):
if not isinstance(ann, ResultVariable):
continue
# We move the variable to the end and remove it.
- retvars.append(ann.type)
+ # PYSIDE-1409: If the variable was the first arg, we move it to the front.
+ # XXX This algorithm should probably be replaced by more introspection.
+ retvars.insert(0 if idx == 0 else len(retvars), ann.type)
deletions.append(idx)
del annos[name]
for idx in reversed(deletions):