aboutsummaryrefslogtreecommitdiffstats
path: root/sources/shiboken2
diff options
context:
space:
mode:
Diffstat (limited to 'sources/shiboken2')
-rw-r--r--sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp113
-rw-r--r--sources/shiboken2/ApiExtractor/abstractmetabuilder.h11
-rw-r--r--sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h6
-rw-r--r--sources/shiboken2/ApiExtractor/abstractmetalang.cpp107
-rw-r--r--sources/shiboken2/ApiExtractor/abstractmetalang.h15
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testabstractmetaclass.cpp66
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testcodeinjection.cpp2
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testresolvetype.cpp16
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testtemplates.cpp32
-rw-r--r--sources/shiboken2/ApiExtractor/typesystemparser.cpp252
-rw-r--r--sources/shiboken2/generator/generator.cpp9
-rw-r--r--sources/shiboken2/generator/shiboken2/cppgenerator.cpp109
-rw-r--r--sources/shiboken2/generator/shiboken2/headergenerator.cpp7
-rw-r--r--sources/shiboken2/generator/shiboken2/overloaddata.cpp16
-rw-r--r--sources/shiboken2/generator/shiboken2/shibokengenerator.cpp25
-rw-r--r--sources/shiboken2/generator/shiboken2/shibokengenerator.h5
-rw-r--r--sources/shiboken2/libshiboken/CMakeLists.txt10
-rw-r--r--sources/shiboken2/libshiboken/basewrapper.cpp12
-rw-r--r--sources/shiboken2/libshiboken/embed/embedding_generator.py4
-rw-r--r--sources/shiboken2/libshiboken/helper.cpp3
-rw-r--r--sources/shiboken2/libshiboken/pep384impl.cpp42
-rw-r--r--sources/shiboken2/libshiboken/pep384impl.h2
-rw-r--r--sources/shiboken2/libshiboken/sbkenum.cpp7
-rw-r--r--sources/shiboken2/libshiboken/sbkstaticstrings.cpp92
-rw-r--r--sources/shiboken2/libshiboken/sbkstaticstrings.h65
-rw-r--r--sources/shiboken2/libshiboken/sbkstaticstrings_p.h73
-rw-r--r--sources/shiboken2/libshiboken/sbkstring.cpp71
-rw-r--r--sources/shiboken2/libshiboken/sbkstring.h10
-rw-r--r--sources/shiboken2/libshiboken/shiboken.h1
-rw-r--r--sources/shiboken2/libshiboken/signature.cpp145
-rw-r--r--sources/shiboken2/libshiboken/signature.h2
-rw-r--r--sources/shiboken2/libshiboken/signature_doc.rst10
-rw-r--r--sources/shiboken2/libshiboken/typespec.cpp3
-rw-r--r--sources/shiboken2/shiboken_version.py7
-rw-r--r--sources/shiboken2/shibokenmodule/CMakeLists.txt2
-rw-r--r--sources/shiboken2/shibokenmodule/files.dir/shibokensupport/backport_inspect.py4
-rw-r--r--sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/importhandler.py103
-rw-r--r--sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/lib/enum_sig.py82
-rw-r--r--sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/loader.py12
-rw-r--r--sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/mapping.py175
-rw-r--r--sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/parser.py110
-rw-r--r--sources/shiboken2/tests/samplebinding/pointerprimitivetype_test.py79
-rw-r--r--sources/shiboken2/tests/samplebinding/typesystem_sample.xml1
43 files changed, 1303 insertions, 615 deletions
diff --git a/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp b/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp
index 84721968d..ae3cdd86b 100644
--- a/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp
+++ b/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp
@@ -1607,8 +1607,13 @@ void AbstractMetaBuilderPrivate::traverseEnums(const ScopeModelItem &scopeItem,
const QStringList &enumsDeclarations)
{
const EnumList &enums = scopeItem->enums();
+#if QT_VERSION >= 0x050E00
+ const QSet<QString> enumsDeclarationSet(enumsDeclarations.cbegin(), enumsDeclarations.cend());
+#else
+ const QSet<QString> enumsDeclarationSet = QSet<QString>::fromList(enumsDeclarations);
+#endif
for (const EnumModelItem &enumItem : enums) {
- AbstractMetaEnum* metaEnum = traverseEnum(enumItem, metaClass, QSet<QString>::fromList(enumsDeclarations));
+ AbstractMetaEnum* metaEnum = traverseEnum(enumItem, metaClass, enumsDeclarationSet);
if (metaEnum) {
metaClass->addEnum(metaEnum);
metaEnum->setEnclosingClass(metaClass);
@@ -1616,6 +1621,26 @@ void AbstractMetaBuilderPrivate::traverseEnums(const ScopeModelItem &scopeItem,
}
}
+static void applyDefaultExpressionModifications(const FunctionModificationList &functionMods,
+ int i, AbstractMetaArgument *metaArg)
+{
+ // use replace/remove-default-expression for set default value
+ for (const auto &modification : functionMods) {
+ for (const auto &argumentModification : modification.argument_mods) {
+ if (argumentModification.index == i + 1) {
+ if (argumentModification.removedDefaultExpression) {
+ metaArg->setDefaultValueExpression(QString());
+ break;
+ }
+ if (!argumentModification.replacedDefaultExpression.isEmpty()) {
+ metaArg->setDefaultValueExpression(argumentModification.replacedDefaultExpression);
+ break;
+ }
+ }
+ }
+ }
+}
+
AbstractMetaFunction* AbstractMetaBuilderPrivate::traverseFunction(const AddedFunctionPtr &addedFunc)
{
return traverseFunction(addedFunc, nullptr);
@@ -1674,20 +1699,13 @@ AbstractMetaFunction* AbstractMetaBuilderPrivate::traverseFunction(const AddedFu
// Find the correct default values
+ const FunctionModificationList functionMods = metaFunction->modifications(metaClass);
for (int i = 0; i < metaArguments.size(); ++i) {
AbstractMetaArgument* metaArg = metaArguments.at(i);
- //use relace-default-expression for set default value
- QString replacedExpression;
- if (metaClass)
- replacedExpression = metaFunction->replacedDefaultExpression(metaClass, i + 1);
-
- if (!replacedExpression.isEmpty()) {
- if (!metaFunction->removedDefaultExpression(metaClass, i + 1)) {
- metaArg->setDefaultValueExpression(replacedExpression);
- metaArg->setOriginalDefaultValueExpression(replacedExpression);
- }
- }
+ // use replace-default-expression for set default value
+ applyDefaultExpressionModifications(functionMods, i, metaArg);
+ metaArg->setOriginalDefaultValueExpression(metaArg->defaultValueExpression()); // appear unmodified
}
metaFunction->setOriginalAttributes(metaFunction->attributes());
@@ -1919,7 +1937,7 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(const Functio
AbstractMetaType *type = nullptr;
if (!returnType.isVoid()) {
- type = translateType(returnType, currentClass, true, &errorMessage);
+ type = translateType(returnType, currentClass, {}, &errorMessage);
if (!type) {
const QString reason = msgUnmatchedReturnType(functionItem, errorMessage);
qCWarning(lcShiboken, "%s",
@@ -1955,7 +1973,7 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(const Functio
return nullptr;
}
- AbstractMetaType *metaType = translateType(arg->type(), currentClass, true, &errorMessage);
+ AbstractMetaType *metaType = translateType(arg->type(), currentClass, {}, &errorMessage);
if (!metaType) {
// If an invalid argument has a default value, simply remove it
if (arg->defaultValue()) {
@@ -2006,35 +2024,16 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(const Functio
const ArgumentModelItem &arg = arguments.at(i);
AbstractMetaArgument* metaArg = metaArguments.at(i);
- //use relace-default-expression for set default value
- QString replacedExpression;
- if (currentClass) {
- replacedExpression = metaFunction->replacedDefaultExpression(currentClass, i + 1);
- } else {
- if (!functionMods.isEmpty()) {
- QVector<ArgumentModification> argMods = functionMods.constFirst().argument_mods;
- if (!argMods.isEmpty())
- replacedExpression = argMods.constFirst().replacedDefaultExpression;
- }
- }
+ const QString originalDefaultExpression =
+ fixDefaultValue(arg, metaArg->type(), metaFunction, currentClass, i);
- bool hasDefaultValue = false;
- if (arg->defaultValue() || !replacedExpression.isEmpty()) {
- QString expr = arg->defaultValueExpression();
- expr = fixDefaultValue(arg, metaArg->type(), metaFunction, currentClass, i);
- metaArg->setOriginalDefaultValueExpression(expr);
+ metaArg->setOriginalDefaultValueExpression(originalDefaultExpression);
+ metaArg->setDefaultValueExpression(originalDefaultExpression);
- if (metaFunction->removedDefaultExpression(currentClass, i + 1)) {
- expr.clear();
- } else if (!replacedExpression.isEmpty()) {
- expr = replacedExpression;
- }
- metaArg->setDefaultValueExpression(expr);
- hasDefaultValue = !expr.isEmpty();
- }
+ applyDefaultExpressionModifications(functionMods, i, metaArg);
//Check for missing argument name
- if (hasDefaultValue
+ if (!metaArg->defaultValueExpression().isEmpty()
&& !metaArg->hasName()
&& !metaFunction->isOperatorOverload()
&& !metaFunction->isSignal()
@@ -2159,22 +2158,27 @@ static const TypeEntry* findTypeEntryUsingContext(const AbstractMetaClass* metaC
AbstractMetaType *AbstractMetaBuilderPrivate::translateType(const TypeInfo &_typei,
AbstractMetaClass *currentClass,
- bool resolveType,
+ TranslateTypeFlags flags,
QString *errorMessage)
{
- return translateTypeStatic(_typei, currentClass, this, resolveType, errorMessage);
+ return translateTypeStatic(_typei, currentClass, this, flags, errorMessage);
}
AbstractMetaType *AbstractMetaBuilderPrivate::translateTypeStatic(const TypeInfo &_typei,
AbstractMetaClass *currentClass,
AbstractMetaBuilderPrivate *d,
- bool resolveType,
+ TranslateTypeFlags flags,
QString *errorMessageIn)
{
// 1. Test the type info without resolving typedefs in case this is present in the
// type system
+ const bool resolveType = !flags.testFlag(AbstractMetaBuilder::DontResolveType);
if (resolveType) {
- if (AbstractMetaType *resolved = translateTypeStatic(_typei, currentClass, d, false, errorMessageIn))
+ AbstractMetaType *resolved =
+ translateTypeStatic(_typei, currentClass, d,
+ flags | AbstractMetaBuilder::DontResolveType,
+ errorMessageIn);
+ if (resolved)
return resolved;
}
@@ -2233,7 +2237,7 @@ AbstractMetaType *AbstractMetaBuilderPrivate::translateTypeStatic(const TypeInfo
newInfo.setReferenceType(typeInfo.referenceType());
newInfo.setVolatile(typeInfo.isVolatile());
- AbstractMetaType *elementType = translateTypeStatic(newInfo, currentClass, d, true, &errorMessage);
+ AbstractMetaType *elementType = translateTypeStatic(newInfo, currentClass, d, flags, &errorMessage);
if (!elementType) {
if (errorMessageIn) {
errorMessage.prepend(QLatin1String("Unable to translate array element: "));
@@ -2344,7 +2348,7 @@ AbstractMetaType *AbstractMetaBuilderPrivate::translateTypeStatic(const TypeInfo
const auto &templateArguments = typeInfo.instantiations();
for (int t = 0, size = templateArguments.size(); t < size; ++t) {
const TypeInfo &ti = templateArguments.at(t);
- AbstractMetaType *targType = translateTypeStatic(ti, currentClass, d, true, &errorMessage);
+ AbstractMetaType *targType = translateTypeStatic(ti, currentClass, d, flags, &errorMessage);
if (!targType) {
if (errorMessageIn)
*errorMessageIn = msgCannotTranslateTemplateArgument(t, ti, errorMessage);
@@ -2366,17 +2370,17 @@ AbstractMetaType *AbstractMetaBuilderPrivate::translateTypeStatic(const TypeInfo
AbstractMetaType *AbstractMetaBuilder::translateType(const TypeInfo &_typei,
AbstractMetaClass *currentClass,
- bool resolveType,
+ TranslateTypeFlags flags,
QString *errorMessage)
{
return AbstractMetaBuilderPrivate::translateTypeStatic(_typei, currentClass,
- nullptr, resolveType,
+ nullptr, flags,
errorMessage);
}
AbstractMetaType *AbstractMetaBuilder::translateType(const QString &t,
AbstractMetaClass *currentClass,
- bool resolveType,
+ TranslateTypeFlags flags,
QString *errorMessageIn)
{
QString errorMessage;
@@ -2389,7 +2393,7 @@ AbstractMetaType *AbstractMetaBuilder::translateType(const QString &t,
qCWarning(lcShiboken, "%s", qPrintable(errorMessage));
return nullptr;
}
- return translateType(typeInfo, currentClass, resolveType, errorMessageIn);
+ return translateType(typeInfo, currentClass, flags, errorMessageIn);
}
qint64 AbstractMetaBuilderPrivate::findOutValueFromString(const QString &stringValue, bool &ok)
@@ -2435,10 +2439,10 @@ QString AbstractMetaBuilderPrivate::fixDefaultValue(const ArgumentModelItem &ite
AbstractMetaClass *implementingClass,
int /* argumentIndex */)
{
- QString functionName = fnc->name();
- QString className = implementingClass ? implementingClass->qualifiedCppName() : QString();
-
QString expr = item->defaultValueExpression();
+ if (expr.isEmpty())
+ return expr;
+
if (type) {
if (type->isPrimitive()) {
if (type->name() == QLatin1String("boolean")) {
@@ -2512,11 +2516,12 @@ QString AbstractMetaBuilderPrivate::fixDefaultValue(const ArgumentModelItem &ite
}
}
} else {
+ const QString className = implementingClass ? implementingClass->qualifiedCppName() : QString();
qCWarning(lcShiboken).noquote().nospace()
<< QStringLiteral("undefined type for default value '%3' of argument in function '%1', class '%2'")
- .arg(functionName, className, item->defaultValueExpression());
+ .arg(fnc->name(), className, item->defaultValueExpression());
- expr = QString();
+ expr.clear();
}
return expr;
diff --git a/sources/shiboken2/ApiExtractor/abstractmetabuilder.h b/sources/shiboken2/ApiExtractor/abstractmetabuilder.h
index 1789ca2aa..93b9d9fd2 100644
--- a/sources/shiboken2/ApiExtractor/abstractmetabuilder.h
+++ b/sources/shiboken2/ApiExtractor/abstractmetabuilder.h
@@ -90,13 +90,18 @@ public:
void setSkipDeprecated(bool value);
+ enum TranslateTypeFlag {
+ DontResolveType = 0x1
+ };
+ Q_DECLARE_FLAGS(TranslateTypeFlags, TranslateTypeFlag);
+
static AbstractMetaType *translateType(const TypeInfo &_typei,
AbstractMetaClass *currentClass = nullptr,
- bool resolveType = true,
+ TranslateTypeFlags flags = {},
QString *errorMessage = nullptr);
static AbstractMetaType *translateType(const QString &t,
AbstractMetaClass *currentClass = nullptr,
- bool resolveType = true,
+ TranslateTypeFlags flags = {},
QString *errorMessage = nullptr);
@@ -109,6 +114,8 @@ private:
AbstractMetaBuilderPrivate *d;
};
+Q_DECLARE_OPERATORS_FOR_FLAGS(AbstractMetaBuilder::TranslateTypeFlags);
+
#ifndef QT_NO_DEBUG_STREAM
QDebug operator<<(QDebug d, const AbstractMetaBuilder &ab);
#endif
diff --git a/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h b/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h
index 18c5afc17..30df236d6 100644
--- a/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h
+++ b/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h
@@ -43,6 +43,8 @@ class TypeDatabase;
class AbstractMetaBuilderPrivate
{
public:
+ using TranslateTypeFlags = AbstractMetaBuilder::TranslateTypeFlags;
+
Q_DISABLE_COPY(AbstractMetaBuilderPrivate)
AbstractMetaBuilderPrivate();
@@ -136,12 +138,12 @@ public:
AbstractMetaType *translateType(const AddedFunction::TypeInfo &typeInfo);
AbstractMetaType *translateType(const TypeInfo &type,
AbstractMetaClass *currentClass,
- bool resolveType = true,
+ TranslateTypeFlags flags = {},
QString *errorMessage = nullptr);
static AbstractMetaType *translateTypeStatic(const TypeInfo &type,
AbstractMetaClass *current,
AbstractMetaBuilderPrivate *d = nullptr,
- bool resolveType = true,
+ TranslateTypeFlags flags = {},
QString *errorMessageIn = nullptr);
qint64 findOutValueFromString(const QString &stringValue, bool &ok);
diff --git a/sources/shiboken2/ApiExtractor/abstractmetalang.cpp b/sources/shiboken2/ApiExtractor/abstractmetalang.cpp
index 455140e59..99e9d01a3 100644
--- a/sources/shiboken2/ApiExtractor/abstractmetalang.cpp
+++ b/sources/shiboken2/ApiExtractor/abstractmetalang.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt for Python.
@@ -268,6 +268,15 @@ QString AbstractMetaType::cppSignature() const
return m_cachedCppSignature;
}
+QString AbstractMetaType::pythonSignature() const
+{
+ // PYSIDE-921: Handle container returntypes correctly.
+ // This is now a clean reimplementation.
+ if (m_cachedPythonSignature.isEmpty())
+ m_cachedPythonSignature = formatPythonSignature(false);
+ return m_cachedPythonSignature;
+}
+
AbstractMetaType::TypeUsagePattern AbstractMetaType::determineUsagePattern() const
{
if (m_typeEntry->isTemplateArgument() || m_referenceType == RValueReference)
@@ -722,37 +731,6 @@ ArgumentOwner AbstractMetaFunction::argumentOwner(const AbstractMetaClass *cls,
return ArgumentOwner();
}
-
-QString AbstractMetaFunction::replacedDefaultExpression(const AbstractMetaClass *cls, int key) const
-{
- const FunctionModificationList &modifications = this->modifications(cls);
- for (const FunctionModification &modification : modifications) {
- for (const ArgumentModification &argumentModification : modification.argument_mods) {
- if (argumentModification.index == key
- && !argumentModification.replacedDefaultExpression.isEmpty()) {
- return argumentModification.replacedDefaultExpression;
- }
- }
- }
-
- return QString();
-}
-
-bool AbstractMetaFunction::removedDefaultExpression(const AbstractMetaClass *cls, int key) const
-{
- const FunctionModificationList &modifications = this->modifications(cls);
- for (const FunctionModification &modification : modifications) {
- for (const ArgumentModification &argumentModification : modification.argument_mods) {
- if (argumentModification.index == key
- && argumentModification.removedDefaultExpression) {
- return true;
- }
- }
- }
-
- return false;
-}
-
QString AbstractMetaFunction::conversionRule(TypeSystem::Language language, int key) const
{
const FunctionModificationList &modifications = this->modifications(declaringClass());
@@ -771,19 +749,6 @@ QString AbstractMetaFunction::conversionRule(TypeSystem::Language language, int
return QString();
}
-QString AbstractMetaFunction::argumentReplaced(int key) const
-{
- const FunctionModificationList &modifications = this->modifications(declaringClass());
- for (const FunctionModification &modification : modifications) {
- for (const ArgumentModification &argumentModification : modification.argument_mods) {
- if (argumentModification.index == key && !argumentModification.replace_value.isEmpty())
- return argumentModification.replace_value;
- }
- }
-
- return QString();
-}
-
// FIXME If we remove a arg. in the method at the base class, it will not reflect here.
bool AbstractMetaFunction::argumentRemoved(int key) const
{
@@ -2555,6 +2520,58 @@ QString AbstractMetaType::formatSignature(bool minimal) const
return result;
}
+QString AbstractMetaType::formatPythonSignature(bool minimal) const
+{
+ /*
+ * This is a version of the above, more suitable for Python.
+ * We avoid extra keywords that are not needed in Python.
+ * We prepend the package name, unless it is a primitive type.
+ *
+ * Primitive types like 'int', 'char' etc.:
+ * When we have a primitive with an indirection, we use that '*'
+ * character for later postprocessing, since those indirections
+ * need to be modified into a result tuple.
+ */
+ QString result;
+ if (m_pattern == AbstractMetaType::NativePointerAsArrayPattern)
+ result += QLatin1String("array ");
+ // We no longer use the "const" qualifier for heuristics. Instead,
+ // NativePointerAsArrayPattern indicates when we have <array> in XML.
+ // if (m_typeEntry->isPrimitive() && isConstant())
+ // result += QLatin1String("const ");
+ if (!m_typeEntry->isPrimitive() && !package().isEmpty())
+ result += package() + QLatin1Char('.');
+ if (isArray()) {
+ // Build nested array dimensions a[2][3] in correct order
+ result += m_arrayElementType->formatPythonSignature(true);
+ const int arrayPos = result.indexOf(QLatin1Char('['));
+ if (arrayPos != -1)
+ result.insert(arrayPos, formatArraySize(m_arrayElementCount));
+ else
+ result.append(formatArraySize(m_arrayElementCount));
+ } else {
+ result += typeEntry()->qualifiedCppName();
+ }
+ if (!m_instantiations.isEmpty()) {
+ result += QLatin1Char('[');
+ for (int i = 0, size = m_instantiations.size(); i < size; ++i) {
+ if (i > 0)
+ result += QLatin1String(", ");
+ result += m_instantiations.at(i)->formatPythonSignature(true);
+ }
+ result += QLatin1Char(']');
+ }
+ if (m_typeEntry->isPrimitive())
+ for (Indirection i : m_indirections)
+ result += TypeInfo::indirectionKeyword(i);
+ // If it is a flags type, we replace it with the full name:
+ // "PySide2.QtCore.Qt.ItemFlags" instead of "PySide2.QtCore.QFlags<Qt.ItemFlag>"
+ if (m_typeEntry->isFlags())
+ result = fullName();
+ result.replace(QLatin1String("::"), QLatin1String("."));
+ return result;
+}
+
bool AbstractMetaType::isCppPrimitive() const
{
return m_pattern == PrimitivePattern && m_typeEntry->isCppPrimitive();
diff --git a/sources/shiboken2/ApiExtractor/abstractmetalang.h b/sources/shiboken2/ApiExtractor/abstractmetalang.h
index 91ca4d7a9..077191471 100644
--- a/sources/shiboken2/ApiExtractor/abstractmetalang.h
+++ b/sources/shiboken2/ApiExtractor/abstractmetalang.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt for Python.
@@ -483,6 +483,8 @@ public:
QString cppSignature() const;
+ QString pythonSignature() const;
+
AbstractMetaType *copy() const;
bool applyArrayModification(QString *errorMessage);
@@ -540,12 +542,14 @@ public:
private:
TypeUsagePattern determineUsagePattern() const;
QString formatSignature(bool minimal) const;
+ QString formatPythonSignature(bool minimal) const;
const TypeEntry *m_typeEntry = nullptr;
AbstractMetaTypeList m_instantiations;
QString m_package;
mutable QString m_name;
mutable QString m_cachedCppSignature;
+ mutable QString m_cachedPythonSignature;
QString m_originalTypeDescription;
int m_arrayElementCount = -1;
@@ -667,7 +671,9 @@ public:
}
bool hasDefaultValueExpression() const
- { return !m_originalExpression.isEmpty() || !m_expression.isEmpty(); }
+ { return !m_expression.isEmpty(); }
+ bool hasOriginalDefaultValueExpression() const
+ { return !m_originalExpression.isEmpty(); }
bool hasUnmodifiedDefaultValueExpression() const
{ return !m_originalExpression.isEmpty() && m_originalExpression == m_expression; }
bool hasModifiedDefaultValueExpression() const
@@ -1016,8 +1022,6 @@ public:
AbstractMetaFunction *copy() const;
- QString replacedDefaultExpression(const AbstractMetaClass *cls, int idx) const;
- bool removedDefaultExpression(const AbstractMetaClass *cls, int idx) const;
QString conversionRule(TypeSystem::Language language, int idx) const;
QVector<ReferenceCount> referenceCounts(const AbstractMetaClass *cls, int idx = -2) const;
ArgumentOwner argumentOwner(const AbstractMetaClass *cls, int idx) const;
@@ -1030,9 +1034,6 @@ public:
bool isRemovedFromAllLanguages(const AbstractMetaClass *) const;
bool isRemovedFrom(const AbstractMetaClass *, TypeSystem::Language language) const;
bool argumentRemoved(int) const;
-
- QString argumentReplaced(int key) const;
-
/**
* Verifies if any modification to the function is an inject code.
* \return true if there is inject code modifications to the function.
diff --git a/sources/shiboken2/ApiExtractor/tests/testabstractmetaclass.cpp b/sources/shiboken2/ApiExtractor/tests/testabstractmetaclass.cpp
index 98b493c67..b85a022b3 100644
--- a/sources/shiboken2/ApiExtractor/tests/testabstractmetaclass.cpp
+++ b/sources/shiboken2/ApiExtractor/tests/testabstractmetaclass.cpp
@@ -47,11 +47,12 @@ void TestAbstractMetaClass::testClassName()
void TestAbstractMetaClass::testClassNameUnderNamespace()
{
const char* cppCode ="namespace Namespace { class ClassName {}; }\n";
- const char* xmlCode = "\
- <typesystem package=\"Foo\">\n\
- <namespace-type name=\"Namespace\"/>\n\
- <value-type name=\"Namespace::ClassName\"/>\n\
- </typesystem>\n";
+ const char* xmlCode = R"XML(
+ <typesystem package="Foo">
+ <namespace-type name="Namespace">
+ <value-type name="ClassName"/>
+ </namespace-type>
+ </typesystem>)XML";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
QVERIFY(!builder.isNull());
AbstractMetaClassList classes = builder->classes();
@@ -201,11 +202,12 @@ void TestAbstractMetaClass::testDefaultValues()
class B {};\n\
void method(B b = B());\n\
};\n";
- const char* xmlCode = "\
- <typesystem package=\"Foo\">\n\
- <value-type name='A'/>\n\
- <value-type name='A::B'/>\n\
- </typesystem>\n";
+ const char* xmlCode = R"XML(
+ <typesystem package="Foo">
+ <value-type name='A'>
+ <value-type name='B'/>
+ </value-type>
+ </typesystem>)XML";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
QVERIFY(!builder.isNull());
AbstractMetaClassList classes = builder->classes();
@@ -224,17 +226,17 @@ void TestAbstractMetaClass::testModifiedDefaultValues()
class B {};\n\
void method(B b = B());\n\
};\n";
- const char* xmlCode = "\
- <typesystem package=\"Foo\">\n\
- <value-type name='A'>\n\
- <modify-function signature='method(A::B)'>\n\
- <modify-argument index='1'>\n\
- <replace-default-expression with='Hello'/>\n\
- </modify-argument>\n\
- </modify-function>\n\
- </value-type>\n\
- <value-type name='A::B'/>\n\
- </typesystem>\n";
+ const char* xmlCode = R"XML(
+ <typesystem package="Foo">
+ <value-type name='A'>
+ <modify-function signature='method(A::B)'>
+ <modify-argument index='1'>
+ <replace-default-expression with='Hello'/>
+ </modify-argument>
+ </modify-function>
+ <value-type name='B'/>
+ </value-type>
+ </typesystem>)XML";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
QVERIFY(!builder.isNull());
AbstractMetaClassList classes = builder->classes();
@@ -254,11 +256,12 @@ void TestAbstractMetaClass::testInnerClassOfAPolymorphicOne()
class B {};\n\
virtual void method();\n\
};\n";
- const char* xmlCode = "\
- <typesystem package=\"Foo\">\n\
- <object-type name='A'/>\n\
- <value-type name='A::B'/>\n\
- </typesystem>\n";
+ const char* xmlCode = R"XML(
+ <typesystem package="Foo">
+ <object-type name='A'>
+ <value-type name='B'/>
+ </object-type>
+ </typesystem>)XML";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
QVERIFY(!builder.isNull());
AbstractMetaClassList classes = builder->classes();
@@ -281,11 +284,12 @@ void TestAbstractMetaClass::testForwardDeclaredInnerClass()
public:\n\
void foo();\n\
};\n";
- const char xmlCode[] = "\
- <typesystem package=\"Foo\">\n\
- <value-type name='A'/>\n\
- <value-type name='A::B'/>\n\
- </typesystem>\n";
+ const char xmlCode[] = R"XML(
+ <typesystem package="Foo">
+ <value-type name='A'>
+ <value-type name='B'/>
+ </value-type>
+ </typesystem>)XML";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
QVERIFY(!builder.isNull());
AbstractMetaClassList classes = builder->classes();
diff --git a/sources/shiboken2/ApiExtractor/tests/testcodeinjection.cpp b/sources/shiboken2/ApiExtractor/tests/testcodeinjection.cpp
index c438e0c37..aeca2d3f4 100644
--- a/sources/shiboken2/ApiExtractor/tests/testcodeinjection.cpp
+++ b/sources/shiboken2/ApiExtractor/tests/testcodeinjection.cpp
@@ -71,8 +71,8 @@ void TestCodeInjections::testReadFile()
<value-type name='A'>\n\
<conversion-rule ") + attribute + QLatin1String("/>\n\
<inject-code class='target' ") + attribute + QLatin1String("/>\n\
+ <value-type name='B'/>\n\
</value-type>\n\
- <value-type name='A::B'/>\n\
</typesystem>\n");
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode.toLocal8Bit().constData()));
QVERIFY(!builder.isNull());
diff --git a/sources/shiboken2/ApiExtractor/tests/testresolvetype.cpp b/sources/shiboken2/ApiExtractor/tests/testresolvetype.cpp
index 2e5a5759a..2203f3648 100644
--- a/sources/shiboken2/ApiExtractor/tests/testresolvetype.cpp
+++ b/sources/shiboken2/ApiExtractor/tests/testresolvetype.cpp
@@ -44,13 +44,15 @@ void TestResolveType::testResolveReturnTypeFromParentScope()
C* method();\n\
};\n\
};";
- const char* xmlCode = "\n\
- <typesystem package='Foo'>\n\
- <namespace-type name='A'/>\n\
- <value-type name='A::B'/>\n\
- <value-type name='A::B::C'/>\n\
- <value-type name='A::D'/>\n\
- </typesystem>";
+ const char* xmlCode = R"XML(
+ <typesystem package='Foo'>
+ <namespace-type name='A'>
+ <value-type name='B'>
+ <value-type name='C'/>
+ </value-type>
+ <value-type name='D'/>
+ </namespace-type>
+ </typesystem>)XML";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
QVERIFY(!builder.isNull());
AbstractMetaClassList classes = builder->classes();
diff --git a/sources/shiboken2/ApiExtractor/tests/testtemplates.cpp b/sources/shiboken2/ApiExtractor/tests/testtemplates.cpp
index 59b601f3b..5191cb38d 100644
--- a/sources/shiboken2/ApiExtractor/tests/testtemplates.cpp
+++ b/sources/shiboken2/ApiExtractor/tests/testtemplates.cpp
@@ -63,9 +63,10 @@ namespace Internet {
<typesystem package='Package.Internet'>
<load-typesystem name='%1' generate='no'/>
<container-type name='QList' type='list'/>
- <namespace-type name='Internet' generate='no'/>
- <value-type name='Internet::Url'/>
- <value-type name='Internet::Bookmarks'/>
+ <namespace-type name='Internet' generate='no'>
+ <value-type name='Url'/>
+ <value-type name='Bookmarks'/>
+ </namespace-type>
</typesystem>)XML").arg(file.fileName());
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, qPrintable(xmlCode1), false));
@@ -97,11 +98,12 @@ namespace Namespace {
const char xmlCode[] = R"XML(
<typesystem package="Package">
<container-type name='QList' type='list'/>
- <namespace-type name='Namespace'/>
- <enum-type name='Namespace::SomeEnum'/>
+ <namespace-type name='Namespace'>
+ <enum-type name='SomeEnum'/>
+ <object-type name='A' generate='no'/>
+ <object-type name='B'/>
+ </namespace-type>
<object-type name='Base'/>
- <object-type name='Namespace::A' generate='no'/>
- <object-type name='Namespace::B'/>
</typesystem>)XML";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
@@ -211,8 +213,9 @@ struct List {
const char xmlCode[] = R"XML(
<typesystem package='Package'>
- <container-type name='List' type='list'/>
- <value-type name='List::Iterator'/>
+ <container-type name='List' type='list'>
+ <value-type name='Iterator'/>
+ </container-type>
</typesystem>)XML";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
@@ -324,11 +327,12 @@ template<SomeEnum type> struct Future {};
const char xmlCode[] = R"XML(
<typesystem package='Package'>
- <namespace-type name='Namespace'/>
- <enum-type name='Namespace::SomeEnum'/>
- <value-type name='Namespace::A' generate='no'/>
- <value-type name='Namespace::B'/>
- <value-type name='Namespace::Future' generate='no'/>
+ <namespace-type name='Namespace'>
+ <enum-type name='SomeEnum'/>
+ <value-type name='A' generate='no'/>
+ <value-type name='B'/>
+ <value-type name='Future' generate='no'/>
+ </namespace-type>
</typesystem>)XML";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
diff --git a/sources/shiboken2/ApiExtractor/typesystemparser.cpp b/sources/shiboken2/ApiExtractor/typesystemparser.cpp
index 57ceb357f..5440de5c0 100644
--- a/sources/shiboken2/ApiExtractor/typesystemparser.cpp
+++ b/sources/shiboken2/ApiExtractor/typesystemparser.cpp
@@ -191,200 +191,200 @@ static EnumType functionName(QStringView needle, EnumType defaultValue = default
ENUM_LOOKUP_BEGIN(TypeSystem::AllowThread, Qt::CaseInsensitive,
allowThreadFromAttribute, TypeSystem::AllowThread::Unspecified)
{
- {QStringViewLiteral("yes"), TypeSystem::AllowThread::Allow},
- {QStringViewLiteral("true"), TypeSystem::AllowThread::Allow},
- {QStringViewLiteral("auto"), TypeSystem::AllowThread::Auto},
- {QStringViewLiteral("no"), TypeSystem::AllowThread::Disallow},
- {QStringViewLiteral("false"), TypeSystem::AllowThread::Disallow},
+ {u"yes", TypeSystem::AllowThread::Allow},
+ {u"true", TypeSystem::AllowThread::Allow},
+ {u"auto", TypeSystem::AllowThread::Auto},
+ {u"no", TypeSystem::AllowThread::Disallow},
+ {u"false", TypeSystem::AllowThread::Disallow},
};
ENUM_LOOKUP_LINEAR_SEARCH()
ENUM_LOOKUP_BEGIN(TypeSystem::Language, Qt::CaseInsensitive,
languageFromAttribute, TypeSystem::NoLanguage)
{
- {QStringViewLiteral("all"), TypeSystem::All}, // sorted!
- {QStringViewLiteral("constructors"), TypeSystem::Constructors},
- {QStringViewLiteral("destructor-function"), TypeSystem::DestructorFunction},
- {QStringViewLiteral("interface"), TypeSystem::Interface},
- {QStringViewLiteral("library-initializer"), TypeSystem::PackageInitializer},
- {QStringViewLiteral("native"), TypeSystem::NativeCode}, // em algum lugar do cpp
- {QStringViewLiteral("shell"), TypeSystem::ShellCode}, // coloca no header, mas antes da declaracao da classe
- {QStringViewLiteral("shell-declaration"), TypeSystem::ShellDeclaration},
- {QStringViewLiteral("target"), TypeSystem::TargetLangCode} // em algum lugar do cpp
+ {u"all", TypeSystem::All}, // sorted!
+ {u"constructors", TypeSystem::Constructors},
+ {u"destructor-function", TypeSystem::DestructorFunction},
+ {u"interface", TypeSystem::Interface},
+ {u"library-initializer", TypeSystem::PackageInitializer},
+ {u"native", TypeSystem::NativeCode}, // em algum lugar do cpp
+ {u"shell", TypeSystem::ShellCode}, // coloca no header, mas antes da declaracao da classe
+ {u"shell-declaration", TypeSystem::ShellDeclaration},
+ {u"target", TypeSystem::TargetLangCode} // em algum lugar do cpp
};
ENUM_LOOKUP_BINARY_SEARCH()
ENUM_LOOKUP_BEGIN(TypeSystem::Ownership, Qt::CaseInsensitive,
ownershipFromFromAttribute, TypeSystem::InvalidOwnership)
{
- {QStringViewLiteral("target"), TypeSystem::TargetLangOwnership},
- {QStringViewLiteral("c++"), TypeSystem::CppOwnership},
- {QStringViewLiteral("default"), TypeSystem::DefaultOwnership}
+ {u"target", TypeSystem::TargetLangOwnership},
+ {u"c++", TypeSystem::CppOwnership},
+ {u"default", TypeSystem::DefaultOwnership}
};
ENUM_LOOKUP_LINEAR_SEARCH()
ENUM_LOOKUP_BEGIN(AddedFunction::Access, Qt::CaseInsensitive,
addedFunctionAccessFromAttribute, AddedFunction::InvalidAccess)
{
- {QStringViewLiteral("public"), AddedFunction::Public},
- {QStringViewLiteral("protected"), AddedFunction::Protected},
+ {u"public", AddedFunction::Public},
+ {u"protected", AddedFunction::Protected},
};
ENUM_LOOKUP_LINEAR_SEARCH()
ENUM_LOOKUP_BEGIN(Modification::Modifiers, Qt::CaseSensitive,
modifierFromAttribute, Modification::InvalidModifier)
{
- {QStringViewLiteral("private"), Modification::Private},
- {QStringViewLiteral("public"), Modification::Public},
- {QStringViewLiteral("protected"), Modification::Protected},
- {QStringViewLiteral("friendly"), Modification::Friendly},
- {QStringViewLiteral("rename"), Modification::Rename},
- {QStringViewLiteral("final"), Modification::Final},
- {QStringViewLiteral("non-final"), Modification::NonFinal}
+ {u"private", Modification::Private},
+ {u"public", Modification::Public},
+ {u"protected", Modification::Protected},
+ {u"friendly", Modification::Friendly},
+ {u"rename", Modification::Rename},
+ {u"final", Modification::Final},
+ {u"non-final", Modification::NonFinal}
};
ENUM_LOOKUP_LINEAR_SEARCH()
ENUM_LOOKUP_BEGIN(ReferenceCount::Action, Qt::CaseInsensitive,
referenceCountFromAttribute, ReferenceCount::Invalid)
{
- {QStringViewLiteral("add"), ReferenceCount::Add},
- {QStringViewLiteral("add-all"), ReferenceCount::AddAll},
- {QStringViewLiteral("remove"), ReferenceCount::Remove},
- {QStringViewLiteral("set"), ReferenceCount::Set},
- {QStringViewLiteral("ignore"), ReferenceCount::Ignore}
+ {u"add", ReferenceCount::Add},
+ {u"add-all", ReferenceCount::AddAll},
+ {u"remove", ReferenceCount::Remove},
+ {u"set", ReferenceCount::Set},
+ {u"ignore", ReferenceCount::Ignore}
};
ENUM_LOOKUP_LINEAR_SEARCH()
ENUM_LOOKUP_BEGIN(ArgumentOwner::Action, Qt::CaseInsensitive,
argumentOwnerActionFromAttribute, ArgumentOwner::Invalid)
{
- {QStringViewLiteral("add"), ArgumentOwner::Add},
- {QStringViewLiteral("remove"), ArgumentOwner::Remove}
+ {u"add", ArgumentOwner::Add},
+ {u"remove", ArgumentOwner::Remove}
};
ENUM_LOOKUP_LINEAR_SEARCH()
ENUM_LOOKUP_BEGIN(TypeSystem::CodeSnipPosition, Qt::CaseInsensitive,
codeSnipPositionFromAttribute, TypeSystem::CodeSnipPositionInvalid)
{
- {QStringViewLiteral("beginning"), TypeSystem::CodeSnipPositionBeginning},
- {QStringViewLiteral("end"), TypeSystem::CodeSnipPositionEnd},
- {QStringViewLiteral("declaration"), TypeSystem::CodeSnipPositionDeclaration},
- {QStringViewLiteral("prototype-initialization"), TypeSystem::CodeSnipPositionPrototypeInitialization},
- {QStringViewLiteral("constructor-initialization"), TypeSystem::CodeSnipPositionConstructorInitialization},
- {QStringViewLiteral("constructor"), TypeSystem::CodeSnipPositionConstructor}
+ {u"beginning", TypeSystem::CodeSnipPositionBeginning},
+ {u"end", TypeSystem::CodeSnipPositionEnd},
+ {u"declaration", TypeSystem::CodeSnipPositionDeclaration},
+ {u"prototype-initialization", TypeSystem::CodeSnipPositionPrototypeInitialization},
+ {u"constructor-initialization", TypeSystem::CodeSnipPositionConstructorInitialization},
+ {u"constructor", TypeSystem::CodeSnipPositionConstructor}
};
ENUM_LOOKUP_LINEAR_SEARCH()
ENUM_LOOKUP_BEGIN(Include::IncludeType, Qt::CaseInsensitive,
locationFromAttribute, Include::InvalidInclude)
{
- {QStringViewLiteral("global"), Include::IncludePath},
- {QStringViewLiteral("local"), Include::LocalPath},
- {QStringViewLiteral("target"), Include::TargetLangImport}
+ {u"global", Include::IncludePath},
+ {u"local", Include::LocalPath},
+ {u"target", Include::TargetLangImport}
};
ENUM_LOOKUP_LINEAR_SEARCH()
ENUM_LOOKUP_BEGIN(TypeSystem::DocModificationMode, Qt::CaseInsensitive,
docModificationFromAttribute, TypeSystem::DocModificationInvalid)
{
- {QStringViewLiteral("append"), TypeSystem::DocModificationAppend},
- {QStringViewLiteral("prepend"), TypeSystem::DocModificationPrepend},
- {QStringViewLiteral("replace"), TypeSystem::DocModificationReplace}
+ {u"append", TypeSystem::DocModificationAppend},
+ {u"prepend", TypeSystem::DocModificationPrepend},
+ {u"replace", TypeSystem::DocModificationReplace}
};
ENUM_LOOKUP_LINEAR_SEARCH()
ENUM_LOOKUP_BEGIN(ContainerTypeEntry::Type, Qt::CaseSensitive,
containerTypeFromAttribute, ContainerTypeEntry::NoContainer)
{
- {QStringViewLiteral("list"), ContainerTypeEntry::ListContainer},
- {QStringViewLiteral("string-list"), ContainerTypeEntry::StringListContainer},
- {QStringViewLiteral("linked-list"), ContainerTypeEntry::LinkedListContainer},
- {QStringViewLiteral("vector"), ContainerTypeEntry::VectorContainer},
- {QStringViewLiteral("stack"), ContainerTypeEntry::StackContainer},
- {QStringViewLiteral("queue"), ContainerTypeEntry::QueueContainer},
- {QStringViewLiteral("set"), ContainerTypeEntry::SetContainer},
- {QStringViewLiteral("map"), ContainerTypeEntry::MapContainer},
- {QStringViewLiteral("multi-map"), ContainerTypeEntry::MultiMapContainer},
- {QStringViewLiteral("hash"), ContainerTypeEntry::HashContainer},
- {QStringViewLiteral("multi-hash"), ContainerTypeEntry::MultiHashContainer},
- {QStringViewLiteral("pair"), ContainerTypeEntry::PairContainer}
+ {u"list", ContainerTypeEntry::ListContainer},
+ {u"string-list", ContainerTypeEntry::StringListContainer},
+ {u"linked-list", ContainerTypeEntry::LinkedListContainer},
+ {u"vector", ContainerTypeEntry::VectorContainer},
+ {u"stack", ContainerTypeEntry::StackContainer},
+ {u"queue", ContainerTypeEntry::QueueContainer},
+ {u"set", ContainerTypeEntry::SetContainer},
+ {u"map", ContainerTypeEntry::MapContainer},
+ {u"multi-map", ContainerTypeEntry::MultiMapContainer},
+ {u"hash", ContainerTypeEntry::HashContainer},
+ {u"multi-hash", ContainerTypeEntry::MultiHashContainer},
+ {u"pair", ContainerTypeEntry::PairContainer}
};
ENUM_LOOKUP_LINEAR_SEARCH()
ENUM_LOOKUP_BEGIN(TypeRejection::MatchType, Qt::CaseSensitive,
typeRejectionFromAttribute, TypeRejection::Invalid)
{
- {QStringViewLiteral("class"), TypeRejection::ExcludeClass},
- {QStringViewLiteral("function-name"), TypeRejection::Function},
- {QStringViewLiteral("field-name"), TypeRejection::Field},
- {QStringViewLiteral("enum-name"), TypeRejection::Enum },
- {QStringViewLiteral("argument-type"), TypeRejection::ArgumentType},
- {QStringViewLiteral("return-type"), TypeRejection::ReturnType}
+ {u"class", TypeRejection::ExcludeClass},
+ {u"function-name", TypeRejection::Function},
+ {u"field-name", TypeRejection::Field},
+ {u"enum-name", TypeRejection::Enum },
+ {u"argument-type", TypeRejection::ArgumentType},
+ {u"return-type", TypeRejection::ReturnType}
};
ENUM_LOOKUP_LINEAR_SEARCH()
ENUM_LOOKUP_BEGIN(TypeSystem::ExceptionHandling, Qt::CaseSensitive,
exceptionHandlingFromAttribute, TypeSystem::ExceptionHandling::Unspecified)
{
- {QStringViewLiteral("no"), TypeSystem::ExceptionHandling::Off},
- {QStringViewLiteral("false"), TypeSystem::ExceptionHandling::Off},
- {QStringViewLiteral("auto-off"), TypeSystem::ExceptionHandling::AutoDefaultToOff},
- {QStringViewLiteral("auto-on"), TypeSystem::ExceptionHandling::AutoDefaultToOn},
- {QStringViewLiteral("yes"), TypeSystem::ExceptionHandling::On},
- {QStringViewLiteral("true"), TypeSystem::ExceptionHandling::On},
+ {u"no", TypeSystem::ExceptionHandling::Off},
+ {u"false", TypeSystem::ExceptionHandling::Off},
+ {u"auto-off", TypeSystem::ExceptionHandling::AutoDefaultToOff},
+ {u"auto-on", TypeSystem::ExceptionHandling::AutoDefaultToOn},
+ {u"yes", TypeSystem::ExceptionHandling::On},
+ {u"true", TypeSystem::ExceptionHandling::On},
};
ENUM_LOOKUP_LINEAR_SEARCH()
ENUM_LOOKUP_BEGIN(StackElement::ElementType, Qt::CaseInsensitive,
elementFromTag, StackElement::None)
{
- {QStringViewLiteral("access"), StackElement::Access}, // sorted!
- {QStringViewLiteral("add-conversion"), StackElement::AddConversion},
- {QStringViewLiteral("add-function"), StackElement::AddFunction},
- {QStringViewLiteral("argument-map"), StackElement::ArgumentMap},
- {QStringViewLiteral("array"), StackElement::Array},
- {QStringViewLiteral("container-type"), StackElement::ContainerTypeEntry},
- {QStringViewLiteral("conversion-rule"), StackElement::ConversionRule},
- {QStringViewLiteral("custom-constructor"), StackElement::CustomMetaConstructor},
- {QStringViewLiteral("custom-destructor"), StackElement::CustomMetaDestructor},
- {QStringViewLiteral("custom-type"), StackElement::CustomTypeEntry},
- {QStringViewLiteral("define-ownership"), StackElement::DefineOwnership},
- {QStringViewLiteral("enum-type"), StackElement::EnumTypeEntry},
- {QStringViewLiteral("extra-includes"), StackElement::ExtraIncludes},
- {QStringViewLiteral("function"), StackElement::FunctionTypeEntry},
- {QStringViewLiteral("include"), StackElement::Include},
- {QStringViewLiteral("inject-code"), StackElement::InjectCode},
- {QStringViewLiteral("inject-documentation"), StackElement::InjectDocumentation},
- {QStringViewLiteral("insert-template"), StackElement::TemplateInstanceEnum},
- {QStringViewLiteral("interface-type"), StackElement::InterfaceTypeEntry},
- {QStringViewLiteral("load-typesystem"), StackElement::LoadTypesystem},
- {QStringViewLiteral("modify-argument"), StackElement::ModifyArgument},
- {QStringViewLiteral("modify-documentation"), StackElement::ModifyDocumentation},
- {QStringViewLiteral("modify-field"), StackElement::ModifyField},
- {QStringViewLiteral("modify-function"), StackElement::ModifyFunction},
- {QStringViewLiteral("namespace-type"), StackElement::NamespaceTypeEntry},
- {QStringViewLiteral("native-to-target"), StackElement::NativeToTarget},
- {QStringViewLiteral("no-null-pointer"), StackElement::NoNullPointers},
- {QStringViewLiteral("object-type"), StackElement::ObjectTypeEntry},
- {QStringViewLiteral("parent"), StackElement::ParentOwner},
- {QStringViewLiteral("primitive-type"), StackElement::PrimitiveTypeEntry},
- {QStringViewLiteral("reference-count"), StackElement::ReferenceCount},
- {QStringViewLiteral("reject-enum-value"), StackElement::RejectEnumValue},
- {QStringViewLiteral("rejection"), StackElement::Rejection},
- {QStringViewLiteral("remove"), StackElement::Removal},
- {QStringViewLiteral("remove-argument"), StackElement::RemoveArgument},
- {QStringViewLiteral("remove-default-expression"), StackElement::RemoveDefaultExpression},
- {QStringViewLiteral("rename"), StackElement::Rename},
- {QStringViewLiteral("replace"), StackElement::Replace},
- {QStringViewLiteral("replace-default-expression"), StackElement::ReplaceDefaultExpression},
- {QStringViewLiteral("replace-type"), StackElement::ReplaceType},
- {QStringViewLiteral("smart-pointer-type"), StackElement::SmartPointerTypeEntry},
- {QStringViewLiteral("suppress-warning"), StackElement::SuppressedWarning},
- {QStringViewLiteral("target-to-native"), StackElement::TargetToNative},
- {QStringViewLiteral("template"), StackElement::Template},
- {QStringViewLiteral("typedef-type"), StackElement::TypedefTypeEntry},
- {QStringViewLiteral("typesystem"), StackElement::Root},
- {QStringViewLiteral("value-type"), StackElement::ValueTypeEntry},
+ {u"access", StackElement::Access}, // sorted!
+ {u"add-conversion", StackElement::AddConversion},
+ {u"add-function", StackElement::AddFunction},
+ {u"argument-map", StackElement::ArgumentMap},
+ {u"array", StackElement::Array},
+ {u"container-type", StackElement::ContainerTypeEntry},
+ {u"conversion-rule", StackElement::ConversionRule},
+ {u"custom-constructor", StackElement::CustomMetaConstructor},
+ {u"custom-destructor", StackElement::CustomMetaDestructor},
+ {u"custom-type", StackElement::CustomTypeEntry},
+ {u"define-ownership", StackElement::DefineOwnership},
+ {u"enum-type", StackElement::EnumTypeEntry},
+ {u"extra-includes", StackElement::ExtraIncludes},
+ {u"function", StackElement::FunctionTypeEntry},
+ {u"include", StackElement::Include},
+ {u"inject-code", StackElement::InjectCode},
+ {u"inject-documentation", StackElement::InjectDocumentation},
+ {u"insert-template", StackElement::TemplateInstanceEnum},
+ {u"interface-type", StackElement::InterfaceTypeEntry},
+ {u"load-typesystem", StackElement::LoadTypesystem},
+ {u"modify-argument", StackElement::ModifyArgument},
+ {u"modify-documentation", StackElement::ModifyDocumentation},
+ {u"modify-field", StackElement::ModifyField},
+ {u"modify-function", StackElement::ModifyFunction},
+ {u"namespace-type", StackElement::NamespaceTypeEntry},
+ {u"native-to-target", StackElement::NativeToTarget},
+ {u"no-null-pointer", StackElement::NoNullPointers},
+ {u"object-type", StackElement::ObjectTypeEntry},
+ {u"parent", StackElement::ParentOwner},
+ {u"primitive-type", StackElement::PrimitiveTypeEntry},
+ {u"reference-count", StackElement::ReferenceCount},
+ {u"reject-enum-value", StackElement::RejectEnumValue},
+ {u"rejection", StackElement::Rejection},
+ {u"remove", StackElement::Removal},
+ {u"remove-argument", StackElement::RemoveArgument},
+ {u"remove-default-expression", StackElement::RemoveDefaultExpression},
+ {u"rename", StackElement::Rename},
+ {u"replace", StackElement::Replace},
+ {u"replace-default-expression", StackElement::ReplaceDefaultExpression},
+ {u"replace-type", StackElement::ReplaceType},
+ {u"smart-pointer-type", StackElement::SmartPointerTypeEntry},
+ {u"suppress-warning", StackElement::SuppressedWarning},
+ {u"target-to-native", StackElement::TargetToNative},
+ {u"template", StackElement::Template},
+ {u"typedef-type", StackElement::TypedefTypeEntry},
+ {u"typesystem", StackElement::Root},
+ {u"value-type", StackElement::ValueTypeEntry},
};
ENUM_LOOKUP_BINARY_SEARCH()
@@ -991,17 +991,17 @@ static bool convertRemovalAttribute(QStringView remove, Modification& mod, QStri
if (remove.isEmpty())
return true;
#ifdef QTBUG_69389_FIXED
- if (remove.compare(QStringViewLiteral("all"), Qt::CaseInsensitive) == 0) {
+ if (remove.compare(u"all", Qt::CaseInsensitive) == 0) {
#else
- if (QtPrivate::compareStrings(remove, QStringViewLiteral("all"), Qt::CaseInsensitive) == 0) {
+ if (QtPrivate::compareStrings(remove, u"all", Qt::CaseInsensitive) == 0) {
#endif
mod.removal = TypeSystem::All;
return true;
}
#ifdef QTBUG_69389_FIXED
- if (remove.compare(QStringViewLiteral("target"), Qt::CaseInsensitive) == 0) {
+ if (remove.compare(u"target", Qt::CaseInsensitive) == 0) {
#else
- if (QtPrivate::compareStrings(remove, QStringViewLiteral("target"), Qt::CaseInsensitive) == 0) {
+ if (QtPrivate::compareStrings(remove, u"target", Qt::CaseInsensitive) == 0) {
#endif
mod.removal = TypeSystem::TargetLangAndNativeCode;
return true;
@@ -1044,7 +1044,7 @@ void TypeSystemParser::applyCommonAttributes(TypeEntry *type, QXmlStreamAttribut
{
type->setCodeGeneration(m_generate);
const int revisionIndex =
- indexOfAttribute(*attributes, QStringViewLiteral("revision"));
+ indexOfAttribute(*attributes, u"revision");
if (revisionIndex != -1)
type->setRevision(attributes->takeAt(revisionIndex).value().toInt());
}
@@ -1084,7 +1084,7 @@ FlagsTypeEntry *
m_database->addType(ftype);
const int revisionIndex =
- indexOfAttribute(*attributes, QStringViewLiteral("flags-revision"));
+ indexOfAttribute(*attributes, u"flags-revision");
ftype->setRevision(revisionIndex != -1
? attributes->takeAt(revisionIndex).value().toInt()
: enumEntry->revision());
@@ -1181,7 +1181,7 @@ ContainerTypeEntry *
const QString &name, const QVersionNumber &since,
QXmlStreamAttributes *attributes)
{
- const int typeIndex = indexOfAttribute(*attributes, QStringViewLiteral("type"));
+ const int typeIndex = indexOfAttribute(*attributes, u"type");
if (typeIndex == -1) {
m_error = QLatin1String("no 'type' attribute specified");
return nullptr;
@@ -1323,7 +1323,7 @@ ValueTypeEntry *
auto *typeEntry = new ValueTypeEntry(name, since);
applyCommonAttributes(typeEntry, attributes);
const int defaultCtIndex =
- indexOfAttribute(*attributes, QStringViewLiteral("default-constructor"));
+ indexOfAttribute(*attributes, u"default-constructor");
if (defaultCtIndex != -1)
typeEntry->setDefaultConstructor(attributes->takeAt(defaultCtIndex).value().toString());
return typeEntry;
@@ -1887,7 +1887,7 @@ bool TypeSystemParser::parseNoNullPointer(const QXmlStreamReader &reader,
lastArgMod.noNullPointers = true;
const int defaultValueIndex =
- indexOfAttribute(*attributes, QStringViewLiteral("default-value"));
+ indexOfAttribute(*attributes, u"default-value");
if (defaultValueIndex != -1) {
const QXmlStreamAttribute attribute = attributes->takeAt(defaultValueIndex);
qCWarning(lcShiboken, "%s",
@@ -2266,7 +2266,7 @@ bool TypeSystemParser::parseReplaceDefaultExpression(const QXmlStreamReader &,
m_error = QLatin1String("Replace default expression only allowed as child of argument modification");
return false;
}
- const int withIndex = indexOfAttribute(*attributes, QStringViewLiteral("with"));
+ const int withIndex = indexOfAttribute(*attributes, u"with");
if (withIndex == -1 || attributes->at(withIndex).value().isEmpty()) {
m_error = QLatin1String("Default expression replaced with empty string. Use remove-default-expression instead.");
return false;
diff --git a/sources/shiboken2/generator/generator.cpp b/sources/shiboken2/generator/generator.cpp
index 6da9fd933..7c6e921c7 100644
--- a/sources/shiboken2/generator/generator.cpp
+++ b/sources/shiboken2/generator/generator.cpp
@@ -760,7 +760,7 @@ DefaultValue Generator::minimalConstructor(const AbstractMetaClass *metaClass) c
bool simple = true;
bool suitable = true;
for (int i = 0, size = arguments.size();
- suitable && i < size && !arguments.at(i)->hasDefaultValueExpression(); ++i) {
+ suitable && i < size && !arguments.at(i)->hasOriginalDefaultValueExpression(); ++i) {
const AbstractMetaArgument *arg = arguments.at(i);
const TypeEntry *aType = arg->type()->typeEntry();
suitable &= aType != cType;
@@ -777,11 +777,12 @@ DefaultValue Generator::minimalConstructor(const AbstractMetaClass *metaClass) c
bool ok = true;
for (int i =0, size = arguments.size(); ok && i < size; ++i) {
const AbstractMetaArgument *arg = arguments.at(i);
- if (arg->hasDefaultValueExpression()) {
- if (arg->hasModifiedDefaultValueExpression())
- args << arg->defaultValueExpression(); // Spell out modified values
+ if (arg->hasModifiedDefaultValueExpression()) {
+ args << arg->defaultValueExpression(); // Spell out modified values
break;
}
+ if (arg->hasOriginalDefaultValueExpression())
+ break;
auto argValue = minimalConstructor(arg->type());
ok &= argValue.isValid();
args << argValue.constructorParameter();
diff --git a/sources/shiboken2/generator/shiboken2/cppgenerator.cpp b/sources/shiboken2/generator/shiboken2/cppgenerator.cpp
index 61429b383..5460fd7c7 100644
--- a/sources/shiboken2/generator/shiboken2/cppgenerator.cpp
+++ b/sources/shiboken2/generator/shiboken2/cppgenerator.cpp
@@ -317,7 +317,10 @@ void CppGenerator::generateClass(QTextStream &s, GeneratorContext &classContext)
s << "#include <pyside.h>" << endl;
s << "#include <destroylistener.h>" << endl;
s << "#include <qapp_macro.h>" << endl;
- }
+ s << endl;
+ s << "QT_WARNING_DISABLE_DEPRECATED" << endl;
+ s << endl;
+ }
s << "#include <typeinfo>" << endl;
if (usePySideExtensions() && metaClass->isQObject()) {
@@ -368,9 +371,6 @@ void CppGenerator::generateClass(QTextStream &s, GeneratorContext &classContext)
if (metaClass->typeEntry()->typeFlags() & ComplexTypeEntry::Deprecated)
s << "#Deprecated" << endl;
- if (usePySideExtensions())
- s << "\nQT_WARNING_DISABLE_DEPRECATED\n";
-
// Use class base namespace
{
const AbstractMetaClass *context = metaClass->enclosingClass();
@@ -1684,7 +1684,7 @@ void CppGenerator::writeConstructorWrapper(QTextStream &s, const AbstractMetaFun
argNamesSet << arg->name();
}
}
- QStringList argNamesList = argNamesSet.toList();
+ QStringList argNamesList = argNamesSet.values();
std::sort(argNamesList.begin(), argNamesList.end());
if (argNamesList.isEmpty()) {
s << INDENT << "const char **argNames{};" << endl;
@@ -1860,18 +1860,19 @@ void CppGenerator::writeMethodWrapper(QTextStream &s, const AbstractMetaFunction
// For custom classes, operations like __radd__ and __rmul__
// will enter an infinite loop.
if (rfunc->isBinaryOperator() && revOpName.contains(QLatin1String("shift"))) {
+ s << INDENT << "Shiboken::AutoDecRef attrName(Py_BuildValue(\"s\", \"" << revOpName << "\"));" << endl;
s << INDENT << "if (!isReverse" << endl;
{
Indentation indent(INDENT);
s << INDENT << "&& Shiboken::Object::checkType(" << PYTHON_ARG << ")" << endl;
s << INDENT << "&& !PyObject_TypeCheck(" << PYTHON_ARG << ", self->ob_type)" << endl;
- s << INDENT << "&& PyObject_HasAttrString(" << PYTHON_ARG << ", const_cast<char *>(\"" << revOpName << "\"))) {" << endl;
+ s << INDENT << "&& PyObject_HasAttr(" << PYTHON_ARG << ", attrName)) {" << endl;
// This PyObject_CallMethod call will emit lots of warnings like
// "deprecated conversion from string constant to char *" during compilation
// due to the method name argument being declared as "char *" instead of "const char *"
// issue 6952 http://bugs.python.org/issue6952
- s << INDENT << "PyObject *revOpMethod = PyObject_GetAttrString(" << PYTHON_ARG << ", const_cast<char *>(\"" << revOpName << "\"));" << endl;
+ s << INDENT << "PyObject *revOpMethod = PyObject_GetAttr(" << PYTHON_ARG << ", attrName);" << endl;
s << INDENT << "if (revOpMethod && PyCallable_Check(revOpMethod)) {" << endl;
{
Indentation indent(INDENT);
@@ -2154,6 +2155,8 @@ void CppGenerator::writeTypeCheck(QTextStream &s, const AbstractMetaType *argTyp
QString customCheck;
if (!customType.isEmpty()) {
AbstractMetaType *metaType;
+ // PYSIDE-795: Note: XML-Overrides are handled in this shibokengenerator function!
+ // This enables iterables for QMatrix4x4 for instance.
customCheck = guessCPythonCheckFunction(customType, &metaType);
if (metaType)
argType = metaType;
@@ -2939,6 +2942,9 @@ void CppGenerator::writePythonToCppConversionFunctions(QTextStream &s,
typeCheck = QLatin1String("PyType_Check(%in)");
else if (pyTypeName == QLatin1String("PyObject"))
typeCheck = QLatin1String("PyObject_TypeCheck(%in, &PyBaseObject_Type)");
+ // PYSIDE-795: We abuse PySequence for iterables
+ else if (pyTypeName == QLatin1String("PySequence"))
+ typeCheck = QLatin1String("Shiboken::String::checkIterable(%in)");
else if (pyTypeName.startsWith(QLatin1String("Py")))
typeCheck = pyTypeName + QLatin1String("_Check(%in)");
}
@@ -3039,29 +3045,31 @@ void CppGenerator::writeNamedArgumentResolution(QTextStream &s, const AbstractMe
QString pyArgName = usePyArgs ? pythonArgsAt(pyArgIndex) : QLatin1String(PYTHON_ARG);
s << INDENT << "keyName = Py_BuildValue(\"s\",\"" << arg->name() << "\");" << endl;
s << INDENT << "if (PyDict_Contains(kwds, keyName)) {" << endl;
- s << INDENT << "value = PyDict_GetItemString(kwds, \"" << arg->name() << "\");" << endl;
- s << INDENT << "if (value && " << pyArgName << ") {" << endl;
{
Indentation indent(INDENT);
- s << INDENT << pyErrString.arg(arg->name()) << endl;
- s << INDENT << returnStatement(m_currentErrorCode) << endl;
- }
- s << INDENT << INDENT << "} else if (value) {" << endl;
- {
- Indentation indent(INDENT);
- s << INDENT << pyArgName << " = value;" << endl;
- s << INDENT << "if (!";
- writeTypeCheck(s, arg->type(), pyArgName, isNumber(arg->type()->typeEntry()), func->typeReplaced(arg->argumentIndex() + 1));
- s << ')' << endl;
+ s << INDENT << "value = PyDict_GetItem(kwds, keyName);" << endl;
+ s << INDENT << "if (value && " << pyArgName << ") {" << endl;
+ {
+ Indentation indent(INDENT);
+ s << INDENT << pyErrString.arg(arg->name()) << endl;
+ s << INDENT << returnStatement(m_currentErrorCode) << endl;
+ }
+ s << INDENT << '}' << endl;
+ s << INDENT << "if (value) {" << endl;
{
Indentation indent(INDENT);
- s << INDENT << "goto " << cpythonFunctionName(func) << "_TypeError;" << endl;
+ s << INDENT << pyArgName << " = value;" << endl;
+ s << INDENT << "if (!";
+ writeTypeCheck(s, arg->type(), pyArgName, isNumber(arg->type()->typeEntry()), func->typeReplaced(arg->argumentIndex() + 1));
+ s << ')' << endl;
+ {
+ Indentation indent(INDENT);
+ s << INDENT << "goto " << cpythonFunctionName(func) << "_TypeError;" << endl;
+ }
}
+ s << INDENT << '}' << endl;
}
s << INDENT << '}' << endl;
- if (arg != args.constLast())
- s << INDENT;
- s << "}" << endl;
}
}
s << INDENT << '}' << endl;
@@ -4563,23 +4571,6 @@ void CppGenerator::writeMethodDefinition(QTextStream &s, const AbstractMetaFunct
s << ',' << endl;
}
-static QString resolveRetOrArgType(const AbstractMetaType *someType)
-{
- QString strRetArg;
- if (CppGenerator::isCString(someType)) {
- strRetArg = QLatin1String("str");
- } else if (someType->isPrimitive()) {
- auto ptp = static_cast<const PrimitiveTypeEntry *>(someType->typeEntry());
- while (ptp->referencedTypeEntry())
- ptp = ptp->referencedTypeEntry();
- strRetArg = ptp->name();
- } else {
- strRetArg = someType->fullName();
- }
- strRetArg.replace(QLatin1String("::"), QLatin1String("."));
- return strRetArg;
-}
-
void CppGenerator::writeSignatureInfo(QTextStream &s, const AbstractMetaFunctionList &overloads)
{
OverloadData overloadData(overloads, this);
@@ -4593,11 +4584,7 @@ void CppGenerator::writeSignatureInfo(QTextStream &s, const AbstractMetaFunction
QStringList args;
const AbstractMetaArgumentList &arguments = f->arguments();
for (const AbstractMetaArgument *arg : arguments) {
- AbstractMetaType *argType = getTypeWithoutContainer(arg->type());
- QString strArg = resolveRetOrArgType(arg->type());
- // PYSIDE-921: Handle container returntypes correctly.
- if (argType != arg->type())
- strArg += QLatin1Char('[') + resolveRetOrArgType(argType) + QLatin1Char(']');
+ QString strArg = arg->type()->pythonSignature();
if (!arg->defaultValueExpression().isEmpty()) {
strArg += QLatin1Char('=');
QString e = arg->defaultValueExpression();
@@ -4612,12 +4599,8 @@ void CppGenerator::writeSignatureInfo(QTextStream &s, const AbstractMetaFunction
if (multiple)
s << idx-- << ':';
s << funcName << '(' << args.join(QLatin1Char(',')) << ')';
- AbstractMetaType *returnType = getTypeWithoutContainer(f->type());
- // PYSIDE-921: Handle container returntypes correctly.
- if (returnType != f->type())
- s << "->" << resolveRetOrArgType(f->type()) << '[' << resolveRetOrArgType(returnType) << ']';
- else if (returnType)
- s << "->" << resolveRetOrArgType(returnType);
+ if (f->type())
+ s << "->" << f->type()->pythonSignature();
s << endl;
}
}
@@ -4634,6 +4617,15 @@ void CppGenerator::writeEnumsInitialization(QTextStream &s, AbstractMetaEnumList
}
}
+static QString mangleName(QString name)
+{
+ if ( name == QLatin1String("None")
+ || name == QLatin1String("False")
+ || name == QLatin1String("True"))
+ name += QLatin1Char('_');
+ return name;
+}
+
void CppGenerator::writeEnumInitialization(QTextStream &s, const AbstractMetaEnum *cppEnum)
{
const AbstractMetaClass *enclosingClass = getProperEnclosingClassForEnum(cppEnum);
@@ -4713,7 +4705,7 @@ void CppGenerator::writeEnumInitialization(QTextStream &s, const AbstractMetaEnu
Indentation indent(INDENT);
s << INDENT << "PyObject *anonEnumItem = PyInt_FromLong(" << enumValueText << ");" << endl;
s << INDENT << "if (PyDict_SetItemString(reinterpret_cast<PyTypeObject *>(reinterpret_cast<SbkObjectType *>(" << enclosingObjectVariable
- << "))->tp_dict, \"" << enumValue->name() << "\", anonEnumItem) < 0)" << endl;
+ << "))->tp_dict, \"" << mangleName(enumValue->name()) << "\", anonEnumItem) < 0)" << endl;
{
Indentation indent(INDENT);
s << INDENT << returnStatement(m_currentErrorCode) << endl;
@@ -4722,7 +4714,7 @@ void CppGenerator::writeEnumInitialization(QTextStream &s, const AbstractMetaEnu
}
s << INDENT << '}' << endl;
} else {
- s << INDENT << "if (PyModule_AddIntConstant(module, \"" << enumValue->name() << "\", ";
+ s << INDENT << "if (PyModule_AddIntConstant(module, \"" << mangleName(enumValue->name()) << "\", ";
s << enumValueText << ") < 0)" << endl;
{
Indentation indent(INDENT);
@@ -4735,7 +4727,7 @@ void CppGenerator::writeEnumInitialization(QTextStream &s, const AbstractMetaEnu
s << ((enclosingClass || hasUpperEnclosingClass) ? "createScopedEnumItem" : "createGlobalEnumItem");
s << '(' << enumVarTypeObj << ',' << endl;
Indentation indent(INDENT);
- s << INDENT << enclosingObjectVariable << ", \"" << enumValue->name() << "\", ";
+ s << INDENT << enclosingObjectVariable << ", \"" << mangleName(enumValue->name()) << "\", ";
s << enumValueText << "))" << endl;
s << INDENT << returnStatement(m_currentErrorCode) << endl;
}
@@ -4744,7 +4736,7 @@ void CppGenerator::writeEnumInitialization(QTextStream &s, const AbstractMetaEnu
s << INDENT << "if (!Shiboken::Enum::createScopedEnumItem("
<< enumVarTypeObj << ',' << endl;
Indentation indent(INDENT);
- s << INDENT << enumVarTypeObj<< ", \"" << enumValue->name() << "\", "
+ s << INDENT << enumVarTypeObj<< ", \"" << mangleName(enumValue->name()) << "\", "
<< enumValueText << "))" << endl
<< INDENT << returnStatement(m_currentErrorCode) << endl;
}
@@ -5567,10 +5559,11 @@ bool CppGenerator::finishGeneration()
{
Indentation indentation(INDENT);
s << INDENT << "PyObject *pyType = reinterpret_cast<PyObject *>(" << cppApiVariableName() << "[i]);" << endl;
- s << INDENT << "if (pyType && PyObject_HasAttrString(pyType, \"staticMetaObject\"))"<< endl;
+ s << INDENT << "Shiboken::AutoDecRef attrName(Py_BuildValue(\"s\", \"staticMetaObject\"));" << endl;
+ s << INDENT << "if (pyType && PyObject_HasAttr(pyType, attrName))"<< endl;
{
Indentation indentation(INDENT);
- s << INDENT << "PyObject_SetAttrString(pyType, \"staticMetaObject\", Py_None);" << endl;
+ s << INDENT << "PyObject_SetAttr(pyType, attrName, Py_None);" << endl;
}
}
s << INDENT << "}" << endl;
@@ -6034,7 +6027,7 @@ QString CppGenerator::writeReprFunction(QTextStream &s,
s << INDENT << "str.replace(0, idx, Py_TYPE(self)->tp_name);" << endl;
}
s << INDENT << "str = str.trimmed();" << endl;
- s << INDENT << "PyObject *mod = PyDict_GetItemString(Py_TYPE(self)->tp_dict, \"__module__\");" << endl;
+ s << INDENT << "PyObject *mod = PyDict_GetItem(Py_TYPE(self)->tp_dict, Shiboken::PyMagicName::module());" << endl;
// PYSIDE-595: The introduction of heap types has the side effect that the module name
// is always prepended to the type name. Therefore the strchr check:
s << INDENT << "if (mod && !strchr(str, '.'))" << endl;
diff --git a/sources/shiboken2/generator/shiboken2/headergenerator.cpp b/sources/shiboken2/generator/shiboken2/headergenerator.cpp
index 8a2c56232..e47c37523 100644
--- a/sources/shiboken2/generator/shiboken2/headergenerator.cpp
+++ b/sources/shiboken2/generator/shiboken2/headergenerator.cpp
@@ -454,6 +454,11 @@ bool HeaderGenerator::finishGeneration()
// TODO-CONVERTER ------------------------------------------------------------------------------
macrosStream << "// Macros for type check" << endl;
+
+ if (usePySideExtensions()) {
+ typeFunctions << "QT_WARNING_PUSH" << endl;
+ typeFunctions << "QT_WARNING_DISABLE_DEPRECATED" << endl;
+ }
for (const AbstractMetaEnum *cppEnum : qAsConst(globalEnums)) {
if (cppEnum->isAnonymous() || cppEnum->isPrivate())
continue;
@@ -489,6 +494,8 @@ bool HeaderGenerator::finishGeneration()
includes << classType->include();
writeSbkTypeFunction(typeFunctions, metaType);
}
+ if (usePySideExtensions())
+ typeFunctions << "QT_WARNING_POP" << endl;
QString moduleHeaderFileName(outputDirectory()
+ QDir::separator() + subDirectoryForPackage(packageName())
diff --git a/sources/shiboken2/generator/shiboken2/overloaddata.cpp b/sources/shiboken2/generator/shiboken2/overloaddata.cpp
index 5c3d7d0b8..5f74ee64d 100644
--- a/sources/shiboken2/generator/shiboken2/overloaddata.cpp
+++ b/sources/shiboken2/generator/shiboken2/overloaddata.cpp
@@ -520,7 +520,7 @@ void OverloadData::addOverload(const AbstractMetaFunction *func)
for (int i = 0; m_headOverloadData->m_minArgs > 0 && i < origNumArgs; i++) {
if (func->argumentRemoved(i + 1))
continue;
- if (!ShibokenGenerator::getDefaultValue(func, func->arguments().at(i)).isEmpty()) {
+ if (func->arguments().at(i)->hasDefaultValueExpression()) {
int fixedArgIndex = i - removed;
if (fixedArgIndex < m_headOverloadData->m_minArgs)
m_headOverloadData->m_minArgs = fixedArgIndex;
@@ -576,7 +576,7 @@ QStringList OverloadData::returnTypes() const
else
retTypes << QLatin1String("void");
}
- return QStringList(retTypes.toList());
+ return retTypes.values();
}
bool OverloadData::hasNonVoidReturnType() const
@@ -754,7 +754,7 @@ const AbstractMetaFunction *OverloadData::getFunctionWithDefaultValue() const
if (func->argumentRemoved(i + 1))
removedArgs++;
}
- if (!ShibokenGenerator::getDefaultValue(func, func->arguments().at(m_argPos + removedArgs)).isEmpty())
+ if (func->arguments().at(m_argPos + removedArgs)->hasDefaultValueExpression())
return func;
}
return nullptr;
@@ -771,7 +771,7 @@ QVector<int> OverloadData::invalidArgumentLengths() const
if (func->argumentRemoved(i+1)) {
offset++;
} else {
- if (!ShibokenGenerator::getDefaultValue(func, args[i]).isEmpty())
+ if (args.at(i)->hasDefaultValueExpression())
validArgLengths << i-offset;
}
}
@@ -820,7 +820,7 @@ QPair<int, int> OverloadData::getMinMaxArguments(const AbstractMetaFunctionList
if (func->argumentRemoved(j + 1))
continue;
int fixedArgIndex = j - removed;
- if (fixedArgIndex < minArgs && !ShibokenGenerator::getDefaultValue(func, func->arguments().at(j)).isEmpty())
+ if (fixedArgIndex < minArgs && func->arguments().at(j)->hasDefaultValueExpression())
minArgs = fixedArgIndex;
}
}
@@ -967,7 +967,7 @@ QString OverloadData::dumpGraph() const
const AbstractMetaArgument *arg = argument(func);
if (!arg)
continue;
- QString argDefault = ShibokenGenerator::getDefaultValue(func, arg);
+ QString argDefault = arg->defaultValueExpression();
if (!argDefault.isEmpty() ||
argDefault != arg->originalDefaultValueExpression()) {
s << "<tr><td bgcolor=\"gray\" align=\"right\">f" << functionNumber(func);
@@ -1038,7 +1038,7 @@ bool OverloadData::hasArgumentWithDefaultValue(const AbstractMetaFunction *func)
for (const AbstractMetaArgument *arg : arguments) {
if (func->argumentRemoved(arg->argumentIndex() + 1))
continue;
- if (!ShibokenGenerator::getDefaultValue(func, arg).isEmpty())
+ if (arg->hasDefaultValueExpression())
return true;
}
return false;
@@ -1049,7 +1049,7 @@ AbstractMetaArgumentList OverloadData::getArgumentsWithDefaultValues(const Abstr
AbstractMetaArgumentList args;
const AbstractMetaArgumentList &arguments = func->arguments();
for (AbstractMetaArgument *arg : arguments) {
- if (ShibokenGenerator::getDefaultValue(func, arg).isEmpty()
+ if (!arg->hasDefaultValueExpression()
|| func->argumentRemoved(arg->argumentIndex() + 1))
continue;
args << arg;
diff --git a/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp b/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp
index 2a8eefba6..67137369c 100644
--- a/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp
+++ b/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp
@@ -571,7 +571,7 @@ QString ShibokenGenerator::guessScopeForDefaultFlagsValue(const AbstractMetaFunc
QString ShibokenGenerator::guessScopeForDefaultValue(const AbstractMetaFunction *func,
const AbstractMetaArgument *arg) const
{
- QString value = getDefaultValue(func, arg);
+ QString value = arg->defaultValueExpression();
if (value.isEmpty()
|| arg->hasModifiedDefaultValueExpression()
@@ -1255,6 +1255,11 @@ QString ShibokenGenerator::cpythonCheckFunction(const TypeEntry *type, bool gene
QString ShibokenGenerator::guessCPythonCheckFunction(const QString &type, AbstractMetaType **metaType)
{
*metaType = nullptr;
+ // PYSIDE-795: We abuse PySequence for iterables.
+ // This part handles the overrides in the XML files.
+ if (type == QLatin1String("PySequence"))
+ return QLatin1String("Shiboken::String::checkIterable");
+
if (type == QLatin1String("PyTypeObject"))
return QLatin1String("PyType_Check");
@@ -2306,7 +2311,7 @@ AbstractMetaType *ShibokenGenerator::buildAbstractMetaTypeFromString(QString typ
auto it = m_metaTypeFromStringCache.find(typeSignature);
if (it == m_metaTypeFromStringCache.end()) {
AbstractMetaType *metaType =
- AbstractMetaBuilder::translateType(typeSignature, nullptr, true, errorMessage);
+ AbstractMetaBuilder::translateType(typeSignature, nullptr, {}, errorMessage);
if (Q_UNLIKELY(!metaType)) {
if (errorMessage)
errorMessage->prepend(msgCannotBuildMetaType(typeSignature));
@@ -2708,22 +2713,6 @@ bool ShibokenGenerator::pythonFunctionWrapperUsesListOfArguments(const OverloadD
|| overloadData.hasArgumentWithDefaultValue();
}
-QString ShibokenGenerator::getDefaultValue(const AbstractMetaFunction *func, const AbstractMetaArgument *arg)
-{
- if (!arg->defaultValueExpression().isEmpty())
- return arg->defaultValueExpression();
-
- //Check modifications
- const FunctionModificationList &mods = func->modifications();
- for (const FunctionModification &m : mods) {
- for (const ArgumentModification &am : m.argument_mods) {
- if (am.index == (arg->argumentIndex() + 1))
- return am.replacedDefaultExpression;
- }
- }
- return QString();
-}
-
void ShibokenGenerator::writeMinimalConstructorExpression(QTextStream &s, const AbstractMetaType *type, const QString &defaultCtor)
{
if (!defaultCtor.isEmpty()) {
diff --git a/sources/shiboken2/generator/shiboken2/shibokengenerator.h b/sources/shiboken2/generator/shiboken2/shibokengenerator.h
index 84b3137b8..7970ceb94 100644
--- a/sources/shiboken2/generator/shiboken2/shibokengenerator.h
+++ b/sources/shiboken2/generator/shiboken2/shibokengenerator.h
@@ -71,11 +71,6 @@ public:
const char *name() const override { return "Shiboken"; }
- /**
- * Helper function to find for argument default value
- */
- static QString getDefaultValue(const AbstractMetaFunction *func, const AbstractMetaArgument *arg);
-
/// Returns a list of all ancestor classes for the given class.
AbstractMetaClassList getAllAncestors(const AbstractMetaClass *metaClass) const;
diff --git a/sources/shiboken2/libshiboken/CMakeLists.txt b/sources/shiboken2/libshiboken/CMakeLists.txt
index 7cbb22978..a38da8d89 100644
--- a/sources/shiboken2/libshiboken/CMakeLists.txt
+++ b/sources/shiboken2/libshiboken/CMakeLists.txt
@@ -30,8 +30,8 @@ configure_file("${CMAKE_CURRENT_SOURCE_DIR}/embed/signature_bootstrap.py"
"${CMAKE_CURRENT_BINARY_DIR}/embed/signature_bootstrap.py" @ONLY)
add_custom_command(
- OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/embed/signature_bootstrap.inc"
- OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/embed/signature.inc"
+ 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"
@@ -53,6 +53,7 @@ sbkconverter.cpp
sbkenum.cpp
sbkmodule.cpp
sbkstring.cpp
+sbkstaticstrings.cpp
bindingmanager.cpp
threadstatesaver.cpp
shibokenbuffer.cpp
@@ -62,8 +63,8 @@ pep384impl.cpp
voidptr.cpp
typespec.cpp
bufferprocs_py37.cpp
-embed/signature_bootstrap.inc
-embed/signature.inc
+embed/signature_bootstrap_inc.h
+embed/signature_inc.h
)
get_numpy_location()
@@ -129,6 +130,7 @@ install(FILES
python25compat.h
sbkdbg.h
sbkstring.h
+ sbkstaticstrings.h
shiboken.h
shibokenmacros.h
threadstatesaver.h
diff --git a/sources/shiboken2/libshiboken/basewrapper.cpp b/sources/shiboken2/libshiboken/basewrapper.cpp
index 9d233b847..000035627 100644
--- a/sources/shiboken2/libshiboken/basewrapper.cpp
+++ b/sources/shiboken2/libshiboken/basewrapper.cpp
@@ -44,6 +44,7 @@
#include "sbkconverter.h"
#include "sbkenum.h"
#include "sbkstring.h"
+#include "sbkstaticstrings_p.h"
#include "autodecref.h"
#include "gilstate.h"
#include <string>
@@ -160,11 +161,10 @@ patch_tp_new_wrapper(PyTypeObject *type)
* The old tp_new_wrapper is added to all types that have tp_new.
* We patch that with a version that ignores the heaptype flag.
*/
- static PyObject *__new__ = nullptr;
+ auto newMethod = Shiboken::PyMagicName::new_();
if (old_tp_new_wrapper == nullptr) {
- if ((__new__ = Py_BuildValue("s", "__new__")) == nullptr)
- return -1;
- PyObject *func = PyDict_GetItem(PyType_Type.tp_dict, __new__);
+ PyObject *func = PyDict_GetItem(PyType_Type.tp_dict, newMethod);
+ assert(func);
PyCFunctionObject *pycf_ob = reinterpret_cast<PyCFunctionObject *>(func);
old_tp_new_wrapper = reinterpret_cast<ternaryfunc>(pycf_ob->m_ml->ml_meth);
}
@@ -172,7 +172,7 @@ patch_tp_new_wrapper(PyTypeObject *type)
Py_ssize_t i, n = PyTuple_GET_SIZE(mro);
for (i = 0; i < n; i++) {
type = reinterpret_cast<PyTypeObject *>(PyTuple_GET_ITEM(mro, i));
- PyObject *existing = PyDict_GetItem(type->tp_dict, __new__);
+ PyObject *existing = PyDict_GetItem(type->tp_dict, newMethod);
if (existing && PyCFunction_Check(existing)
&& type->tp_flags & Py_TPFLAGS_HEAPTYPE) {
auto *pycf_ob = reinterpret_cast<PyCFunctionObject *>(existing);
@@ -182,7 +182,7 @@ patch_tp_new_wrapper(PyTypeObject *type)
if (existing_wrapper == old_tp_new_wrapper) {
PyObject *ob_type = reinterpret_cast<PyObject *>(type);
Shiboken::AutoDecRef func(PyCFunction_New(tp_new_methoddef, ob_type));
- if (func.isNull() || PyDict_SetItem(type->tp_dict, __new__, func))
+ if (func.isNull() || PyDict_SetItem(type->tp_dict, newMethod, func))
return -1;
}
}
diff --git a/sources/shiboken2/libshiboken/embed/embedding_generator.py b/sources/shiboken2/libshiboken/embed/embedding_generator.py
index 77aa5c329..15f63649b 100644
--- a/sources/shiboken2/libshiboken/embed/embedding_generator.py
+++ b/sources/shiboken2/libshiboken/embed/embedding_generator.py
@@ -88,7 +88,7 @@ def create_zipfile(limited_api):
and make a chunked base64 encoded file from it.
"""
zip_name = "signature.zip"
- inc_name = "signature.inc"
+ inc_name = "signature_inc.h"
flag = '-b' if sys.version_info >= (3,) else ''
os.chdir(work_dir)
@@ -131,7 +131,7 @@ def create_zipfile(limited_api):
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", "w") as inc:
+ 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)
diff --git a/sources/shiboken2/libshiboken/helper.cpp b/sources/shiboken2/libshiboken/helper.cpp
index fac72d56f..013080b6e 100644
--- a/sources/shiboken2/libshiboken/helper.cpp
+++ b/sources/shiboken2/libshiboken/helper.cpp
@@ -39,6 +39,7 @@
#include "helper.h"
#include "sbkstring.h"
+#include "sbkstaticstrings.h"
#include <stdarg.h>
#ifdef _WIN32
@@ -78,7 +79,7 @@ bool listToArgcArgv(PyObject *argList, int *argc, char ***argv, const char *defa
if (hasEmptyArgList) {
// Try to get the script name
PyObject *globals = PyEval_GetGlobals();
- PyObject *appName = PyDict_GetItemString(globals, "__file__");
+ PyObject *appName = PyDict_GetItem(globals, Shiboken::PyMagicName::file());
(*argv)[0] = strdup(appName ? Shiboken::String::toCString(appName) : defaultAppName);
} else {
for (int i = 0; i < numArgs; ++i) {
diff --git a/sources/shiboken2/libshiboken/pep384impl.cpp b/sources/shiboken2/libshiboken/pep384impl.cpp
index fe7157d24..5729100bf 100644
--- a/sources/shiboken2/libshiboken/pep384impl.cpp
+++ b/sources/shiboken2/libshiboken/pep384impl.cpp
@@ -39,6 +39,8 @@
#include "pep384impl.h"
#include "autodecref.h"
+#include "sbkstaticstrings.h"
+#include "sbkstaticstrings_p.h"
extern "C"
{
@@ -85,14 +87,15 @@ static PyGetSetDef probe_getseters[] = {
#define probe_tp_str make_dummy(2)
#define probe_tp_traverse make_dummy(3)
#define probe_tp_clear make_dummy(4)
+#define probe_tp_iternext make_dummy(5)
#define probe_tp_methods probe_methoddef
#define probe_tp_getset probe_getseters
-#define probe_tp_descr_get make_dummy(7)
-#define probe_tp_init make_dummy(8)
-#define probe_tp_alloc make_dummy(9)
-#define probe_tp_new make_dummy(10)
-#define probe_tp_free make_dummy(11)
-#define probe_tp_is_gc make_dummy(12)
+#define probe_tp_descr_get make_dummy(8)
+#define probe_tp_init make_dummy(9)
+#define probe_tp_alloc make_dummy(10)
+#define probe_tp_new make_dummy(11)
+#define probe_tp_free make_dummy(12)
+#define probe_tp_is_gc make_dummy(13)
#define probe_tp_name "type.probe"
#define probe_tp_basicsize make_dummy_int(42)
@@ -102,6 +105,7 @@ static PyType_Slot typeprobe_slots[] = {
{Py_tp_str, probe_tp_str},
{Py_tp_traverse, probe_tp_traverse},
{Py_tp_clear, probe_tp_clear},
+ {Py_tp_iternext, probe_tp_iternext},
{Py_tp_methods, probe_tp_methods},
{Py_tp_getset, probe_tp_getset},
{Py_tp_descr_get, probe_tp_descr_get},
@@ -125,16 +129,16 @@ check_PyTypeObject_valid()
{
auto *obtype = reinterpret_cast<PyObject *>(&PyType_Type);
auto *probe_tp_base = reinterpret_cast<PyTypeObject *>(
- PyObject_GetAttrString(obtype, "__base__"));
- PyObject *probe_tp_bases = PyObject_GetAttrString(obtype, "__bases__");
+ PyObject_GetAttr(obtype, Shiboken::PyMagicName::base()));
+ auto *probe_tp_bases = PyObject_GetAttr(obtype, Shiboken::PyMagicName::bases());
auto *check = reinterpret_cast<PyTypeObject *>(
PyType_FromSpecWithBases(&typeprobe_spec, probe_tp_bases));
auto *typetype = reinterpret_cast<PyTypeObject *>(obtype);
- PyObject *w = PyObject_GetAttrString(obtype, "__weakrefoffset__");
+ PyObject *w = PyObject_GetAttr(obtype, Shiboken::PyMagicName::weakrefoffset());
long probe_tp_weakrefoffset = PyLong_AsLong(w);
- PyObject *d = PyObject_GetAttrString(obtype, "__dictoffset__");
+ PyObject *d = PyObject_GetAttr(obtype, Shiboken::PyMagicName::dictoffset());
long probe_tp_dictoffset = PyLong_AsLong(d);
- PyObject *probe_tp_mro = PyObject_GetAttrString(obtype, "__mro__");
+ PyObject *probe_tp_mro = PyObject_GetAttr(obtype, Shiboken::PyMagicName::mro());
if (false
|| strcmp(probe_tp_name, check->tp_name) != 0
|| probe_tp_basicsize != check->tp_basicsize
@@ -143,6 +147,7 @@ check_PyTypeObject_valid()
|| probe_tp_traverse != check->tp_traverse
|| probe_tp_clear != check->tp_clear
|| probe_tp_weakrefoffset != typetype->tp_weaklistoffset
+ || probe_tp_iternext != check->tp_iternext
|| probe_tp_methods != check->tp_methods
|| probe_tp_getset != check->tp_getset
|| probe_tp_base != typetype->tp_base
@@ -416,9 +421,10 @@ PepRun_GetResult(const char *command, const char *resvar)
PyObject *d, *v, *res;
d = PyDict_New();
- if (d == NULL || PyDict_SetItemString(d, "__builtins__",
- PyEval_GetBuiltins()) < 0)
- return NULL;
+ if (d == nullptr
+ || PyDict_SetItem(d, Shiboken::PyMagicName::builtins(), PyEval_GetBuiltins()) < 0) {
+ return nullptr;
+ }
v = PyRun_String(command, Py_file_input, d, d);
res = v ? PyDict_GetItemString(d, resvar) : NULL;
Py_XDECREF(v);
@@ -457,7 +463,7 @@ PyMethod_New(PyObject *func, PyObject *self)
PyObject *
PyMethod_Function(PyObject *im)
{
- PyObject *ret = PyObject_GetAttrString(im, "__func__");
+ PyObject *ret = PyObject_GetAttr(im, Shiboken::PyMagicName::func());
// We have to return a borrowed reference.
Py_DECREF(ret);
@@ -467,7 +473,7 @@ PyMethod_Function(PyObject *im)
PyObject *
PyMethod_Self(PyObject *im)
{
- PyObject *ret = PyObject_GetAttrString(im, "__self__");
+ PyObject *ret = PyObject_GetAttr(im, Shiboken::PyMagicName::self());
// We have to return a borrowed reference.
// If we don't obey that here, then we get a test error!
@@ -620,8 +626,8 @@ _Pep_PrivateMangle(PyObject *self, PyObject *name)
return name;
}
#endif
- Shiboken::AutoDecRef privateobj(PyObject_GetAttrString(
- reinterpret_cast<PyObject *>(Py_TYPE(self)), "__name__"));
+ Shiboken::AutoDecRef privateobj(PyObject_GetAttr(
+ reinterpret_cast<PyObject *>(Py_TYPE(self)), Shiboken::PyMagicName::name()));
#ifndef Py_LIMITED_API
return _Py_Mangle(privateobj, name);
#else
diff --git a/sources/shiboken2/libshiboken/pep384impl.h b/sources/shiboken2/libshiboken/pep384impl.h
index 93f718988..1aa7e6fc0 100644
--- a/sources/shiboken2/libshiboken/pep384impl.h
+++ b/sources/shiboken2/libshiboken/pep384impl.h
@@ -110,7 +110,7 @@ typedef struct _typeobject {
void *X23; // richcmpfunc tp_richcompare;
Py_ssize_t tp_weaklistoffset;
void *X25; // getiterfunc tp_iter;
- void *X26; // iternextfunc tp_iternext;
+ iternextfunc tp_iternext;
struct PyMethodDef *tp_methods;
void *X28; // struct PyMemberDef *tp_members;
struct PyGetSetDef *tp_getset;
diff --git a/sources/shiboken2/libshiboken/sbkenum.cpp b/sources/shiboken2/libshiboken/sbkenum.cpp
index 2dc785884..71fcf5f64 100644
--- a/sources/shiboken2/libshiboken/sbkenum.cpp
+++ b/sources/shiboken2/libshiboken/sbkenum.cpp
@@ -412,13 +412,6 @@ PyTypeObject *createScopedEnum(SbkObjectType *scope, const char *name, const cha
static PyObject *createEnumItem(PyTypeObject *enumType, const char *itemName, long itemValue)
{
- char mangled[20];
- if (strcmp(itemName, "None") == 0
- || strcmp(itemName, "False") == 0 || strcmp(itemName, "True") == 0) {
- strcpy(mangled, itemName);
- strcat(mangled, "_");
- itemName = mangled;
- }
PyObject *enumItem = newItem(enumType, itemValue, itemName);
if (PyDict_SetItemString(enumType->tp_dict, itemName, enumItem) < 0)
return nullptr;
diff --git a/sources/shiboken2/libshiboken/sbkstaticstrings.cpp b/sources/shiboken2/libshiboken/sbkstaticstrings.cpp
new file mode 100644
index 000000000..3727eb494
--- /dev/null
+++ b/sources/shiboken2/libshiboken/sbkstaticstrings.cpp
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt for Python.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "sbkstaticstrings.h"
+#include "sbkstaticstrings_p.h"
+#include "sbkstring.h"
+
+#define STATIC_STRING_IMPL(funcName, value) \
+PyObject *funcName() \
+{ \
+ static PyObject *const s = Shiboken::String::createStaticString(value); \
+ return s; \
+}
+
+namespace Shiboken
+{
+namespace PyName {
+// exported:
+STATIC_STRING_IMPL(dumps, "dumps")
+STATIC_STRING_IMPL(loads, "loads")
+
+// Internal:
+STATIC_STRING_IMPL(classmethod, "classmethod")
+STATIC_STRING_IMPL(compile, "compile");
+STATIC_STRING_IMPL(function, "function")
+STATIC_STRING_IMPL(marshal, "marshal")
+STATIC_STRING_IMPL(method, "method")
+STATIC_STRING_IMPL(overload, "overload")
+STATIC_STRING_IMPL(staticmethod, "staticmethod")
+} // namespace PyName
+
+namespace PyMagicName {
+// exported:
+STATIC_STRING_IMPL(class_, "__class__")
+STATIC_STRING_IMPL(ecf, "__ecf__")
+STATIC_STRING_IMPL(file, "__file__")
+STATIC_STRING_IMPL(module, "__module__")
+STATIC_STRING_IMPL(name, "__name__")
+
+// Internal:
+STATIC_STRING_IMPL(base, "__base__")
+STATIC_STRING_IMPL(bases, "__bases__")
+STATIC_STRING_IMPL(builtins, "__builtins__")
+STATIC_STRING_IMPL(code, "__code__")
+STATIC_STRING_IMPL(dictoffset, "__dictoffset__")
+STATIC_STRING_IMPL(func, "__func__")
+STATIC_STRING_IMPL(func_kind, "__func_kind__")
+STATIC_STRING_IMPL(iter, "__iter__")
+STATIC_STRING_IMPL(mro, "__mro__")
+STATIC_STRING_IMPL(new_, "__new__")
+STATIC_STRING_IMPL(objclass, "__objclass__")
+STATIC_STRING_IMPL(self, "__self__")
+STATIC_STRING_IMPL(signature, "__signature__")
+STATIC_STRING_IMPL(weakrefoffset, "__weakrefoffset__")
+} // namespace PyMagicName
+} // namespace Shiboken
diff --git a/sources/shiboken2/libshiboken/sbkstaticstrings.h b/sources/shiboken2/libshiboken/sbkstaticstrings.h
new file mode 100644
index 000000000..fa21a8e2c
--- /dev/null
+++ b/sources/shiboken2/libshiboken/sbkstaticstrings.h
@@ -0,0 +1,65 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt for Python.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef SBKSTATICSTRINGS_H
+#define SBKSTATICSTRINGS_H
+
+#include "sbkpython.h"
+#include "shibokenmacros.h"
+
+namespace Shiboken
+{
+// Some often-used strings
+namespace PyName
+{
+LIBSHIBOKEN_API PyObject *dumps();
+LIBSHIBOKEN_API PyObject *loads();
+} // namespace PyName
+
+namespace PyMagicName
+{
+LIBSHIBOKEN_API PyObject *class_();
+LIBSHIBOKEN_API PyObject *ecf();
+LIBSHIBOKEN_API PyObject *file();
+LIBSHIBOKEN_API PyObject *module();
+LIBSHIBOKEN_API PyObject *name();
+} // namespace PyMagicName
+} // namespace Shiboken
+
+#endif // SBKSTATICSTRINGS_H
diff --git a/sources/shiboken2/libshiboken/sbkstaticstrings_p.h b/sources/shiboken2/libshiboken/sbkstaticstrings_p.h
new file mode 100644
index 000000000..42c5585fa
--- /dev/null
+++ b/sources/shiboken2/libshiboken/sbkstaticstrings_p.h
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt for Python.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "sbkpython.h"
+#include "shibokenmacros.h"
+
+namespace Shiboken
+{
+namespace PyName
+{
+PyObject *classmethod();
+PyObject *compile();
+PyObject *function();
+PyObject *marshal();
+PyObject *method();
+PyObject *overload();
+PyObject *staticmethod();
+} // namespace PyName
+namespace PyMagicName
+{
+PyObject *base();
+PyObject *bases();
+PyObject *builtins();
+PyObject *code();
+PyObject *dictoffset();
+PyObject *func();
+PyObject *func_kind();
+PyObject *iter();
+PyObject *module();
+PyObject *mro();
+PyObject *new_();
+PyObject *objclass();
+PyObject *self();
+PyObject *signature();
+PyObject *weakrefoffset();
+} // namespace PyMagicName
+} // namespace Shiboken
diff --git a/sources/shiboken2/libshiboken/sbkstring.cpp b/sources/shiboken2/libshiboken/sbkstring.cpp
index 9ba5be281..4a441222f 100644
--- a/sources/shiboken2/libshiboken/sbkstring.cpp
+++ b/sources/shiboken2/libshiboken/sbkstring.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2018 The Qt Company Ltd.
+** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt for Python.
@@ -38,14 +38,23 @@
****************************************************************************/
#include "sbkstring.h"
+#include "sbkstaticstrings_p.h"
#include "autodecref.h"
+#include <vector>
+
namespace Shiboken
{
namespace String
{
+// PYSIDE-795: Redirecting PySequence to Iterable
+bool checkIterable(PyObject *obj)
+{
+ return PyObject_HasAttr(obj, Shiboken::PyMagicName::iter());
+}
+
bool checkType(PyTypeObject *type)
{
return type == &PyUnicode_Type
@@ -200,6 +209,64 @@ Py_ssize_t len(PyObject *str)
return 0;
}
-} // namespace String
+///////////////////////////////////////////////////////////////////////
+//
+// Implementation of efficient Python strings
+// ------------------------------------------
+//
+// Instead of repetitively executing
+//
+// PyObject *attr = PyObject_GetAttrString(obj, "__name__");
+//
+// a helper of the form
+//
+// PyObject *name()
+// {
+// static PyObject *const s = Shiboken::String::createStaticString("__name__");
+// return result;
+// }
+//
+// can now be implemented, which registers the string into a static set avoiding
+// repetitive string creation. The resulting code looks like:
+//
+// PyObject *attr = PyObject_GetAttr(obj, name());
+//
+// Missing:
+// There is no finalization for the string structures, yet.
+// But this is a global fault in shiboken. We are missing a true
+// finalization like in all other modules.
+
+using StaticStrings = std::vector<PyObject *>;
+static StaticStrings &staticStrings()
+{
+ static StaticStrings result;
+ return result;
+}
+
+PyObject *createStaticString(const char *str)
+{
+#if PY_VERSION_HEX >= 0x03000000
+ PyObject *result = PyUnicode_InternFromString(str);
+#else
+ PyObject *result = PyString_InternFromString(str);
+#endif
+ if (result == nullptr) {
+ // This error is never checked, but also very unlikely. Report and exit.
+ PyErr_Print();
+ Py_FatalError("unexpected error in createStaticString()");
+ }
+ staticStrings().push_back(result);
+ return result;
+}
+
+void finalizeStaticStrings() // Currently unused
+{
+ auto &list = staticStrings();
+ for (auto s : list)
+ Py_DECREF(s);
+ list.clear();
+}
+
+} // namespace String
} // namespace Shiboken
diff --git a/sources/shiboken2/libshiboken/sbkstring.h b/sources/shiboken2/libshiboken/sbkstring.h
index 7f434e1b9..84d7768c5 100644
--- a/sources/shiboken2/libshiboken/sbkstring.h
+++ b/sources/shiboken2/libshiboken/sbkstring.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt for Python.
@@ -43,17 +43,12 @@
#include "sbkpython.h"
#include "shibokenmacros.h"
-#if PY_MAJOR_VERSION >= 3
- #define SBK_BYTES_NAME "bytes"
-#else
- #define SBK_BYTES_NAME "str"
-#endif
-
namespace Shiboken
{
namespace String
{
LIBSHIBOKEN_API bool check(PyObject *obj);
+ LIBSHIBOKEN_API bool checkIterable(PyObject *obj);
LIBSHIBOKEN_API bool checkType(PyTypeObject *obj);
LIBSHIBOKEN_API bool checkChar(PyObject *obj);
LIBSHIBOKEN_API bool isConvertible(PyObject *obj);
@@ -65,6 +60,7 @@ namespace String
LIBSHIBOKEN_API PyObject *fromStringAndSize(const char *str, Py_ssize_t size);
LIBSHIBOKEN_API int compare(PyObject *val1, const char *val2);
LIBSHIBOKEN_API Py_ssize_t len(PyObject *str);
+ LIBSHIBOKEN_API PyObject *createStaticString(const char *str);
} // namespace String
} // namespace Shiboken
diff --git a/sources/shiboken2/libshiboken/shiboken.h b/sources/shiboken2/libshiboken/shiboken.h
index 1356670aa..0d2d6b0a6 100644
--- a/sources/shiboken2/libshiboken/shiboken.h
+++ b/sources/shiboken2/libshiboken/shiboken.h
@@ -52,6 +52,7 @@
#include "sbkenum.h"
#include "sbkmodule.h"
#include "sbkstring.h"
+#include "sbkstaticstrings.h"
#include "shibokenmacros.h"
#include "shibokenbuffer.h"
diff --git a/sources/shiboken2/libshiboken/signature.cpp b/sources/shiboken2/libshiboken/signature.cpp
index 0afdbcdc9..5430ab064 100644
--- a/sources/shiboken2/libshiboken/signature.cpp
+++ b/sources/shiboken2/libshiboken/signature.cpp
@@ -39,6 +39,8 @@
#include "basewrapper.h"
#include "autodecref.h"
+#include "sbkstaticstrings.h"
+#include "sbkstaticstrings_p.h"
extern "C"
{
@@ -51,11 +53,11 @@ extern "C"
// These constants were needed in former versions of the module:
#define PYTHON_HAS_QUALNAME (PY_VERSION_HEX >= 0x03030000)
-#define PYTHON_HAS_UNICODE (PY_VERSION_HEX >= 0x03000000)
#define PYTHON_HAS_WEAKREF_PYCFUNCTION (PY_VERSION_HEX >= 0x030500A0)
#define PYTHON_IS_PYTHON3 (PY_VERSION_HEX >= 0x03000000)
#define PYTHON_HAS_KEYWORDONLY (PYTHON_IS_PYTHON3)
#define PYTHON_USES_PERCENT_V_FORMAT (PYTHON_IS_PYTHON3)
+#define PYTHON_USES_D_COMMON (PY_VERSION_HEX >= 0x03020000)
#define PYTHON_HAS_DESCR_REDUCE (PY_VERSION_HEX >= 0x03040000)
#define PYTHON_HAS_METH_REDUCE (PYTHON_HAS_DESCR_REDUCE)
#define PYTHON_NEEDS_ITERATOR_FLAG (!PYTHON_IS_PYTHON3)
@@ -64,7 +66,7 @@ extern "C"
#define PYTHON_HAS_INT_AND_LONG (!PYTHON_IS_PYTHON3)
// These constants are still in use:
-#define PYTHON_USES_D_COMMON (PY_VERSION_HEX >= 0x03020000)
+#define PYTHON_USES_UNICODE (PY_VERSION_HEX >= 0x03000000)
typedef struct safe_globals_struc {
// init part 1: get arg_dict
@@ -77,17 +79,18 @@ typedef struct safe_globals_struc {
PyObject *create_signature_func;
PyObject *seterror_argument_func;
PyObject *make_helptext_func;
+ PyObject *finish_import_func;
} safe_globals_struc, *safe_globals;
static safe_globals pyside_globals = nullptr;
static PyObject *GetTypeKey(PyObject *ob);
-static PyObject *GetSignature_Function(PyObject *, const char *);
-static PyObject *GetSignature_TypeMod(PyObject *, const char *);
-static PyObject *GetSignature_Wrapper(PyObject *, const char *);
+static PyObject *GetSignature_Function(PyObject *, PyObject *);
+static PyObject *GetSignature_TypeMod(PyObject *, PyObject *);
+static PyObject *GetSignature_Wrapper(PyObject *, PyObject *);
static PyObject *get_signature(PyObject *self, PyObject *args);
-static PyObject *get_signature_intern(PyObject *ob, const char *modifier);
+static PyObject *get_signature_intern(PyObject *ob, PyObject *modifier);
static PyObject *PySide_BuildSignatureProps(PyObject *class_mod);
@@ -107,10 +110,10 @@ CreateSignature(PyObject *props, PyObject *key)
const_cast<char *>("(OO)"), props, key);
}
-typedef PyObject *(*signaturefunc)(PyObject *, const char *);
+typedef PyObject *(*signaturefunc)(PyObject *, PyObject *);
static PyObject *
-_get_written_signature(signaturefunc sf, PyObject *ob, const char *modifier)
+_get_written_signature(signaturefunc sf, PyObject *ob, PyObject *modifier)
{
/*
* Be a writable Attribute, but have a computed value.
@@ -133,19 +136,19 @@ _get_written_signature(signaturefunc sf, PyObject *ob, const char *modifier)
}
static PyObject *
-pyside_cf_get___signature__(PyObject *func, const char *modifier)
+pyside_cf_get___signature__(PyObject *func, PyObject *modifier)
{
init_module_2();
return _get_written_signature(GetSignature_Function, func, modifier);
}
static PyObject *
-pyside_sm_get___signature__(PyObject *sm, const char *modifier)
+pyside_sm_get___signature__(PyObject *sm, PyObject *modifier)
{
init_module_2();
- Shiboken::AutoDecRef func(PyObject_GetAttrString(sm, "__func__"));
+ Shiboken::AutoDecRef func(PyObject_GetAttr(sm, Shiboken::PyMagicName::func()));
if (Py_TYPE(func) == PepFunction_TypePtr)
- return PyObject_GetAttrString(func, "__signature__");
+ return PyObject_GetAttr(func, Shiboken::PyMagicName::signature());
return _get_written_signature(GetSignature_Function, func, modifier);
}
@@ -157,7 +160,7 @@ _get_class_of_cf(PyObject *ob_cf)
selftype = PyDict_GetItem(pyside_globals->map_dict, ob_cf);
if (selftype == nullptr) {
// This must be an overloaded function that we handled special.
- Shiboken::AutoDecRef special(Py_BuildValue("(Os)", ob_cf, "overload"));
+ Shiboken::AutoDecRef special(Py_BuildValue("(OO)", ob_cf, Shiboken::PyName::overload()));
selftype = PyDict_GetItem(pyside_globals->map_dict, special);
if (selftype == nullptr) {
// This is probably a module function. We will return type(None).
@@ -175,15 +178,15 @@ _get_class_of_cf(PyObject *ob_cf)
static PyObject *
_get_class_of_sm(PyObject *ob_sm)
{
- Shiboken::AutoDecRef func(PyObject_GetAttrString(ob_sm, "__func__"));
+ Shiboken::AutoDecRef func(PyObject_GetAttr(ob_sm, Shiboken::PyMagicName::func()));
return _get_class_of_cf(func);
}
static PyObject *
_get_class_of_descr(PyObject *ob)
{
- Shiboken::AutoDecRef func_name(PyObject_GetAttrString(ob, "__name__"));
- return PyObject_GetAttrString(ob, "__objclass__");
+ Shiboken::AutoDecRef func_name(PyObject_GetAttr(ob, Shiboken::PyMagicName::name()));
+ return PyObject_GetAttr(ob, Shiboken::PyMagicName::objclass());
}
static PyObject *
@@ -215,10 +218,10 @@ get_funcname(PyObject *ob)
{
PyObject *func = ob;
if (Py_TYPE(ob) == PepStaticMethod_TypePtr)
- func = PyObject_GetAttrString(ob, "__func__");
+ func = PyObject_GetAttr(ob, Shiboken::PyMagicName::func());
else
Py_INCREF(func);
- PyObject *func_name = PyObject_GetAttrString(func, "__name__");
+ PyObject *func_name = PyObject_GetAttr(func, Shiboken::PyMagicName::name());
Py_DECREF(func);
if (func_name == nullptr)
Py_FatalError("unexpected name problem in compute_name_key");
@@ -286,7 +289,7 @@ name_key_to_func(PyObject *ob)
}
static PyObject *
-pyside_md_get___signature__(PyObject *ob_md, const char *modifier)
+pyside_md_get___signature__(PyObject *ob_md, PyObject *modifier)
{
init_module_2();
Shiboken::AutoDecRef func(name_key_to_func(ob_md));
@@ -298,14 +301,14 @@ pyside_md_get___signature__(PyObject *ob_md, const char *modifier)
}
static PyObject *
-pyside_wd_get___signature__(PyObject *ob, const char *modifier)
+pyside_wd_get___signature__(PyObject *ob, PyObject *modifier)
{
init_module_2();
return _get_written_signature(GetSignature_Wrapper, ob, modifier);
}
static PyObject *
-pyside_tp_get___signature__(PyObject *obtype_mod, const char *modifier)
+pyside_tp_get___signature__(PyObject *obtype_mod, PyObject *modifier)
{
init_module_2();
return _get_written_signature(GetSignature_TypeMod, obtype_mod, modifier);
@@ -313,7 +316,7 @@ pyside_tp_get___signature__(PyObject *obtype_mod, const char *modifier)
// forward
static PyObject *
-GetSignature_Cached(PyObject *props, const char *func_kind, const char *modifier);
+GetSignature_Cached(PyObject *props, PyObject *func_kind, PyObject *modifier);
static PyObject *
GetTypeKey(PyObject *ob)
@@ -331,8 +334,8 @@ GetTypeKey(PyObject *ob)
*
* This is the PyCFunction behavior, as opposed to Python functions.
*/
- Shiboken::AutoDecRef class_name(PyObject_GetAttrString(ob, "__name__"));
- Shiboken::AutoDecRef module_name(PyObject_GetAttrString(ob, "__module__"));
+ Shiboken::AutoDecRef class_name(PyObject_GetAttr(ob, Shiboken::PyMagicName::name()));
+ Shiboken::AutoDecRef module_name(PyObject_GetAttr(ob, Shiboken::PyMagicName::module()));
if (module_name.isNull())
PyErr_Clear();
@@ -363,7 +366,7 @@ TypeKey_to_PropsDict(PyObject *type_key, PyObject *obtype)
}
static PyObject *
-GetSignature_Function(PyObject *obfunc, const char *modifier)
+GetSignature_Function(PyObject *obfunc, PyObject *modifier)
{
// make sure that we look into PyCFunction, only...
if (Py_TYPE(obfunc) == PepFunction_TypePtr)
@@ -375,29 +378,29 @@ GetSignature_Function(PyObject *obfunc, const char *modifier)
PyObject *dict = TypeKey_to_PropsDict(type_key, obtype_mod);
if (dict == nullptr)
return nullptr;
- Shiboken::AutoDecRef func_name(PyObject_GetAttrString(obfunc, "__name__"));
+ Shiboken::AutoDecRef func_name(PyObject_GetAttr(obfunc, Shiboken::PyMagicName::name()));
PyObject *props = !func_name.isNull() ? PyDict_GetItem(dict, func_name) : nullptr;
if (props == nullptr)
Py_RETURN_NONE;
int flags = PyCFunction_GET_FLAGS(obfunc);
- const char *func_kind;
+ PyObject *func_kind;
if (PyModule_Check(obtype_mod))
- func_kind = "function";
+ func_kind = Shiboken::PyName::function();
else if (flags & METH_CLASS)
- func_kind = "classmethod";
+ func_kind = Shiboken::PyName::classmethod();
else if (flags & METH_STATIC)
- func_kind = "staticmethod";
+ func_kind = Shiboken::PyName::staticmethod();
else
- func_kind = "method";
+ func_kind = Shiboken::PyName::method();
return GetSignature_Cached(props, func_kind, modifier);
}
static PyObject *
-GetSignature_Wrapper(PyObject *ob, const char *modifier)
+GetSignature_Wrapper(PyObject *ob, PyObject *modifier)
{
- Shiboken::AutoDecRef func_name(PyObject_GetAttrString(ob, "__name__"));
- Shiboken::AutoDecRef objclass(PyObject_GetAttrString(ob, "__objclass__"));
+ Shiboken::AutoDecRef func_name(PyObject_GetAttr(ob, Shiboken::PyMagicName::name()));
+ Shiboken::AutoDecRef objclass(PyObject_GetAttr(ob, Shiboken::PyMagicName::objclass()));
Shiboken::AutoDecRef class_key(GetTypeKey(objclass));
if (func_name.isNull() || objclass.isNull() || class_key.isNull())
@@ -408,13 +411,13 @@ GetSignature_Wrapper(PyObject *ob, const char *modifier)
PyObject *props = PyDict_GetItem(dict, func_name);
if (props == nullptr)
Py_RETURN_NONE;
- return GetSignature_Cached(props, "method", modifier);
+ return GetSignature_Cached(props, Shiboken::PyName::method(), modifier);
}
static PyObject *
-GetSignature_TypeMod(PyObject *ob, const char *modifier)
+GetSignature_TypeMod(PyObject *ob, PyObject *modifier)
{
- Shiboken::AutoDecRef ob_name(PyObject_GetAttrString(ob, "__name__"));
+ Shiboken::AutoDecRef ob_name(PyObject_GetAttr(ob, Shiboken::PyMagicName::name()));
Shiboken::AutoDecRef ob_key(GetTypeKey(ob));
PyObject *dict = TypeKey_to_PropsDict(ob_key, ob);
@@ -423,19 +426,26 @@ GetSignature_TypeMod(PyObject *ob, const char *modifier)
PyObject *props = PyDict_GetItem(dict, ob_name);
if (props == nullptr)
Py_RETURN_NONE;
- return GetSignature_Cached(props, "method", modifier);
+ return GetSignature_Cached(props, Shiboken::PyName::method(), modifier);
}
static PyObject *
-GetSignature_Cached(PyObject *props, const char *func_kind, const char *modifier)
+GetSignature_Cached(PyObject *props, PyObject *func_kind, PyObject *modifier)
{
// Special case: We want to know the func_kind.
- if (modifier && strcmp(modifier, "__func_kind__") == 0)
- return Py_BuildValue("s", func_kind);
+ if (modifier) {
+#if PYTHON_USES_UNICODE
+ PyUnicode_InternInPlace(&modifier);
+#else
+ PyString_InternInPlace(&modifier);
+#endif
+ if (modifier == Shiboken::PyMagicName::func_kind())
+ return Py_BuildValue("O", func_kind);
+ }
Shiboken::AutoDecRef key(modifier == nullptr
- ? Py_BuildValue("s", func_kind)
- : Py_BuildValue("(ss)", func_kind, modifier));
+ ? Py_BuildValue("O", func_kind)
+ : Py_BuildValue("(OO)", func_kind, modifier));
PyObject *value = PyDict_GetItem(props, key);
if (value == nullptr) {
// we need to compute a signature object
@@ -454,11 +464,11 @@ GetSignature_Cached(PyObject *props, const char *func_kind, const char *modifier
}
static const char *PySide_CompressedSignaturePackage[] = {
-#include "embed/signature.inc"
+#include "embed/signature_inc.h"
};
static const unsigned char PySide_SignatureLoader[] = {
-#include "embed/signature_bootstrap.inc"
+#include "embed/signature_bootstrap_inc.h"
};
static safe_globals_struc *
@@ -477,13 +487,10 @@ init_phase_1(void)
#ifdef Py_LIMITED_API
// We must work for multiple versions, so use source code.
#else
- Shiboken::AutoDecRef marshal_str(Py_BuildValue("s", "marshal"));
- if (marshal_str.isNull())
- goto error;
- Shiboken::AutoDecRef marshal_module(PyImport_Import(marshal_str));
+ Shiboken::AutoDecRef marshal_module(PyImport_Import(Shiboken::PyName::marshal()));
if (marshal_module.isNull())
goto error;
- Shiboken::AutoDecRef loads(PyObject_GetAttrString(marshal_module, "loads"));
+ Shiboken::AutoDecRef loads(PyObject_GetAttr(marshal_module, Shiboken::PyName::loads()));
if (loads.isNull())
goto error;
#endif
@@ -495,7 +502,7 @@ init_phase_1(void)
goto error;
#ifdef Py_LIMITED_API
PyObject *builtins = PyEval_GetBuiltins();
- PyObject *compile = PyDict_GetItemString(builtins, "compile");
+ PyObject *compile = PyDict_GetItem(builtins, Shiboken::PyName::compile());
if (compile == nullptr)
goto error;
Shiboken::AutoDecRef code_obj(PyObject_CallFunction(compile, "Oss",
@@ -512,7 +519,7 @@ init_phase_1(void)
goto error;
// Initialize the module
PyObject *mdict = PyModule_GetDict(p->helper_module);
- if (PyDict_SetItemString(mdict, "__builtins__", PyEval_GetBuiltins()) < 0)
+ if (PyDict_SetItem(mdict, Shiboken::PyMagicName::builtins(), PyEval_GetBuiltins()) < 0)
goto error;
/*
* Unpack an embedded ZIP file with more signature modules.
@@ -551,11 +558,14 @@ init_phase_1(void)
if (p->value_dict == nullptr)
goto error;
+ // This function will be disabled until phase 2 is done.
+ p->finish_import_func = nullptr;
+
return p;
}
error:
PyErr_Print();
- PyErr_SetString(PyExc_SystemError, "could not initialize part 1");
+ Py_FatalError("could not initialize part 1");
return nullptr;
}
@@ -593,11 +603,14 @@ init_phase_2(safe_globals_struc *p, PyMethodDef *methods)
p->make_helptext_func = PyObject_GetAttrString(loader, "make_helptext");
if (p->make_helptext_func == nullptr)
goto error;
+ p->finish_import_func = PyObject_GetAttrString(loader, "finish_import");
+ if (p->finish_import_func == nullptr)
+ goto error;
return 0;
}
error:
PyErr_Print();
- PyErr_SetString(PyExc_SystemError, "could not initialize part 2");
+ Py_FatalError("could not initialize part 2");
return -1;
}
@@ -795,7 +808,7 @@ static PyGetSetDef new_PyWrapperDescr_getsets[] = {
//
static PyObject *
-get_signature_intern(PyObject *ob, const char *modifier)
+get_signature_intern(PyObject *ob, PyObject *modifier)
{
if (PyType_IsSubtype(Py_TYPE(ob), &PyCFunction_Type))
return pyside_cf_get___signature__(ob, modifier);
@@ -814,11 +827,11 @@ static PyObject *
get_signature(PyObject * /* self */, PyObject *args)
{
PyObject *ob;
- const char *modifier = nullptr;
+ PyObject *modifier = nullptr;
init_module_1();
- if (!PyArg_ParseTuple(args, "O|s", &ob, &modifier))
+ if (!PyArg_ParseTuple(args, "O|O", &ob, &modifier))
return nullptr;
if (Py_TYPE(ob) == PepFunction_TypePtr)
Py_RETURN_NONE;
@@ -1030,7 +1043,16 @@ PySide_FinishSignatures(PyObject *module, const char *signatures[])
return -1;
if (_finish_nested_classes(obdict) < 0)
return -1;
- return 0;
+ // The finish_import function will not work the first time since phase 2
+ // was not yet run. But that is ok, because the first import is always for
+ // the shiboken module (or a test module).
+ if (pyside_globals->finish_import_func == nullptr) {
+ assert(strncmp(name, "PySide2.", 8) != 0);
+ return 0;
+ }
+ Shiboken::AutoDecRef ret(PyObject_CallFunction(
+ pyside_globals->finish_import_func, const_cast<char *>("(O)"), module));
+ return ret.isNull() ? -1 : 0;
}
static int
@@ -1093,13 +1115,14 @@ _build_func_to_type(PyObject *obtype)
* "{name}.overload".
*/
PyObject *descr = PyDict_GetItemString(dict, meth->ml_name);
- const char *look_attr = meth->ml_flags & METH_STATIC ? "__func__" : "__name__";
+ PyObject *look_attr = meth->ml_flags & METH_STATIC
+ ? Shiboken::PyMagicName::func() : Shiboken::PyMagicName::name();
int check_name = meth->ml_flags & METH_STATIC ? 0 : 1;
if (descr == nullptr)
return -1;
// We first check all methods if one is hidden by something else.
- Shiboken::AutoDecRef look(PyObject_GetAttrString(descr, look_attr));
+ Shiboken::AutoDecRef look(PyObject_GetAttr(descr, look_attr));
Shiboken::AutoDecRef given(Py_BuildValue("s", meth->ml_name));
if (look.isNull()
|| (check_name && PyObject_RichCompareBool(look, given, Py_EQ) != 1)) {
@@ -1206,7 +1229,7 @@ SetError_Argument(PyObject *args, const char *func_name)
*/
PyObject *
-Sbk_TypeGet___signature__(PyObject *ob, const char *modifier)
+Sbk_TypeGet___signature__(PyObject *ob, PyObject *modifier)
{
return pyside_tp_get___signature__(ob, modifier);
}
diff --git a/sources/shiboken2/libshiboken/signature.h b/sources/shiboken2/libshiboken/signature.h
index 57fd4047a..b22a78497 100644
--- a/sources/shiboken2/libshiboken/signature.h
+++ b/sources/shiboken2/libshiboken/signature.h
@@ -48,7 +48,7 @@ extern "C"
LIBSHIBOKEN_API int SbkSpecial_Type_Ready(PyObject *, PyTypeObject *, const char *[]);
LIBSHIBOKEN_API void FinishSignatureInitialization(PyObject *, const char *[]);
LIBSHIBOKEN_API void SetError_Argument(PyObject *, const char *);
-LIBSHIBOKEN_API PyObject *Sbk_TypeGet___signature__(PyObject *, const char *);
+LIBSHIBOKEN_API PyObject *Sbk_TypeGet___signature__(PyObject *, PyObject *);
LIBSHIBOKEN_API PyObject *Sbk_TypeGet___doc__(PyObject *);
} // extern "C"
diff --git a/sources/shiboken2/libshiboken/signature_doc.rst b/sources/shiboken2/libshiboken/signature_doc.rst
index 9c42c5976..a984de4ce 100644
--- a/sources/shiboken2/libshiboken/signature_doc.rst
+++ b/sources/shiboken2/libshiboken/signature_doc.rst
@@ -73,8 +73,8 @@ It calls ``GetSignature_Function`` which returns the signature if it is found.
Why this Code is Fast
---------------------
-It costs a little time (maybe 4 seconds) to run througs every single signature
-object, since these are more than 15000 Python objects. But all the signature
+It costs a little time (maybe 6 seconds) to run througs every single signature
+object, since these are more than 25000 Python objects. But all the signature
objects will be rarely accessed but in special applications.
The normal case are only a few accesses, and these are working pretty fast.
@@ -111,10 +111,6 @@ the ``signature`` Python package. It has the following structure::
shiboken2/files.dir/shibokensupport/
backport_inspect.py
- python_minilib_2_7.py
- python_minilib_3_5.py
- python_minilib_3_6.py
- python_minilib_3_7.py
signature/
loader.py
@@ -125,6 +121,8 @@ the ``signature`` Python package. It has the following structure::
lib/
enum_sig.py
+ tool.py
+
Really important are the **parser**, **mapping**, **errorhandler**, **enum_sig**,
diff --git a/sources/shiboken2/libshiboken/typespec.cpp b/sources/shiboken2/libshiboken/typespec.cpp
index 6dc5b00bc..510ed51e6 100644
--- a/sources/shiboken2/libshiboken/typespec.cpp
+++ b/sources/shiboken2/libshiboken/typespec.cpp
@@ -39,6 +39,7 @@
#include "sbkpython.h"
#include "typespec.h"
+#include "sbkstaticstrings.h"
#include <structmember.h>
#if PY_MAJOR_VERSION < 3
@@ -730,7 +731,7 @@ PyType_FromSpecWithBases(PyType_Spec *spec, PyObject *bases)
}
// no PyId_ things in Python 2
// err = _PyDict_SetItemId(type->tp_dict, &PyId___module__, modname);
- err = PyDict_SetItemString(type->tp_dict, "__module__", modname);
+ err = PyDict_SetItem(type->tp_dict, Shiboken::PyMagicName::module(), modname);
Py_DECREF(modname);
if (err != 0)
goto fail;
diff --git a/sources/shiboken2/shiboken_version.py b/sources/shiboken2/shiboken_version.py
index 93c9fe6be..78ea0019d 100644
--- a/sources/shiboken2/shiboken_version.py
+++ b/sources/shiboken2/shiboken_version.py
@@ -1,6 +1,6 @@
#############################################################################
##
-## Copyright (C) 2018 The Qt Company Ltd.
+## Copyright (C) 2019 The Qt Company Ltd.
## Contact: https://www.qt.io/licensing/
##
## This file is part of Qt for Python.
@@ -38,9 +38,8 @@
#############################################################################
major_version = "5"
-minor_version = "13"
-patch_version = "2"
-
+minor_version = "14"
+patch_version = "0"
# 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 bbf2677e4..e1eafa12f 100644
--- a/sources/shiboken2/shibokenmodule/CMakeLists.txt
+++ b/sources/shiboken2/shibokenmodule/CMakeLists.txt
@@ -52,6 +52,8 @@ configure_file("${CMAKE_CURRENT_SOURCE_DIR}/files.dir/shibokensupport/signature/
"${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"
diff --git a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/backport_inspect.py b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/backport_inspect.py
index c690493b6..1f6d70b31 100644
--- a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/backport_inspect.py
+++ b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/backport_inspect.py
@@ -113,7 +113,9 @@ CO_NOFREE = 0x0040
# We use '__builtin__' and '__name__' instead.
def formatannotation(annotation, base_module=None):
if getattr(annotation, '__module__', None) == 'typing':
- return repr(annotation).replace('typing.', '')
+ # The replace must not be done on Python 2.7 because it
+ # already happens somewhere else.
+ return repr(annotation) ##.replace('typing.', '')
if isinstance(annotation, type):
if annotation.__module__ in ('__builtin__', base_module):
return annotation.__name__
diff --git a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/importhandler.py b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/importhandler.py
new file mode 100644
index 000000000..0417f132a
--- /dev/null
+++ b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/importhandler.py
@@ -0,0 +1,103 @@
+#############################################################################
+##
+## Copyright (C) 2019 The Qt Company Ltd.
+## Contact: https://www.qt.io/licensing/
+##
+## This file is part of Qt for Python.
+##
+## $QT_BEGIN_LICENSE:LGPL$
+## Commercial License Usage
+## Licensees holding valid commercial Qt licenses may use this file in
+## accordance with the commercial license agreement provided with the
+## Software or, alternatively, in accordance with the terms contained in
+## a written agreement between you and The Qt Company. For licensing terms
+## and conditions see https://www.qt.io/terms-conditions. For further
+## information use the contact form at https://www.qt.io/contact-us.
+##
+## GNU Lesser General Public License Usage
+## Alternatively, this file may be used under the terms of the GNU Lesser
+## General Public License version 3 as published by the Free Software
+## Foundation and appearing in the file LICENSE.LGPL3 included in the
+## packaging of this file. Please review the following information to
+## ensure the GNU Lesser General Public License version 3 requirements
+## will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+##
+## GNU General Public License Usage
+## Alternatively, this file may be used under the terms of the GNU
+## General Public License version 2.0 or (at your option) the GNU General
+## Public license version 3 or any later version approved by the KDE Free
+## Qt Foundation. The licenses are as published by the Free Software
+## Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+## included in the packaging of this file. Please review the following
+## information to ensure the GNU General Public License requirements will
+## be met: https://www.gnu.org/licenses/gpl-2.0.html and
+## https://www.gnu.org/licenses/gpl-3.0.html.
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+from __future__ import print_function, absolute_import
+
+"""
+importhandler.py
+
+This module handles special actions after the import of PySide modules.
+The reason for this was the wish to replace some deprecated functions
+by a Python implementation that gives a warning.
+
+It provides a framework to safely call functions outside of files.dir,
+because the implementation of deprecated functions should be visible
+to the users (in the hope they don't use it any longer <wink>).
+
+As a first approach, the function finish_import redirects to
+PySide2/support/deprecated.py . There can come other extensions as well.
+"""
+
+try:
+ from PySide2.support import deprecated
+ have_deprecated = True
+except ImportError:
+ have_deprecated = False
+
+
+# called by loader.py from signature.cpp
+def finish_import(module):
+ if have_deprecated and module.__name__.startswith("PySide2."):
+ try:
+ name = "fix_for_" + module.__name__.split(".")[1]
+ func = getattr(deprecated, name, None)
+ if func:
+ func(module)
+ except Exception as e:
+ name = e.__class__.__name__
+ print(72 * "*")
+ print("Error in deprecated.py, ignored:")
+ print(" {name}: {e}".format(**locals()))
+
+"""
+A note for people who might think this could be written in pure Python:
+
+Sure, by an explicit import of the modules to patch, this is no problem.
+But in the general case, a module should only be imported on user
+request and not because we want to patch it. So I started over.
+
+I then tried to do it on demand by redirection of the __import__ function.
+Things worked quite nicely as it seemed, but at second view this solution
+was much less appealing.
+
+Reason:
+If someone executes as the first PySide statement
+
+ from PySide2 import QtGui
+
+then this import is already running. We can see the other imports like the
+diverse initializations and QtCore, because it is triggered by import of
+QtGui. But the QtGui import can not be seen at all!
+
+With a lot of effort, sys.setprofile() and stack inspection with the inspect
+module, it is *perhaps* possible to solve that. I tried for a day and then
+gave up, since the solution is anyway not too nice when __import__ must
+be overridden.
+"""
+#eof
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 a5e3247b1..f11f3cf3d 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
@@ -52,11 +52,6 @@ by producing a lot of clarity.
import sys
from shibokensupport.signature import inspect
from shibokensupport.signature import get_signature
-try:
- from PySide2.QtCore import Qt
- EnumType = type(Qt.Key)
-except ImportError:
- EnumType = None
class ExactEnumerator(object):
@@ -69,6 +64,14 @@ class ExactEnumerator(object):
"""
def __init__(self, formatter, result_type=dict):
+ global EnumType
+ try:
+ # Lazy import
+ from PySide2.QtCore import Qt
+ EnumType = type(Qt.Key)
+ except ImportError:
+ EnumType = None
+
self.fmt = formatter
self.result_type = result_type
self.fmt.level = 0
@@ -81,6 +84,7 @@ class ExactEnumerator(object):
def module(self, mod_name):
__import__(mod_name)
+ self.fmt.mod_name = mod_name
with self.fmt.module(mod_name):
module = sys.modules[mod_name]
members = inspect.getmembers(module, inspect.isclass)
@@ -90,7 +94,7 @@ class ExactEnumerator(object):
for class_name, klass in members:
ret.update(self.klass(class_name, klass))
if isinstance(klass, EnumType):
- self.enum(klass)
+ raise SystemError("implement enum instances at module level")
for func_name, func in functions:
ret.update(self.function(func_name, func))
return ret
@@ -106,26 +110,47 @@ class ExactEnumerator(object):
name = modname + "." + base.__name__
bases_list.append(name)
class_str = "{}({})".format(class_name, ", ".join(bases_list))
- with self.fmt.klass(class_name, class_str):
- ret = self.result_type()
- # class_members = inspect.getmembers(klass)
- # gives us also the inherited things.
- class_members = sorted(list(klass.__dict__.items()))
- subclasses = []
- functions = []
- for thing_name, thing in class_members:
- if inspect.isclass(thing):
- subclass_name = ".".join((class_name, thing_name))
- subclasses.append((subclass_name, thing))
- elif inspect.isroutine(thing):
- func_name = thing_name.split(".")[0] # remove ".overload"
+ ret = self.result_type()
+ # class_members = inspect.getmembers(klass)
+ # gives us also the inherited things.
+ class_members = sorted(list(klass.__dict__.items()))
+ subclasses = []
+ functions = []
+ enums = []
+
+ for thing_name, thing in class_members:
+ if inspect.isclass(thing):
+ subclass_name = ".".join((class_name, thing_name))
+ subclasses.append((subclass_name, thing))
+ elif inspect.isroutine(thing):
+ func_name = thing_name.split(".")[0] # remove ".overload"
+ signature = getattr(thing, "__signature__", None)
+ if signature is not None:
functions.append((func_name, thing))
+ elif type(type(thing)) is EnumType:
+ enums.append((thing_name, thing))
+ init_signature = getattr(klass, "__signature__", None)
+ enums.sort(key=lambda tup: tup[1]) # sort by enum value
+ self.fmt.have_body = bool(subclasses or functions or enums or init_signature)
+
+ with self.fmt.klass(class_name, class_str):
self.fmt.level += 1
+ self.fmt.class_name = class_name
+ if hasattr(self.fmt, "enum"):
+ # this is an optional feature
+ for enum_name, value in enums:
+ with self.fmt.enum(class_name, enum_name, int(value)):
+ pass
for subclass_name, subclass in subclasses:
+ if klass == subclass:
+ # this is a side effect of the typing module for Python 2.7
+ # via the "._gorg" property, which we can safely ignore.
+ print("Warning: {class_name} points to itself via {subclass_name}, skipped!"
+ .format(**locals()))
+ continue
ret.update(self.klass(subclass_name, subclass))
- if isinstance(subclass, EnumType):
- self.enum(subclass)
- ret = self.function("__init__", klass)
+ self.fmt.class_name = class_name
+ ret.update(self.function("__init__", klass))
for func_name, func in functions:
func_kind = get_signature(func, "__func_kind__")
modifier = func_kind if func_kind in (
@@ -137,24 +162,13 @@ class ExactEnumerator(object):
def function(self, func_name, func, modifier=None):
self.fmt.level += 1
ret = self.result_type()
- signature = getattr(func, '__signature__', None)
+ signature = func.__signature__
if signature is not None:
with self.fmt.function(func_name, signature, modifier) as key:
ret[key] = signature
self.fmt.level -= 1
return ret
- def enum(self, subclass):
- if not hasattr(self.fmt, "enum"):
- # this is an optional feature
- return
- class_name = subclass.__name__
- for enum_name, value in subclass.__dict__.items():
- if type(type(value)) is EnumType:
- with self.fmt.enum(class_name, enum_name, int(value)):
- pass
- self._after_enum = True
-
def stringify(signature):
if isinstance(signature, list):
diff --git a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/loader.py b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/loader.py
index 8eff19d77..a0367883a 100644
--- a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/loader.py
+++ b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/loader.py
@@ -89,6 +89,10 @@ def formatannotation(annotation, base_module=None):
# break the Python license decorated files without an encoding line.
# name used in signature.cpp
+def pyside_type_init(type_key, sig_strings):
+ return parser.pyside_type_init(type_key, sig_strings)
+
+# name used in signature.cpp
def create_signature(props, key):
return layout.create_signature(props, key)
@@ -100,6 +104,11 @@ def seterror_argument(args, func_name):
def make_helptext(func):
return errorhandler.make_helptext(func)
+# name used in signature.cpp
+def finish_import(module):
+ return importhandler.finish_import(module)
+
+
import signature_bootstrap
from shibokensupport import signature
signature.get_signature = signature_bootstrap.get_signature
@@ -185,6 +194,7 @@ def move_into_pyside_package():
put_into_package(PySide2.support.signature, layout)
put_into_package(PySide2.support.signature, lib)
put_into_package(PySide2.support.signature, parser)
+ put_into_package(PySide2.support.signature, importhandler)
put_into_package(PySide2.support.signature.lib, enum_sig)
put_into_package(None if orig_typing else PySide2.support.signature, typing)
@@ -195,8 +205,8 @@ from shibokensupport.signature import errorhandler
from shibokensupport.signature import layout
from shibokensupport.signature import lib
from shibokensupport.signature import parser
+from shibokensupport.signature import importhandler
from shibokensupport.signature.lib import enum_sig
-from shibokensupport.signature.parser import pyside_type_init
if "PySide2" in sys.modules:
# We publish everything under "PySide2.support.signature", again.
diff --git a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/mapping.py b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/mapping.py
index 163aac851..2110ebe7a 100644
--- a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/mapping.py
+++ b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/mapping.py
@@ -66,7 +66,6 @@ Point = typing.Tuple[float, float]
Variant = typing.Any
ModelIndexList = typing.List[int]
QImageCleanupFunction = typing.Callable
-StringList = typing.List[str]
# unfortunately, typing.Optional[t] expands to typing.Union[t, NoneType]
# Until we can force it to create Optional[t] again, we use this.
@@ -184,6 +183,27 @@ class Default(_NotCalled):
class Instance(_NotCalled):
pass
+# Parameterized primitive variables
+class _Parameterized(object):
+ def __init__(self, type):
+ self.type = type
+ self.__name__ = self.__class__.__name__
+
+ def __repr__(self):
+ return "{}({})".format(
+ type(self).__name__, self.type.__name__)
+
+# Mark the primitive variables to be moved into the result.
+class ResultVariable(_Parameterized):
+ pass
+
+# Mark the primitive variables to become Sequence, Iterable or List
+# (decided in the parser).
+class ArrayLikeVariable(_Parameterized):
+ pass
+
+StringList = ArrayLikeVariable(str)
+
class Reloader(object):
"""
@@ -244,6 +264,7 @@ type_map = {}
namespace = globals() # our module's __dict__
type_map.update({
+ "...": ellipsis,
"bool": bool,
"char": Char,
"char*": str,
@@ -251,7 +272,7 @@ type_map.update({
"double": float,
"float": float,
"int": int,
- "List": typing.List,
+ "List": ArrayLikeVariable,
"long": int,
"PyCallable": typing.Callable,
"PyObject": object,
@@ -264,7 +285,7 @@ type_map.update({
"qint64": int,
"qint8": int,
"qintptr": int,
- "QList": typing.List,
+ "QList": ArrayLikeVariable,
"qlonglong": int,
"QMap": typing.Dict,
"QPair": typing.Tuple,
@@ -286,17 +307,28 @@ type_map.update({
"short": int,
"signed char": Char,
"signed long": int,
+ "std.list": typing.List,
+ "std.map": typing.Dict,
+ "std.pair": typing.Tuple,
+ "std.vector": typing.List,
"str": str,
"true": True,
+ "Tuple": typing.Tuple,
+ "uchar": Char,
+ "uchar*": str,
+ "uint": int,
+ "ulong": int,
"ULONG_MAX": ulong_max,
- "unsigned char": Char,
- "unsigned int": int, # should we define an unsigned type?
+ "unsigned char": Char, # 5.9
+ "unsigned char*": str,
+ "unsigned int": int,
"unsigned long int": int, # 5.6, RHEL 6.6
"unsigned long long": int,
"unsigned long": int,
"unsigned short int": int, # 5.6, RHEL 6.6
"unsigned short": int,
- "UnsignedShortType": int, # 5.9
+ "Unspecified": None,
+ "ushort": int,
"void": int, # be more specific?
"WId": WId,
"zero(bytes)": b"",
@@ -305,7 +337,51 @@ type_map.update({
"zero(int)": 0,
"zero(object)": None,
"zero(str)": "",
- "...": "...",
+ "zero(typing.Any)": None,
+ })
+
+type_map.update({
+ # Handling variables declared as array:
+ "array double*" : ArrayLikeVariable(float),
+ "array float*" : ArrayLikeVariable(float),
+ "array GLint*" : ArrayLikeVariable(int),
+ "array GLuint*" : ArrayLikeVariable(int),
+ "array int*" : ArrayLikeVariable(int),
+ "array long long*" : ArrayLikeVariable(int),
+ "array long*" : ArrayLikeVariable(int),
+ "array short*" : ArrayLikeVariable(int),
+ "array signed char*" : bytes,
+ "array unsigned char*" : bytes,
+ "array unsigned int*" : ArrayLikeVariable(int),
+ "array unsigned short*" : ArrayLikeVariable(int),
+ })
+
+type_map.update({
+ # Special cases:
+ "char*" : bytes,
+ "QChar*" : bytes,
+ "quint32*" : int, # only for QRandomGenerator
+ "quint8*" : bytearray, # only for QCborStreamReader and QCborValue
+ "uchar*" : bytes,
+ "unsigned char*": bytes,
+ })
+
+type_map.update({
+ # Handling variables that are returned, eventually as Tuples:
+ "bool*" : ResultVariable(bool),
+ "float*" : ResultVariable(float),
+ "int*" : ResultVariable(int),
+ "long long*" : ResultVariable(int),
+ "long*" : ResultVariable(int),
+ "PStr*" : ResultVariable(str), # module sample
+ "qint32*" : ResultVariable(int),
+ "qint64*" : ResultVariable(int),
+ "qreal*" : ResultVariable(float),
+ "QString*" : ResultVariable(str),
+ "quint16*" : ResultVariable(int),
+ "uint*" : ResultVariable(int),
+ "unsigned int*" : ResultVariable(int),
+ "QStringList*" : ResultVariable(StringList),
})
@@ -330,6 +406,7 @@ def init_sample():
import datetime
type_map.update({
"char": Char,
+ "char**": typing.List[str],
"Complex": complex,
"double": float,
"Foo.HANDLE": int,
@@ -346,7 +423,8 @@ def init_sample():
"sample.int": int,
"sample.ObjectType": object,
"sample.OddBool": bool,
- "sample.Photon.TemplateBase": Missing("sample.Photon.TemplateBase"),
+ "sample.Photon.TemplateBase[Photon.DuplicatorType]": sample.Photon.ValueDuplicator,
+ "sample.Photon.TemplateBase[Photon.IdentityType]": sample.Photon.ValueIdentity,
"sample.Point": Point,
"sample.PStr": str,
"sample.unsigned char": Char,
@@ -381,6 +459,7 @@ def init_smart():
})
return locals()
+
# The PySide Part
def init_PySide2_QtCore():
from PySide2.QtCore import Qt, QUrl, QDir
@@ -402,50 +481,18 @@ def init_PySide2_QtCore():
"list of QAbstractAnimation": typing.List[PySide2.QtCore.QAbstractAnimation],
"list of QAbstractState": typing.List[PySide2.QtCore.QAbstractState],
"long long": int,
- "long": int,
"NULL": None, # 5.6, MSVC
"nullptr": None, # 5.9
"PyByteArray": bytearray,
"PyBytes": bytes,
- "PyCallable": typing.Callable,
- "PyObject": object,
- "PySequence": typing.Iterable, # important for numpy
- "PySide2.QtCore.bool": bool,
- "PySide2.QtCore.char": StringList, # A 'char **' is a list of strings.
- "PySide2.QtCore.double": float,
- "PySide2.QtCore.float": float,
- "PySide2.QtCore.int": int,
- "PySide2.QtCore.int32_t": int, # 5.9
- "PySide2.QtCore.int64_t": int, # 5.9
- "PySide2.QtCore.long long": int, # 5.9, MSVC 15
- "PySide2.QtCore.long": int,
- "PySide2.QtCore.QCborStreamReader.StringResult": typing.AnyStr,
- "PySide2.QtCore.QChar": Char,
- "PySide2.QtCore.qint16": int,
- "PySide2.QtCore.qint32": int,
- "PySide2.QtCore.qint64": int,
- "PySide2.QtCore.qint8": int,
- "PySide2.QtCore.qreal": float,
- "PySide2.QtCore.QString": str,
- "PySide2.QtCore.QStringList": StringList,
- "PySide2.QtCore.quint16": int,
- "PySide2.QtCore.quint32": int,
- "PySide2.QtCore.quint64": int,
- "PySide2.QtCore.quint8": int,
+ "PySide2.QtCore.QCborStreamReader.StringResult[PySide2.QtCore.QByteArray]":
+ PySide2.QtCore.QCborStringResultByteArray,
+ "PySide2.QtCore.QCborStreamReader.StringResult[QString]":
+ PySide2.QtCore.QCborStringResultString,
"PySide2.QtCore.QUrl.ComponentFormattingOptions":
PySide2.QtCore.QUrl.ComponentFormattingOption, # mismatch option/enum, why???
- "PySide2.QtCore.QVariant": Variant,
- "PySide2.QtCore.short": int,
- "PySide2.QtCore.signed char": Char,
- "PySide2.QtCore.uchar": Char,
- "PySide2.QtCore.uint32_t": int, # 5.9
- "PySide2.QtCore.unsigned char": Char, # 5.9
- "PySide2.QtCore.unsigned int": int, # 5.9 Ubuntu
- "PySide2.QtCore.unsigned short": int,
- "PyTypeObject": type,
"PyUnicode": typing.Text,
"Q_NULLPTR": None,
- "QChar": Char,
"QDir.Filters(AllEntries | NoDotAndDotDot)": Instance(
"QDir.Filters(QDir.AllEntries | QDir.NoDotAndDotDot)"),
"QDir.SortFlags(Name | IgnoreCase)": Instance(
@@ -456,24 +503,21 @@ def init_PySide2_QtCore():
"QGenericArgument(NULL)": ellipsis, # 5.6, MSVC
"QGenericArgument(nullptr)": ellipsis, # 5.10
"QGenericArgument(Q_NULLPTR)": ellipsis,
- "QHash": typing.Dict,
"QJsonObject": typing.Dict[str, PySide2.QtCore.QJsonValue],
"QModelIndex()": Invalid("PySide2.QtCore.QModelIndex"), # repr is btw. very wrong, fix it?!
"QModelIndexList": ModelIndexList,
- "qptrdiff": int,
- "QString": str,
+ "QModelIndexList": ModelIndexList,
"QString()": "",
- "QStringList": StringList,
"QStringList()": [],
"QStringRef": str,
- "Qt.HANDLE": int, # be more explicit with some consts?
- "quintptr": int,
+ "QStringRef": str,
+ "Qt.HANDLE": int, # be more explicit with some constants?
"QUrl.FormattingOptions(PrettyDecoded)": Instance(
"QUrl.FormattingOptions(QUrl.PrettyDecoded)"),
- "QVariant": Variant,
"QVariant()": Invalid(Variant),
"QVariant.Type": type, # not so sure here...
"QVariantMap": typing.Dict[str, Variant],
+ "QVariantMap": typing.Dict[str, Variant],
})
try:
type_map.update({
@@ -493,16 +537,12 @@ def init_PySide2_QtGui():
"GL_COLOR_BUFFER_BIT": GL_COLOR_BUFFER_BIT,
"GL_NEAREST": GL_NEAREST,
"int32_t": int,
- "PySide2.QtCore.uint8_t": int, # macOS 5.9
- "PySide2.QtGui.QGenericMatrix": Missing("PySide2.QtGui.QGenericMatrix"),
- "PySide2.QtGui.QPlatformSurface": int, # a handle
- "QList< QTouchEvent.TouchPoint >()": [], # XXX improve?
"QPixmap()": Default("PySide2.QtGui.QPixmap"), # can't create without qApp
+ "QPlatformSurface*": int, # a handle
"QVector< QTextLayout.FormatRange >()": [], # do we need more structure?
"uint32_t": int,
"uint8_t": int,
"USHRT_MAX": ushort_max,
- "WId": WId,
})
return locals()
@@ -513,7 +553,6 @@ def init_PySide2_QtWidgets():
type_map.update({
"QMessageBox.StandardButtons(Yes | No)": Instance(
"QMessageBox.StandardButtons(QMessageBox.Yes | QMessageBox.No)"),
- "QVector< int >()": [],
"QWidget.RenderFlags(DrawWindowBackground | DrawChildren)": Instance(
"QWidget.RenderFlags(QWidget.DrawWindowBackground | QWidget.DrawChildren)"),
"SH_Default": QStyleHintReturn.SH_Default,
@@ -536,9 +575,12 @@ def init_PySide2_QtSql():
def init_PySide2_QtNetwork():
+ best_structure = typing.OrderedDict if getattr(typing, "OrderedDict", None) else typing.Dict
type_map.update({
- "QMultiMap": MultiMap,
+ "QMultiMap[PySide2.QtNetwork.QSsl.AlternativeNameEntryType, QString]":
+ best_structure[PySide2.QtNetwork.QSsl.AlternativeNameEntryType, typing.List[str]],
})
+ del best_structure
return locals()
@@ -557,6 +599,7 @@ def init_PySide2_QtMultimedia():
check_module(PySide2.QtMultimediaWidgets)
type_map.update({
"QGraphicsVideoItem": PySide2.QtMultimediaWidgets.QGraphicsVideoItem,
+ "qint64": int,
"QVideoWidget": PySide2.QtMultimediaWidgets.QVideoWidget,
})
return locals()
@@ -569,26 +612,23 @@ def init_PySide2_QtOpenGL():
"GLfloat": float, # 5.6, MSVC 15
"GLint": int,
"GLuint": int,
- "PySide2.QtOpenGL.GLint": int,
- "PySide2.QtOpenGL.GLuint": int,
})
return locals()
def init_PySide2_QtQml():
type_map.update({
- "PySide2.QtQml.bool volatile": bool,
"QJSValueList()": [],
- "QVariantHash()": typing.Dict[str, Variant], # XXX sorted?
+ "QVariantHash()": typing.Dict[str, Variant], # from 5.9
})
return locals()
def init_PySide2_QtQuick():
type_map.update({
- "PySide2.QtCore.uint": int,
- "PySide2.QtQuick.QSharedPointer": int,
- "T": int,
+ "PySide2.QtQuick.QSharedPointer[PySide2.QtQuick.QQuickItemGrabResult]":
+ PySide2.QtQuick.QQuickItemGrabResult,
+ "UnsignedShortType": int,
})
return locals()
@@ -602,6 +642,7 @@ def init_PySide2_QtScript():
def init_PySide2_QtTest():
type_map.update({
+ "PySide2.QtTest.QTest.PySideQTouchEventSequence": PySide2.QtTest.QTest.QTouchEventSequence,
"PySide2.QtTest.QTouchEventSequence": PySide2.QtTest.QTest.QTouchEventSequence,
})
return locals()
@@ -622,6 +663,10 @@ def init_PySide2_QtDataVisualization():
QtDataVisualization.QSurfaceDataArray = typing.List[QtDataVisualization.QSurfaceDataRow]
type_map.update({
"100.0f": 100.0,
+ "QtDataVisualization.QBarDataArray": QtDataVisualization.QBarDataArray,
+ "QtDataVisualization.QBarDataArray*": QtDataVisualization.QBarDataArray,
+ "QtDataVisualization.QSurfaceDataArray": QtDataVisualization.QSurfaceDataArray,
+ "QtDataVisualization.QSurfaceDataArray*": QtDataVisualization.QSurfaceDataArray,
})
return locals()
diff --git a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/parser.py b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/parser.py
index 0081a07ba..8d970956b 100644
--- a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/parser.py
+++ b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/parser.py
@@ -46,7 +46,7 @@ import types
import keyword
import functools
from shibokensupport.signature.mapping import (type_map, update_mapping,
- namespace, typing, _NotCalled)
+ namespace, typing, _NotCalled, ResultVariable, ArrayLikeVariable)
from shibokensupport.signature.lib.tool import (SimpleNamespace,
build_brace_pattern)
@@ -170,9 +170,9 @@ def _resolve_value(thing, valtype, line):
if thing in ("0", "None") and valtype:
if valtype.startswith("PySide2.") or valtype.startswith("typing."):
return None
- mapped = type_map[valtype]
+ map = type_map[valtype]
# typing.Any: '_SpecialForm' object has no attribute '__name__'
- name = mapped.__name__ if hasattr(mapped, "__name__") else str(mapped)
+ name = map.__name__ if hasattr(map, "__name__") else str(map)
thing = "zero({})".format(name)
if thing in type_map:
return type_map[thing]
@@ -219,8 +219,6 @@ def to_string(thing):
matrix_pattern = "PySide2.QtGui.QGenericMatrix"
-# The matrix patch is borrowed from the future (extracted).
-# It will work when the parser recognizes matrices.
def handle_matrix(arg):
n, m, typstr = tuple(map(lambda x:x.strip(), arg.split(",")))
assert typstr == "float"
@@ -238,7 +236,7 @@ def lno(level):
"""
-def _resolve_type(thing, line, level):
+def _resolve_type(thing, line, level, var_handler):
# Capture total replacements, first. Happens in
# "PySide2.QtCore.QCborStreamReader.StringResult[PySide2.QtCore.QByteArray]"
if thing in type_map:
@@ -253,13 +251,13 @@ def _resolve_type(thing, line, level):
# Special case: Handle the generic matrices.
if contr == matrix_pattern:
return handle_matrix(thing)
- contr = _resolve_type(contr, line, level+1)
+ contr = var_handler(_resolve_type(contr, line, level+1, var_handler))
if isinstance(contr, _NotCalled):
raise SystemError("Container types must exist:", repr(contr))
contr = to_string(contr)
pieces = []
for part in _parse_arglist(thing):
- part = _resolve_type(part, line, level+1)
+ part = var_handler(_resolve_type(part, line, level+1, var_handler))
if isinstance(part, _NotCalled):
# fix the tag (i.e. "Missing") by repr
part = repr(part)
@@ -270,6 +268,46 @@ def _resolve_type(thing, line, level):
return _resolve_value(thing, None, line)
+def _handle_generic(obj, repl):
+ """
+ Assign repl if obj is an ArrayLikeVariable
+
+ This is a neat trick. Example:
+
+ obj repl result
+ ---------------------- -------- ---------
+ ArrayLikeVariable List List
+ ArrayLikeVariable(str) List List[str]
+ ArrayLikeVariable Sequence Sequence
+ ArrayLikeVariable(str) Sequence Sequence[str]
+ """
+ if isinstance(obj, ArrayLikeVariable):
+ return repl[obj.type]
+ if isinstance(obj, type) and issubclass(obj, ArrayLikeVariable):
+ # was "if obj is ArrayLikeVariable"
+ return repl
+ return obj
+
+
+def handle_argvar(obj):
+ """
+ Decide how array-like variables are resolved in arguments
+
+ Currently, the best approximation is types.Sequence.
+ We want to change that to types.Iterable in the near future.
+ """
+ return _handle_generic(obj, typing.Sequence)
+
+
+def handle_retvar(obj):
+ """
+ Decide how array-like variables are resolved in results
+
+ This will probably stay typing.List forever.
+ """
+ return _handle_generic(obj, typing.List)
+
+
def calculate_props(line):
parsed = SimpleNamespace(**_parse_line(line.strip()))
arglist = parsed.arglist
@@ -283,14 +321,14 @@ def calculate_props(line):
ann = 'nullptr' # maps to None
tup = name, ann
arglist[idx] = tup
- annotations[name] = _resolve_type(ann, line, 0)
+ annotations[name] = _resolve_type(ann, line, 0, handle_argvar)
if len(tup) == 3:
default = _resolve_value(tup[2], ann, line)
_defaults.append(default)
defaults = tuple(_defaults)
returntype = parsed.returntype
if returntype is not None:
- annotations["return"] = _resolve_type(returntype, line, 0)
+ annotations["return"] = _resolve_type(returntype, line, 0, handle_retvar)
props = SimpleNamespace()
props.defaults = defaults
props.kwdefaults = {}
@@ -301,9 +339,61 @@ def calculate_props(line):
shortname = funcname[funcname.rindex(".")+1:]
props.name = shortname
props.multi = parsed.multi
+ fix_variables(props, line)
return vars(props)
+def fix_variables(props, line):
+ annos = props.annotations
+ if not any(isinstance(ann, (ResultVariable, ArrayLikeVariable))
+ for ann in annos.values()):
+ return
+ retvar = annos.get("return", None)
+ 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)
+
+ safe_annos = annos.copy()
+ retvars = [retvar] if retvar else []
+ deletions = []
+ for idx, name in enumerate(varnames):
+ ann = safe_annos[name]
+ if isinstance(ann, ArrayLikeVariable):
+ ann = typing.Sequence[ann.type]
+ annos[name] = ann
+ if not isinstance(ann, ResultVariable):
+ continue
+ # We move the variable to the end and remove it.
+ retvars.append(ann.type)
+ deletions.append(idx)
+ del annos[name]
+ for idx in reversed(deletions):
+ # varnames: 0 1 2 3 4 5 6 7
+ # defaults: 0 1 2 3 4
+ # diff: 3
+ del varnames[idx]
+ if idx >= diff:
+ del defaults[idx - diff]
+ else:
+ diff -= 1
+ if retvars:
+ rvs = []
+ retvars = list(handle_retvar(rv) if isinstance(rv, ArrayLikeVariable) else rv
+ for rv in retvars)
+ if len(retvars) == 1:
+ returntype = retvars[0]
+ else:
+ typestr = "typing.Tuple[{}]".format(", ".join(map(to_string, retvars)))
+ returntype = eval(typestr, namespace)
+ props.annotations["return"] = returntype
+ props.varnames = tuple(varnames)
+ props.defaults = tuple(defaults)
+
+
def fixup_multilines(lines):
"""
Multilines can collapse when certain distinctions between C++ types
diff --git a/sources/shiboken2/tests/samplebinding/pointerprimitivetype_test.py b/sources/shiboken2/tests/samplebinding/pointerprimitivetype_test.py
new file mode 100644
index 000000000..c40770862
--- /dev/null
+++ b/sources/shiboken2/tests/samplebinding/pointerprimitivetype_test.py
@@ -0,0 +1,79 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+#############################################################################
+##
+## Copyright (C) 2019 The Qt Company Ltd.
+## Contact: https://www.qt.io/licensing/
+##
+## This file is part of the test suite of Qt for Python.
+##
+## $QT_BEGIN_LICENSE:GPL-EXCEPT$
+## Commercial License Usage
+## Licensees holding valid commercial Qt licenses may use this file in
+## accordance with the commercial license agreement provided with the
+## Software or, alternatively, in accordance with the terms contained in
+## a written agreement between you and The Qt Company. For licensing terms
+## and conditions see https://www.qt.io/terms-conditions. For further
+## information use the contact form at https://www.qt.io/contact-us.
+##
+## GNU General Public License Usage
+## Alternatively, this file may be used under the terms of the GNU
+## General Public License version 3 as published by the Free Software
+## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+## included in the packaging of this file. Please review the following
+## information to ensure the GNU General Public License requirements will
+## be met: https://www.gnu.org/licenses/gpl-3.0.html.
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+"""
+pointerprimitivetype_test.py
+
+check that the primitive types are correctly mapped by the signature module.
+
+Mapping
+-------
+IntArray2(const int*) -- <Signature (self, data: typing.Sequence)>
+getMargins(int*,int*,int*,int*)const -- <Signature (self) -> typing.Tuple[int, int, int, int]>
+
+We explicitly check only against typing.Iterable in the first test,
+because typing.Sequence is a subclass, but we will generalize this
+to typing.Iterable in the future.
+"""
+
+import unittest
+from sample import IntArray2, VirtualMethods
+
+import shiboken2
+type.__signature__ # trigger init, which does not happen in tests
+from shibokensupport.signature import typing
+
+
+class PointerPrimitiveTypeTest(unittest.TestCase):
+
+ def testArraySignature(self):
+ # signature="IntArray2(const int*)"
+ found = False
+ for sig in IntArray2.__signature__:
+ if "data" in sig.parameters:
+ found = True
+ break
+ self.assertTrue(found)
+ ann = sig.parameters["data"].annotation
+ self.assertEqual(ann.__args__, (int,))
+ # un-specify this class (forget "int") by setting the _special
+ # flag, so we can check using issubclass (undocumented feature).
+ ann._special = True
+ self.assertTrue(issubclass(ann, typing.Iterable))
+
+ def testReturnVarSignature(self):
+ # signature="getMargins(int*,int*,int*,int*)const">
+ ann = VirtualMethods.getMargins.__signature__.return_annotation
+ self.assertEqual(ann, typing.Tuple[int, int, int, int])
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken2/tests/samplebinding/typesystem_sample.xml b/sources/shiboken2/tests/samplebinding/typesystem_sample.xml
index 4d624f952..30ad5def7 100644
--- a/sources/shiboken2/tests/samplebinding/typesystem_sample.xml
+++ b/sources/shiboken2/tests/samplebinding/typesystem_sample.xml
@@ -227,7 +227,6 @@
</modify-argument>
<modify-argument index="1">
<replace-type modified-type="PStr"/>
- <remove-default-expression/>
<replace-default-expression with="PStr()"/>
</modify-argument>
<inject-code class="target" position="end">