aboutsummaryrefslogtreecommitdiffstats
path: root/sources
diff options
context:
space:
mode:
Diffstat (limited to 'sources')
-rw-r--r--sources/pyside2/PySide2/QtUiTools/typesystem_uitools.xml2
-rw-r--r--sources/pyside2/PySide2/QtWidgets/typesystem_widgets_common.xml8
-rw-r--r--sources/pyside2/PySide2/glue/qtcore.cpp46
-rw-r--r--sources/pyside2/PySide2/support/generate_pyi.py10
-rw-r--r--sources/pyside2/doc/CMakeLists.txt3
-rw-r--r--sources/pyside2/doc/conf.py.in5
-rw-r--r--sources/pyside2/tests/registry/init_platform.py6
-rw-r--r--sources/pyside2/tests/support/voidptr_test.py18
-rw-r--r--sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp64
-rw-r--r--sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h2
-rw-r--r--sources/shiboken2/ApiExtractor/abstractmetalang.cpp33
-rw-r--r--sources/shiboken2/ApiExtractor/abstractmetalang.h1
-rw-r--r--sources/shiboken2/ApiExtractor/typesystem.h2
-rw-r--r--sources/shiboken2/generator/generator.h38
-rw-r--r--sources/shiboken2/generator/indentor.h85
-rw-r--r--sources/shiboken2/generator/qtdoc/qtdocgenerator.cpp134
-rw-r--r--sources/shiboken2/generator/qtdoc/qtdocgenerator.h5
-rw-r--r--sources/shiboken2/generator/shiboken2/cppgenerator.cpp7
-rw-r--r--sources/shiboken2/generator/shiboken2/overloaddata.cpp14
-rw-r--r--sources/shiboken2/libshiboken/signature.cpp11
-rw-r--r--sources/shiboken2/libshiboken/voidptr.cpp65
-rw-r--r--sources/shiboken2/shibokenmodule/CMakeLists.txt4
-rw-r--r--sources/shiboken2/shibokenmodule/support/signature/fix-complaints.py2
-rw-r--r--sources/shiboken2/shibokenmodule/support/signature/loader.py4
-rw-r--r--sources/shiboken2/tests/libsample/nontypetemplate.h1
-rw-r--r--sources/shiboken2/tests/samplebinding/nontypetemplate_test.py15
-rw-r--r--sources/shiboken2/tests/samplebinding/typesystem_sample.xml13
27 files changed, 406 insertions, 192 deletions
diff --git a/sources/pyside2/PySide2/QtUiTools/typesystem_uitools.xml b/sources/pyside2/PySide2/QtUiTools/typesystem_uitools.xml
index 2cbe490aa..c3b800454 100644
--- a/sources/pyside2/PySide2/QtUiTools/typesystem_uitools.xml
+++ b/sources/pyside2/PySide2/QtUiTools/typesystem_uitools.xml
@@ -62,7 +62,7 @@
of the `.ui` file.
(Remember that `duck punching virtual methods is an invitation for your own demise!
- <http://www.pyside.org/docs/shiboken/wordsofadvice.html#duck-punching-and-virtual-methods>`_)
+ <https://doc.qt.io/qtforpython/shiboken2/wordsofadvice.html#duck-punching-and-virtual-methods>`_)
Let's see an obvious example. If you want to create a new widget it's probable you'll end up
overriding :class:`~PySide2.QtGui.QWidget`'s :meth:`~PySide2.QtGui.QWidget.paintEvent` method.
diff --git a/sources/pyside2/PySide2/QtWidgets/typesystem_widgets_common.xml b/sources/pyside2/PySide2/QtWidgets/typesystem_widgets_common.xml
index c2c36d60f..a41a27c33 100644
--- a/sources/pyside2/PySide2/QtWidgets/typesystem_widgets_common.xml
+++ b/sources/pyside2/PySide2/QtWidgets/typesystem_widgets_common.xml
@@ -610,7 +610,13 @@
<include file-name="QPair" location="global"/>
</extra-includes>
</object-type>
- <object-type name="QGraphicsItemGroup"/>
+ <object-type name="QGraphicsItemGroup">
+ <modify-function signature="addToGroup(QGraphicsItem*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
<object-type name="QGraphicsLineItem"/>
<object-type name="QGraphicsPathItem"/>
<object-type name="QGraphicsPixmapItem">
diff --git a/sources/pyside2/PySide2/glue/qtcore.cpp b/sources/pyside2/PySide2/glue/qtcore.cpp
index 629484458..6259724c3 100644
--- a/sources/pyside2/PySide2/glue/qtcore.cpp
+++ b/sources/pyside2/PySide2/glue/qtcore.cpp
@@ -965,13 +965,33 @@ if (PyIndex_Check(_key)) {
// @snippet qbytearray-msetitem
// @snippet qbytearray-bufferprotocol
-#if PY_VERSION_HEX < 0x03000000
-
+extern "C" {
// QByteArray buffer protocol functions
// see: http://www.python.org/dev/peps/pep-3118/
-extern "C" {
+static int SbkQByteArray_getbufferproc(PyObject* obj, Py_buffer *view, int flags)
+{
+ if (!view || !Shiboken::Object::isValid(obj))
+ return -1;
+
+ QByteArray* cppSelf = %CONVERTTOCPP[QByteArray*](obj);
+ view->obj = obj;
+ view->buf = reinterpret_cast<void*>(cppSelf->data());
+ view->len = cppSelf->size();
+ view->readonly = 0;
+ view->itemsize = 1;
+ view->format = const_cast<char*>("c");
+ view->ndim = 1;
+ view->shape = NULL;
+ view->strides = &view->itemsize;
+ view->suboffsets = NULL;
+ view->internal = NULL;
+
+ Py_XINCREF(obj);
+ return 0;
+}
+#if PY_VERSION_HEX < 0x03000000
static Py_ssize_t SbkQByteArray_segcountproc(PyObject* self, Py_ssize_t* lenp)
{
if (lenp)
@@ -993,12 +1013,18 @@ PyBufferProcs SbkQByteArrayBufferProc = {
/*bf_getreadbuffer*/ &SbkQByteArray_readbufferproc,
/*bf_getwritebuffer*/ (writebufferproc) &SbkQByteArray_readbufferproc,
/*bf_getsegcount*/ &SbkQByteArray_segcountproc,
- /*bf_getcharbuffer*/ (charbufferproc) &SbkQByteArray_readbufferproc
+ /*bf_getcharbuffer*/ (charbufferproc) &SbkQByteArray_readbufferproc,
+ /*bf_getbuffer*/ (getbufferproc)SbkQByteArray_getbufferproc,
};
+#else
-}
+static PyBufferProcs SbkQByteArrayBufferProc = {
+ /*bf_getbuffer*/ (getbufferproc)SbkQByteArray_getbufferproc,
+ /*bf_releasebuffer*/ (releasebufferproc)0,
+};
#endif
+}
// @snippet qbytearray-bufferprotocol
// @snippet qbytearray-operatorplus-1
@@ -1110,8 +1136,14 @@ if (PyBytes_Check(%PYARG_1)) {
// @snippet qbytearray-py3
#if PY_VERSION_HEX < 0x03000000
- Shiboken::SbkType<QByteArray>()->tp_as_buffer = &SbkQByteArrayBufferProc;
- Shiboken::SbkType<QByteArray>()->tp_flags |= Py_TPFLAGS_HAVE_GETCHARBUFFER;
+Shiboken::SbkType<QByteArray>()->tp_as_buffer = &SbkQByteArrayBufferProc;
+Shiboken::SbkType<QByteArray>()->tp_flags |= Py_TPFLAGS_HAVE_NEWBUFFER;
+#else
+#ifdef Py_LIMITED_API
+PepType_AS_BUFFER(Shiboken::SbkType<QByteArray>()) = &SbkQByteArrayBufferProc;
+#else
+Shiboken::SbkType<QByteArray>()->tp_as_buffer = &SbkQByteArrayBufferProc;
+#endif
#endif
// @snippet qbytearray-py3
diff --git a/sources/pyside2/PySide2/support/generate_pyi.py b/sources/pyside2/PySide2/support/generate_pyi.py
index 21ef841fe..a92ee76f0 100644
--- a/sources/pyside2/PySide2/support/generate_pyi.py
+++ b/sources/pyside2/PySide2/support/generate_pyi.py
@@ -53,13 +53,6 @@ import re
import subprocess
import argparse
import glob
-# PYSIDE-953: Use a newer contextlib for Python 3.5
-skip_creation = False
-if sys.version_info[:2] == (3, 5):
- try:
- import PySide2.support.signature # gets new contextlib
- except:
- skip_creation = True
from contextlib import contextmanager
from textwrap import dedent
@@ -279,9 +272,6 @@ def single_process(lockdir):
def generate_all_pyi(outpath, options):
- if skip_creation:
- logger.warn("Sorry, we cannot create .pyi files with Python 3.5 while PySide")
- logger.warn(" is not installed. Please run it by hand!")
ps = os.pathsep
if options.sys_path:
# make sure to propagate the paths from sys_path to subprocesses
diff --git a/sources/pyside2/doc/CMakeLists.txt b/sources/pyside2/doc/CMakeLists.txt
index eb5200e85..b5bde885a 100644
--- a/sources/pyside2/doc/CMakeLists.txt
+++ b/sources/pyside2/doc/CMakeLists.txt
@@ -28,6 +28,8 @@ configure_file("pyside-config.qdocconf.in" "${CMAKE_CURRENT_LIST_DIR}/pyside-con
file(READ "${pyside2_BINARY_DIR}/pyside2_global.h" docHeaderContents)
file(READ "typesystem_doc.xml.in" typeSystemDocXmlContents)
+set(HAS_WEBENGINE_WIDGETS 0)
+
foreach(moduleIn ${all_module_shortnames})
string(TOLOWER "${moduleIn}" lowerModuleIn)
set(docConf "${CMAKE_CURRENT_LIST_DIR}/qtmodules/pyside-qt${lowerModuleIn}.qdocconf.in")
@@ -45,6 +47,7 @@ foreach(moduleIn ${all_module_shortnames})
set(modules Multimedia "${moduleIn}")
elseif ("${moduleIn}" STREQUAL "WebEngineWidgets")
set(modules WebEngine WebEngineCore "${moduleIn}")
+ set(HAS_WEBENGINE_WIDGETS 1)
else()
set(modules "${moduleIn}")
endif()
diff --git a/sources/pyside2/doc/conf.py.in b/sources/pyside2/doc/conf.py.in
index 99b74deef..33f408354 100644
--- a/sources/pyside2/doc/conf.py.in
+++ b/sources/pyside2/doc/conf.py.in
@@ -18,7 +18,8 @@ import sys, os
# documentation root, use os.path.abspath to make it absolute, like shown here.
sys.path.append('@CMAKE_CURRENT_SOURCE_DIR@')
sys.path.append('@pyside_BINARY_DIR@')
-sys.path.append('@CMAKE_CURRENT_SOURCE_DIR@/../../../examples/webenginewidgets/tabbedbrowser')
+if @HAS_WEBENGINE_WIDGETS@:
+ sys.path.append('@CMAKE_CURRENT_SOURCE_DIR@/../../../examples/webenginewidgets/tabbedbrowser')
# -- General configuration -----------------------------------------------------
@@ -170,3 +171,5 @@ html_show_sourcelink = False
# Link to the shiboken2 sphinx project to enable linking
# between the two projects.
intersphinx_mapping = {'shiboken2': ('shiboken2','@CMAKE_BINARY_DIR@/../shiboken2/doc/html/objects.inv')}
+
+add_module_names = False
diff --git a/sources/pyside2/tests/registry/init_platform.py b/sources/pyside2/tests/registry/init_platform.py
index 6031dd2ad..a324c36a2 100644
--- a/sources/pyside2/tests/registry/init_platform.py
+++ b/sources/pyside2/tests/registry/init_platform.py
@@ -55,8 +55,7 @@ shiboken and pysidetest projects.
import sys
import os
import re
-# PYSIDE-953: Use a newer contextlib for Python 3.5
-# from contextlib import contextmanager
+from contextlib import contextmanager
from textwrap import dedent
script_dir = os.path.normpath(os.path.join(__file__, *".. .. .. .. ..".split()))
@@ -118,9 +117,6 @@ sys.path[:0] = [os.path.join(shiboken_build_dir, "shibokenmodule"),
pyside_build_dir]
import PySide2
-# PYSIDE-953: Use a newer contextlib for Python 3.5
-import PySide2.support.signature # new contextlib
-from contextlib import contextmanager
all_modules = list("PySide2." + x for x in PySide2.__all__)
diff --git a/sources/pyside2/tests/support/voidptr_test.py b/sources/pyside2/tests/support/voidptr_test.py
index 330788c63..c04022489 100644
--- a/sources/pyside2/tests/support/voidptr_test.py
+++ b/sources/pyside2/tests/support/voidptr_test.py
@@ -38,9 +38,21 @@ class PySide2Support(unittest.TestCase):
# a C++ object, a wrapped Shiboken Object type,
# an object implementing the Python Buffer interface,
# or another VoidPtr object.
- ba = QByteArray(b"Hello world")
- voidptr = VoidPtr(ba)
- self.assertIsInstance(voidptr, shiboken.VoidPtr)
+
+ # Original content
+ b = b"Hello world"
+ ba = QByteArray(b)
+ vp = VoidPtr(ba, ba.size())
+ self.assertIsInstance(vp, shiboken.VoidPtr)
+
+ # Create QByteArray from voidptr byte interpretation
+ nba = QByteArray.fromRawData(vp.toBytes())
+ # Compare original bytes to toBytes()
+ self.assertTrue(b, vp.toBytes())
+ # Compare original with new QByteArray data
+ self.assertTrue(b, nba.data())
+ # Convert original and new to str
+ self.assertTrue(str(b), str(nba))
if __name__ == '__main__':
unittest.main()
diff --git a/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp b/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp
index 37ff3b72c..0b11b1666 100644
--- a/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp
+++ b/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp
@@ -1840,34 +1840,27 @@ static inline AbstractMetaFunction::FunctionType functionTypeFromCodeModel(CodeM
return result;
}
-bool AbstractMetaBuilderPrivate::setArrayArgumentType(AbstractMetaFunction *func,
- const FunctionModelItem &functionItem,
- int i)
-{
- if (i < 0 || i >= func->arguments().size()) {
- qCWarning(lcShiboken).noquote()
- << msgCannotSetArrayUsage(func->minimalSignature(), i,
- QLatin1String("Index out of range."));
- return false;
- }
- AbstractMetaType *metaType = func->arguments().at(i)->type();
- if (metaType->indirections() == 0) {
- qCWarning(lcShiboken).noquote()
- << msgCannotSetArrayUsage(func->minimalSignature(), i,
- QLatin1String("Type does not have indirections."));
- return false;
- }
- TypeInfo elementType = functionItem->arguments().at(i)->type();
- elementType.setIndirections(elementType.indirections() - 1);
- AbstractMetaType *element = translateType(elementType);
- if (element == nullptr) {
- qCWarning(lcShiboken).noquote()
- << msgCannotSetArrayUsage(func->minimalSignature(), i,
- QLatin1String("Cannot translate element type ") + elementType.toString());
- return false;
+// Apply the <array> modifications of the arguments
+static bool applyArrayArgumentModifications(const FunctionModificationList &functionMods,
+ AbstractMetaFunction *func,
+ QString *errorMessage)
+{
+ for (const FunctionModification &mod : functionMods) {
+ for (const ArgumentModification &argMod : mod.argument_mods) {
+ if (argMod.array) {
+ const int i = argMod.index - 1;
+ if (i < 0 || i >= func->arguments().size()) {
+ *errorMessage = msgCannotSetArrayUsage(func->minimalSignature(), i,
+ QLatin1String("Index out of range."));
+ return false;
+ }
+ if (!func->arguments().at(i)->type()->applyArrayModification(errorMessage)) {
+ *errorMessage = msgCannotSetArrayUsage(func->minimalSignature(), i, *errorMessage);
+ return false;
+ }
+ }
+ }
}
- metaType->setArrayElementType(element);
- metaType->setTypeUsagePattern(AbstractMetaType::NativePointerAsArrayPattern);
return true;
}
@@ -2109,11 +2102,10 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(const Functio
if (!metaArguments.isEmpty()) {
fixArgumentNames(metaFunction, functionMods);
- for (const FunctionModification &mod : functionMods) {
- for (const ArgumentModification &argMod : mod.argument_mods) {
- if (argMod.array)
- setArrayArgumentType(metaFunction, functionItem, argMod.index - 1);
- }
+ QString errorMessage;
+ if (!applyArrayArgumentModifications(functionMods, metaFunction, &errorMessage)) {
+ qCWarning(lcShiboken, "While traversing %s: %s",
+ qPrintable(className), qPrintable(errorMessage));
}
}
@@ -2744,6 +2736,7 @@ bool AbstractMetaBuilderPrivate::inheritTemplate(AbstractMetaClass *subclass,
{
QVector<TypeInfo> targs = info.instantiations();
QVector<AbstractMetaType *> templateTypes;
+ QString errorMessage;
if (subclass->isTypeDef()) {
subclass->setHasCloneOperator(templateClass->hasCloneOperator());
@@ -2876,6 +2869,13 @@ bool AbstractMetaBuilderPrivate::inheritTemplate(AbstractMetaClass *subclass,
te->addFunctionModification(mod);
}
+
+ if (!applyArrayArgumentModifications(f->modifications(subclass), f.data(),
+ &errorMessage)) {
+ qCWarning(lcShiboken, "While specializing %s (%s): %s",
+ qPrintable(subclass->name()), qPrintable(templateClass->name()),
+ qPrintable(errorMessage));
+ }
subclass->addFunction(f.take());
}
diff --git a/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h b/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h
index 226d6defd..185dd0e30 100644
--- a/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h
+++ b/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h
@@ -156,8 +156,6 @@ public:
AbstractMetaArgumentList reverseList(const AbstractMetaArgumentList &list);
void setInclude(TypeEntry *te, const QString &fileName) const;
void fixArgumentNames(AbstractMetaFunction *func, const FunctionModificationList &mods);
- bool setArrayArgumentType(AbstractMetaFunction *func,
- const FunctionModelItem &functionItem, int i);
void fillAddedFunctions(AbstractMetaClass *metaClass);
diff --git a/sources/shiboken2/ApiExtractor/abstractmetalang.cpp b/sources/shiboken2/ApiExtractor/abstractmetalang.cpp
index a10a15b08..95f8048cd 100644
--- a/sources/shiboken2/ApiExtractor/abstractmetalang.cpp
+++ b/sources/shiboken2/ApiExtractor/abstractmetalang.cpp
@@ -207,6 +207,35 @@ AbstractMetaType *AbstractMetaType::copy() const
return cpy;
}
+// For applying the <array> function argument modification: change into a type
+// where "int *" becomes "int[]".
+bool AbstractMetaType::applyArrayModification(QString *errorMessage)
+{
+ if (m_pattern == AbstractMetaType::NativePointerAsArrayPattern) {
+ *errorMessage = QLatin1String("<array> modification already applied.");
+ return false;
+ }
+ if (m_arrayElementType != nullptr) {
+ QTextStream(errorMessage) << "The type \"" << cppSignature()
+ << "\" is an array of " << m_arrayElementType->name() << '.';
+ return false;
+ }
+ if (m_indirections.isEmpty()) {
+ QTextStream(errorMessage) << "The type \"" << cppSignature()
+ << "\" does not have indirections.";
+ return false;
+ }
+ // Element type to be used for ArrayHandle<>, strip constness.
+ auto elementType = copy();
+ elementType->m_indirections.pop_front();
+ elementType->setConstant(false);
+ elementType->setVolatile(false);
+ elementType->decideUsagePattern();
+ m_arrayElementType = elementType;
+ setTypeUsagePattern(AbstractMetaType::NativePointerAsArrayPattern);
+ return true;
+}
+
AbstractMetaTypeCList AbstractMetaType::nestedArrayTypes() const
{
AbstractMetaTypeCList result;
@@ -1256,6 +1285,8 @@ void AbstractMetaFunction::formatDebugVerbose(QDebug &d) const
d << " [userAdded]";
if (m_explicit)
d << " [explicit]";
+ if (attributes().testFlag(AbstractMetaAttributes::Deprecated))
+ d << " [deprecated]";
if (m_pointerOperator)
d << " [operator->]";
if (m_isCallOperator)
@@ -2608,6 +2639,8 @@ QDebug operator<<(QDebug d, const AbstractMetaClass *ac)
d << '"' << ac->fullName() << '"';
if (ac->attributes() & AbstractMetaAttributes::FinalCppClass)
d << " [final]";
+ if (ac->attributes().testFlag(AbstractMetaAttributes::Deprecated))
+ d << " [deprecated]";
if (ac->m_baseClass)
d << ", inherits \"" << ac->m_baseClass->name() << '"';
if (ac->m_templateBaseClass)
diff --git a/sources/shiboken2/ApiExtractor/abstractmetalang.h b/sources/shiboken2/ApiExtractor/abstractmetalang.h
index 074adbe00..9d36706ac 100644
--- a/sources/shiboken2/ApiExtractor/abstractmetalang.h
+++ b/sources/shiboken2/ApiExtractor/abstractmetalang.h
@@ -488,6 +488,7 @@ public:
QString cppSignature() const;
AbstractMetaType *copy() const;
+ bool applyArrayModification(QString *errorMessage);
const TypeEntry *typeEntry() const
{
diff --git a/sources/shiboken2/ApiExtractor/typesystem.h b/sources/shiboken2/ApiExtractor/typesystem.h
index 36a75c599..96d0bb5fd 100644
--- a/sources/shiboken2/ApiExtractor/typesystem.h
+++ b/sources/shiboken2/ApiExtractor/typesystem.h
@@ -46,8 +46,6 @@
extern const char *TARGET_CONVERSION_RULE_FLAG;
extern const char *NATIVE_CONVERSION_RULE_FLAG;
-class Indentor;
-
class AbstractMetaType;
QT_BEGIN_NAMESPACE
class QDebug;
diff --git a/sources/shiboken2/generator/generator.h b/sources/shiboken2/generator/generator.h
index cdf6d89b3..04840427f 100644
--- a/sources/shiboken2/generator/generator.h
+++ b/sources/shiboken2/generator/generator.h
@@ -29,6 +29,7 @@
#ifndef GENERATOR_H
#define GENERATOR_H
+#include "indentor.h"
#include <abstractmetalang_typedefs.h>
#include <typedatabase_typedefs.h>
#include <dependency.h>
@@ -54,7 +55,6 @@ QT_END_NAMESPACE
class PrimitiveTypeEntry;
class ContainerTypeEntry;
-class Indentor;
QTextStream& formatCode(QTextStream &s, const QString& code, Indentor &indentor);
void verifyDirectoryFor(const QString &file);
@@ -417,41 +417,5 @@ Q_DECLARE_OPERATORS_FOR_FLAGS(Generator::Options)
typedef QSharedPointer<Generator> GeneratorPtr;
typedef QVector<GeneratorPtr> Generators;
-/**
-* Utility class to store the identation level, use it in a QTextStream.
-*/
-class Indentor
-{
-public:
- Indentor() : indent(0) {}
- int indent;
-};
-
-/**
-* Class that use the RAII idiom to set and unset the identation level.
-*/
-class Indentation
-{
-public:
- Indentation(Indentor &indentor) : indentor(indentor)
- {
- indentor.indent++;
- }
- ~Indentation()
- {
- indentor.indent--;
- }
-
-private:
- Indentor &indentor;
-};
-
-inline QTextStream &operator <<(QTextStream &s, const Indentor &indentor)
-{
- for (int i = 0; i < indentor.indent; ++i)
- s << " ";
- return s;
-}
-
#endif // GENERATOR_H
diff --git a/sources/shiboken2/generator/indentor.h b/sources/shiboken2/generator/indentor.h
new file mode 100644
index 000000000..111259f12
--- /dev/null
+++ b/sources/shiboken2/generator/indentor.h
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part 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$
+**
+****************************************************************************/
+
+#ifndef INDENTOR_H
+#define INDENTOR_H
+
+#include <QtCore/QTextStream>
+
+/**
+* Utility class to store the indentation level, use it in a QTextStream.
+*/
+
+template <int tabWidth>
+class IndentorBase
+{
+public:
+ int total() const { return tabWidth * indent; }
+
+ int indent = 0;
+};
+
+using Indentor = IndentorBase<4>;
+using Indentor1 = IndentorBase<1>;
+
+/**
+* Class that use the RAII idiom to set and unset the indentation level.
+*/
+
+template <int tabWidth>
+class IndentationBase
+{
+public:
+ using Indentor = IndentorBase<tabWidth>;
+
+ IndentationBase(Indentor &indentor, int count = 1) : m_count(count), indentor(indentor)
+ {
+ indentor.indent += m_count;
+ }
+
+ ~IndentationBase()
+ {
+ indentor.indent -= m_count;
+ }
+
+private:
+ const int m_count;
+ Indentor &indentor;
+};
+
+using Indentation = IndentationBase<4>;
+
+template <int tabWidth>
+inline QTextStream &operator <<(QTextStream &s, const IndentorBase<tabWidth> &indentor)
+{
+ for (int i = 0, total = indentor.total(); i < total; ++i)
+ s << ' ';
+ return s;
+}
+
+#endif // GENERATOR_H
diff --git a/sources/shiboken2/generator/qtdoc/qtdocgenerator.cpp b/sources/shiboken2/generator/qtdoc/qtdocgenerator.cpp
index c194c0ea4..9410bc158 100644
--- a/sources/shiboken2/generator/qtdoc/qtdocgenerator.cpp
+++ b/sources/shiboken2/generator/qtdoc/qtdocgenerator.cpp
@@ -55,6 +55,13 @@ static inline QString briefAttribute() { return QStringLiteral("brief"); }
static inline QString none() { return QStringLiteral("None"); }
+static void stripPythonQualifiers(QString *s)
+{
+ const int lastSep = s->lastIndexOf(QLatin1Char('.'));
+ if (lastSep != -1)
+ s->remove(0, lastSep + 1);
+}
+
static bool shouldSkip(const AbstractMetaFunction* func)
{
// Constructors go to separate section
@@ -167,12 +174,33 @@ static QTextStream &ensureEndl(QTextStream &s)
return s;
}
-static void formatSince(QTextStream &s, const char *what, const TypeEntry *te)
+static inline QVersionNumber versionOf(const TypeEntry *te)
{
- if (te && te->version() > QVersionNumber(0, 0)) {
- s << ".. note:: This " << what << " was introduced in Qt "
- << te->version().toString() << '.' << endl;
+ if (te) {
+ const auto version = te->version();
+ if (!version.isNull() && version > QVersionNumber(0, 0))
+ return version;
}
+ return QVersionNumber();
+}
+
+struct rstVersionAdded
+{
+ explicit rstVersionAdded(const QVersionNumber &v) : m_version(v) {}
+
+ const QVersionNumber m_version;
+};
+
+static QTextStream &operator<<(QTextStream &s, const rstVersionAdded &v)
+{
+ s << ".. versionadded:: "<< v.m_version.toString() << "\n\n";
+ return s;
+}
+
+static QByteArray rstDeprecationNote(const char *what)
+{
+ return QByteArrayLiteral(".. note:: This ")
+ + what + QByteArrayLiteral(" is deprecated.\n\n");
}
// RST anchor string: Anything else but letters, numbers, '_' or '.' replaced by '-'
@@ -1013,22 +1041,19 @@ static QString fixLinkText(const QtXmlToSphinx::LinkContext *linkContext,
|| linkContext->type == QtXmlToSphinx::LinkContext::Reference) {
return linktext;
}
- // For the language reference documentation, clear the link text if it matches
- // the function/class/enumeration name.
- linktext.replace(QLatin1String("::"), QLatin1String("."));
+ // For the language reference documentation, strip the module name.
+ // Clear the link text if that matches the function/class/enumeration name.
+ const int lastSep = linktext.lastIndexOf(QLatin1String("::"));
+ if (lastSep != -1)
+ linktext.remove(0, lastSep + 2);
+ else
+ stripPythonQualifiers(&linktext);
if (linkContext->linkRef == linktext)
return QString();
if ((linkContext->type & QtXmlToSphinx::LinkContext::FunctionMask) != 0
&& (linkContext->linkRef + QLatin1String("()")) == linktext) {
return QString();
}
- const QStringRef item = linkContext->linkRef.splitRef(QLatin1Char('.')).constLast();
- if (item == linktext)
- return QString();
- if ((linkContext->type & QtXmlToSphinx::LinkContext::FunctionMask) != 0
- && (item + QLatin1String("()")) == linktext) {
- return QString();
- }
return linktext;
}
@@ -1576,7 +1601,11 @@ void QtDocGenerator::generateClass(QTextStream &s, GeneratorContext &classContex
writeInheritedByList(s, metaClass, classes());
- formatSince(s, "class", metaClass->typeEntry());
+ const auto version = versionOf(metaClass->typeEntry());
+ if (!version.isNull())
+ s << rstVersionAdded(version);
+ if (metaClass->attributes().testFlag(AbstractMetaAttributes::Deprecated))
+ s << rstDeprecationNote("class");
writeFunctionList(s, metaClass);
@@ -1608,7 +1637,7 @@ void QtDocGenerator::generateClass(QTextStream &s, GeneratorContext &classContex
else
s << ".. method:: ";
- writeFunction(s, true, metaClass, func);
+ writeFunction(s, metaClass, func);
}
writeInjectDocumentation(s, TypeSystem::DocModificationAppend, metaClass, 0);
@@ -1697,7 +1726,9 @@ void QtDocGenerator::writeEnums(QTextStream& s, const AbstractMetaClass* cppClas
for (AbstractMetaEnum *en : enums) {
s << section_title << getClassTargetFullName(cppClass) << '.' << en->name() << endl << endl;
writeFormattedText(s, en->documentation(), cppClass);
- formatSince(s, "enum", en->typeEntry());
+ const auto version = versionOf(en->typeEntry());
+ if (!version.isNull())
+ s << rstVersionAdded(version);
}
}
@@ -1717,7 +1748,6 @@ void QtDocGenerator::writeFields(QTextStream& s, const AbstractMetaClass* cppCla
void QtDocGenerator::writeConstructors(QTextStream& s, const AbstractMetaClass* cppClass)
{
static const QString sectionTitle = QLatin1String(".. class:: ");
- static const QString sectionTitleSpace = QString(sectionTitle.size(), QLatin1Char(' '));
AbstractMetaFunctionList lst = cppClass->queryFunctions(AbstractMetaClass::Constructors | AbstractMetaClass::Visible);
for (int i = lst.size() - 1; i >= 0; --i) {
@@ -1728,14 +1758,23 @@ void QtDocGenerator::writeConstructors(QTextStream& s, const AbstractMetaClass*
bool first = true;
QHash<QString, AbstractMetaArgument*> arg_map;
+ IndentorBase<1> indent1;
+ indent1.indent = INDENT.total();
for (AbstractMetaFunction *func : qAsConst(lst)) {
+ s << indent1;
if (first) {
first = false;
s << sectionTitle;
- } else {
- s << sectionTitleSpace;
+ indent1.indent += sectionTitle.size();
}
- writeFunction(s, false, cppClass, func);
+ s << functionSignature(cppClass, func) << "\n\n";
+
+ const auto version = versionOf(func->typeEntry());
+ if (!version.isNull())
+ s << indent1 << rstVersionAdded(version);
+ if (func->attributes().testFlag(AbstractMetaAttributes::Deprecated))
+ s << indent1 << rstDeprecationNote("constructor");
+
const AbstractMetaArgumentList &arguments = func->arguments();
for (AbstractMetaArgument *arg : arguments) {
if (!arg_map.contains(arg->name())) {
@@ -1747,7 +1786,7 @@ void QtDocGenerator::writeConstructors(QTextStream& s, const AbstractMetaClass*
s << endl;
for (QHash<QString, AbstractMetaArgument*>::const_iterator it = arg_map.cbegin(), end = arg_map.cend(); it != end; ++it) {
- Indentation indentation(INDENT);
+ Indentation indentation(INDENT, 2);
writeParameterType(s, cppClass, it.value());
}
@@ -1910,7 +1949,7 @@ bool QtDocGenerator::writeInjectDocumentation(QTextStream& s,
return didSomething;
}
-void QtDocGenerator::writeFunctionSignature(QTextStream& s, const AbstractMetaClass* cppClass, const AbstractMetaFunction* func)
+QString QtDocGenerator::functionSignature(const AbstractMetaClass* cppClass, const AbstractMetaFunction* func)
{
QString className;
if (!func->isConstructor())
@@ -1922,23 +1961,25 @@ void QtDocGenerator::writeFunctionSignature(QTextStream& s, const AbstractMetaCl
if (!funcName.startsWith(className))
funcName = className + funcName;
- s << funcName << "(" << parseArgDocStyle(cppClass, func) << ")";
+ return funcName + QLatin1Char('(') + parseArgDocStyle(cppClass, func)
+ + QLatin1Char(')');
}
QString QtDocGenerator::translateToPythonType(const AbstractMetaType* type, const AbstractMetaClass* cppClass)
{
QString strType;
- if (type->name() == QLatin1String("QString")) {
+ const QString name = type->name();
+ if (name == QLatin1String("QString")) {
strType = QLatin1String("unicode");
- } else if (type->name() == QLatin1String("QVariant")) {
+ } else if (name == QLatin1String("QVariant")) {
strType = QLatin1String("object");
- } else if (type->name() == QLatin1String("QStringList")) {
+ } else if (name == QLatin1String("QStringList")) {
strType = QLatin1String("list of strings");
- } else if (type->isConstant() && type->name() == QLatin1String("char") && type->indirections() == 1) {
+ } else if (type->isConstant() && name == QLatin1String("char") && type->indirections() == 1) {
strType = QLatin1String("str");
- } else if (type->name().startsWith(QLatin1String("unsigned short"))) {
+ } else if (name.startsWith(QLatin1String("unsigned short"))) {
strType = QLatin1String("int");
- } else if (type->name().startsWith(QLatin1String("unsigned "))) { // uint and ulong
+ } else if (name.startsWith(QLatin1String("unsigned "))) { // uint and ulong
strType = QLatin1String("long");
} else if (type->isContainer()) {
QString strType = translateType(type, cppClass, Options(ExcludeConst) | ExcludeReference);
@@ -1962,7 +2003,7 @@ QString QtDocGenerator::translateToPythonType(const AbstractMetaType* type, cons
refTag = QLatin1String("attr");
else
refTag = QLatin1String("class");
- strType = QLatin1Char(':') + refTag + QLatin1String(":`") + type->fullName() + QLatin1Char('`');
+ strType = QLatin1Char(':') + refTag + QLatin1String(":`") + name + QLatin1Char('`');
}
return strType;
}
@@ -1976,8 +2017,6 @@ void QtDocGenerator::writeParameterType(QTextStream& s, const AbstractMetaClass*
void QtDocGenerator::writeFunctionParametersType(QTextStream &s, const AbstractMetaClass *cppClass,
const AbstractMetaFunction *func)
{
- Indentation indentation(INDENT);
-
s << endl;
const AbstractMetaArgumentList &funcArgs = func->arguments();
for (AbstractMetaArgument *arg : funcArgs) {
@@ -2009,22 +2048,25 @@ void QtDocGenerator::writeFunctionParametersType(QTextStream &s, const AbstractM
s << endl;
}
-void QtDocGenerator::writeFunction(QTextStream& s, bool writeDoc, const AbstractMetaClass* cppClass, const AbstractMetaFunction* func)
+void QtDocGenerator::writeFunction(QTextStream& s, const AbstractMetaClass* cppClass,
+ const AbstractMetaFunction* func)
{
- writeFunctionSignature(s, cppClass, func);
- s << endl;
-
- formatSince(s, "method", func->typeEntry());
+ s << functionSignature(cppClass, func) << "\n\n";
- if (writeDoc) {
- s << endl;
+ {
+ Indentation indentation(INDENT);
writeFunctionParametersType(s, cppClass, func);
- s << endl;
- writeInjectDocumentation(s, TypeSystem::DocModificationPrepend, cppClass, func);
- if (!writeInjectDocumentation(s, TypeSystem::DocModificationReplace, cppClass, func))
- writeFormattedText(s, func->documentation(), cppClass);
- writeInjectDocumentation(s, TypeSystem::DocModificationAppend, cppClass, func);
+ const auto version = versionOf(func->typeEntry());
+ if (!version.isNull())
+ s << INDENT << rstVersionAdded(version);
+ if (func->attributes().testFlag(AbstractMetaAttributes::Deprecated))
+ s << INDENT << rstDeprecationNote("function");
}
+
+ writeInjectDocumentation(s, TypeSystem::DocModificationPrepend, cppClass, func);
+ if (!writeInjectDocumentation(s, TypeSystem::DocModificationReplace, cppClass, func))
+ writeFormattedText(s, func->documentation(), cppClass);
+ writeInjectDocumentation(s, TypeSystem::DocModificationAppend, cppClass, func);
}
static void writeFancyToc(QTextStream& s, const QStringList& items, int cols = 4)
@@ -2159,7 +2201,7 @@ void QtDocGenerator::writeModuleDocumentation()
Documentation moduleDoc = m_docParser->retrieveModuleDocumentation(it.key());
if (moduleDoc.format() == Documentation::Native) {
QString context = it.key();
- context.remove(0, context.lastIndexOf(QLatin1Char('.')) + 1);
+ stripPythonQualifiers(&context);
QtXmlToSphinx x(this, moduleDoc.value(), context);
s << x;
} else {
diff --git a/sources/shiboken2/generator/qtdoc/qtdocgenerator.h b/sources/shiboken2/generator/qtdoc/qtdocgenerator.h
index 5545de9a9..43345716d 100644
--- a/sources/shiboken2/generator/qtdoc/qtdocgenerator.h
+++ b/sources/shiboken2/generator/qtdoc/qtdocgenerator.h
@@ -239,8 +239,9 @@ private:
void writeFields(QTextStream &s, const AbstractMetaClass *cppClass);
void writeArguments(QTextStream &s, const AbstractMetaClass *cppClass, const AbstractMetaFunction *func);
- void writeFunctionSignature(QTextStream& s, const AbstractMetaClass* cppClass, const AbstractMetaFunction* func);
- void writeFunction(QTextStream& s, bool writeDoc, const AbstractMetaClass* cppClass, const AbstractMetaFunction* func);
+ QString functionSignature(const AbstractMetaClass* cppClass, const AbstractMetaFunction* func);
+ void writeFunction(QTextStream& s, const AbstractMetaClass* cppClass,
+ const AbstractMetaFunction* func);
void writeFunctionParametersType(QTextStream &s, const AbstractMetaClass *cppClass,
const AbstractMetaFunction* func);
void writeFunctionList(QTextStream& s, const AbstractMetaClass* cppClass);
diff --git a/sources/shiboken2/generator/shiboken2/cppgenerator.cpp b/sources/shiboken2/generator/shiboken2/cppgenerator.cpp
index f2112e34f..86a632e78 100644
--- a/sources/shiboken2/generator/shiboken2/cppgenerator.cpp
+++ b/sources/shiboken2/generator/shiboken2/cppgenerator.cpp
@@ -2091,10 +2091,7 @@ void CppGenerator::writeCppSelfDefinition(QTextStream &s,
QString checkFunc = cpythonCheckFunction(func->ownerClass()->typeEntry());
s << INDENT << "bool isReverse = " << checkFunc << PYTHON_ARG << ')' << endl;
{
- Indentation indent1(INDENT);
- Indentation indent2(INDENT);
- Indentation indent3(INDENT);
- Indentation indent4(INDENT);
+ Indentation indent1(INDENT, 4);
s << INDENT << "&& !" << checkFunc << "self);" << endl;
}
s << INDENT << "if (isReverse)" << endl;
@@ -5536,7 +5533,7 @@ bool CppGenerator::finishGeneration()
if (usePySideExtensions()) {
s << "void cleanTypesAttributes(void) {" << endl;
s << INDENT << "if (PY_VERSION_HEX >= 0x03000000 && PY_VERSION_HEX < 0x03060000)" << endl;
- s << INDENT << " return; // testbinding crashes in Python 3.5 when hasattr touches types!" << endl;
+ s << INDENT << " return; // PYSIDE-953: testbinding crashes in Python 3.5 when hasattr touches types!" << endl;
s << INDENT << "for (int i = 0, imax = SBK_" << moduleName() << "_IDX_COUNT; i < imax; i++) {" << endl;
{
Indentation indentation(INDENT);
diff --git a/sources/shiboken2/generator/shiboken2/overloaddata.cpp b/sources/shiboken2/generator/shiboken2/overloaddata.cpp
index a95603754..6a85bf7ef 100644
--- a/sources/shiboken2/generator/shiboken2/overloaddata.cpp
+++ b/sources/shiboken2/generator/shiboken2/overloaddata.cpp
@@ -30,6 +30,7 @@
#include <reporthandler.h>
#include <graph.h>
#include "overloaddata.h"
+#include "indentor.h"
#include "shibokengenerator.h"
#include <QtCore/QDir>
@@ -857,13 +858,14 @@ static inline QString toHtml(QString s)
QString OverloadData::dumpGraph() const
{
- QString indent(4, QLatin1Char(' '));
+ Indentor INDENT;
+ Indentation indent(INDENT);
QString result;
QTextStream s(&result);
if (m_argPos == -1) {
const AbstractMetaFunction* rfunc = referenceFunction();
s << "digraph OverloadedFunction {" << endl;
- s << indent << "graph [fontsize=12 fontname=freemono labelloc=t splines=true overlap=false rankdir=LR];" << endl;
+ s << INDENT << "graph [fontsize=12 fontname=freemono labelloc=t splines=true overlap=false rankdir=LR];" << endl;
// Shows all function signatures
s << "legend [fontsize=9 fontname=freemono shape=rect label=\"";
@@ -878,7 +880,7 @@ QString OverloadData::dumpGraph() const
s << "\"];" << endl;
// Function box title
- s << indent << '"' << rfunc->name() << "\" [shape=plaintext style=\"filled,bold\" margin=0 fontname=freemono fillcolor=white penwidth=1 ";
+ s << INDENT << '"' << rfunc->name() << "\" [shape=plaintext style=\"filled,bold\" margin=0 fontname=freemono fillcolor=white penwidth=1 ";
s << "label=<<table border=\"0\" cellborder=\"0\" cellpadding=\"3\" bgcolor=\"white\">";
s << "<tr><td bgcolor=\"black\" align=\"center\" cellpadding=\"6\" colspan=\"2\"><font color=\"white\">";
if (rfunc->ownerClass())
@@ -931,14 +933,14 @@ QString OverloadData::dumpGraph() const
s << "</table>> ];" << endl;
for (const OverloadData *pd : m_nextOverloadData)
- s << indent << '"' << rfunc->name() << "\" -> " << pd->dumpGraph();
+ s << INDENT << '"' << rfunc->name() << "\" -> " << pd->dumpGraph();
s << "}" << endl;
} else {
QString argId = QLatin1String("arg_") + QString::number(quintptr(this));
s << argId << ';' << endl;
- s << indent << '"' << argId << "\" [shape=\"plaintext\" style=\"filled,bold\" margin=\"0\" fontname=\"freemono\" fillcolor=\"white\" penwidth=1 ";
+ s << INDENT << '"' << argId << "\" [shape=\"plaintext\" style=\"filled,bold\" margin=\"0\" fontname=\"freemono\" fillcolor=\"white\" penwidth=1 ";
s << "label=<<table border=\"0\" cellborder=\"0\" cellpadding=\"3\" bgcolor=\"white\">";
// Argument box title
@@ -982,7 +984,7 @@ QString OverloadData::dumpGraph() const
s << "</table>>];" << endl;
for (const OverloadData *pd : m_nextOverloadData)
- s << indent << argId << " -> " << pd->dumpGraph();
+ s << INDENT << argId << " -> " << pd->dumpGraph();
}
return result;
}
diff --git a/sources/shiboken2/libshiboken/signature.cpp b/sources/shiboken2/libshiboken/signature.cpp
index 61a097771..cd00a1482 100644
--- a/sources/shiboken2/libshiboken/signature.cpp
+++ b/sources/shiboken2/libshiboken/signature.cpp
@@ -167,8 +167,11 @@ _get_class_of_descr(PyObject *ob)
static PyObject *
GetClassOfFunc(PyObject *ob)
{
- if (PyType_Check(ob))
+ if (PyType_Check(ob)) {
+ // PySide-928: The type case must do refcounting like the others as well.
+ Py_INCREF(ob);
return ob;
+ }
if (PyType_IsSubtype(Py_TYPE(ob), &PyCFunction_Type))
return _get_class_of_cf(ob);
if (Py_TYPE(ob) == PepStaticMethod_TypePtr)
@@ -535,6 +538,10 @@ error:
static int
_fixup_getset(PyTypeObject *type, const char *name, PyGetSetDef *new_gsp)
{
+ /*
+ * This function pre-fills all fields of the new gsp. We then
+ * insert the changed values.
+ */
PyGetSetDef *gsp = type->tp_getset;
if (gsp != nullptr) {
for (; gsp->name != NULL; gsp++) {
@@ -542,7 +549,7 @@ _fixup_getset(PyTypeObject *type, const char *name, PyGetSetDef *new_gsp)
new_gsp->set = gsp->set;
new_gsp->doc = gsp->doc;
new_gsp->closure = gsp->closure;
- return 1;
+ return 1; // success
}
}
}
diff --git a/sources/shiboken2/libshiboken/voidptr.cpp b/sources/shiboken2/libshiboken/voidptr.cpp
index a306f7a9d..e55ccfab5 100644
--- a/sources/shiboken2/libshiboken/voidptr.cpp
+++ b/sources/shiboken2/libshiboken/voidptr.cpp
@@ -95,13 +95,6 @@ int SbkVoidPtrObject_init(PyObject *self, PyObject *args, PyObject *kwds)
sbkSelf->size = sbkOther->size;
sbkSelf->isWritable = sbkOther->isWritable;
}
- // Shiboken::Object wrapper.
- else if (Shiboken::Object::checkType(addressObject)) {
- SbkObject *sbkOther = reinterpret_cast<SbkObject *>(addressObject);
- sbkSelf->cptr = sbkOther->d->cptr[0];
- sbkSelf->size = size;
- sbkSelf->isWritable = isWritable > 0 ? true : false;
- }
// Python buffer interface.
else if (PyObject_CheckBuffer(addressObject)) {
Py_buffer bufferView;
@@ -111,26 +104,41 @@ int SbkVoidPtrObject_init(PyObject *self, PyObject *args, PyObject *kwds)
return 0;
sbkSelf->cptr = bufferView.buf;
- sbkSelf->size = bufferView.len;
+ sbkSelf->size = bufferView.len > 0 ? bufferView.len : size;
sbkSelf->isWritable = bufferView.readonly > 0 ? false : true;
// Release the buffer.
PyBuffer_Release(&bufferView);
}
+ // Shiboken::Object wrapper.
+ else if (Shiboken::Object::checkType(addressObject)) {
+ SbkObject *sbkOther = reinterpret_cast<SbkObject *>(addressObject);
+ sbkSelf->cptr = sbkOther->d->cptr[0];
+ sbkSelf->size = size;
+ sbkSelf->isWritable = isWritable > 0 ? true : false;
+ }
// An integer representing an address.
else {
- void *cptr = PyLong_AsVoidPtr(addressObject);
- if (PyErr_Occurred()) {
- PyErr_SetString(PyExc_TypeError,
- "Creating a VoidPtr object requires an address of a C++ object, "
- "a wrapped Shiboken Object type, "
- "an object implementing the Python Buffer interface, "
- "or another VoidPtr object.");
- return -1;
+ if (addressObject == Py_None) {
+ sbkSelf->cptr = nullptr;
+ sbkSelf->size = 0;
+ sbkSelf->isWritable = false;
+ }
+
+ else {
+ void *cptr = PyLong_AsVoidPtr(addressObject);
+ if (PyErr_Occurred()) {
+ PyErr_SetString(PyExc_TypeError,
+ "Creating a VoidPtr object requires an address of a C++ object, "
+ "a wrapped Shiboken Object type, "
+ "an object implementing the Python Buffer interface, "
+ "or another VoidPtr object.");
+ return -1;
+ }
+ sbkSelf->cptr = cptr;
+ sbkSelf->size = size;
+ sbkSelf->isWritable = isWritable > 0 ? true : false;
}
- sbkSelf->cptr = cptr;
- sbkSelf->size = size;
- sbkSelf->isWritable = isWritable > 0 ? true : false;
}
return 0;
@@ -174,6 +182,24 @@ PyObject *SbkVoidPtrObject_int(PyObject *v)
return PyLong_FromVoidPtr(sbkObject->cptr);
}
+PyObject *toBytes(PyObject *self, PyObject *args)
+{
+ SbkVoidPtrObject *sbkObject = reinterpret_cast<SbkVoidPtrObject *>(self);
+ if (sbkObject->size < 0) {
+ PyErr_SetString(PyExc_IndexError, "VoidPtr does not have a size set.");
+ return nullptr;
+ }
+ PyObject *bytes = PyBytes_FromStringAndSize(reinterpret_cast<const char*>(sbkObject->cptr),
+ sbkObject->size);
+ Py_XINCREF(bytes);
+ return bytes;
+}
+
+static struct PyMethodDef SbkVoidPtrObject_methods[] = {
+ {"toBytes", toBytes, METH_NOARGS},
+ {0}
+};
+
static Py_ssize_t SbkVoidPtrObject_length(PyObject *v)
{
SbkVoidPtrObject *sbkObject = reinterpret_cast<SbkVoidPtrObject *>(v);
@@ -233,6 +259,7 @@ static PyType_Slot SbkVoidPtrType_slots[] = {
{Py_tp_init, (void *)SbkVoidPtrObject_init},
{Py_tp_new, (void *)SbkVoidPtrObject_new},
{Py_tp_dealloc, (void *)object_dealloc},
+ {Py_tp_methods, (void *)SbkVoidPtrObject_methods},
{0, 0}
};
static PyType_Spec SbkVoidPtrType_spec = {
diff --git a/sources/shiboken2/shibokenmodule/CMakeLists.txt b/sources/shiboken2/shibokenmodule/CMakeLists.txt
index 952d31994..b37d0c941 100644
--- a/sources/shiboken2/shibokenmodule/CMakeLists.txt
+++ b/sources/shiboken2/shibokenmodule/CMakeLists.txt
@@ -70,10 +70,6 @@ configure_file("${CMAKE_CURRENT_SOURCE_DIR}/support/signature/lib/__init__.py"
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/support/signature/lib/enum_sig.py"
"${CMAKE_CURRENT_BINARY_DIR}/support/signature/lib/enum_sig.py" COPYONLY)
if (PYTHON_VERSION_MAJOR EQUAL 3)
- if (PYTHON_VERSION_MINOR EQUAL 5)
- configure_file("${CMAKE_CURRENT_SOURCE_DIR}/support/signature/contextlib36.py"
- "${CMAKE_CURRENT_BINARY_DIR}/support/signature/contextlib36.py" COPYONLY)
- endif()
else()
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/support/signature/backport_inspect.py"
"${CMAKE_CURRENT_BINARY_DIR}/support/signature/backport_inspect.py" COPYONLY)
diff --git a/sources/shiboken2/shibokenmodule/support/signature/fix-complaints.py b/sources/shiboken2/shibokenmodule/support/signature/fix-complaints.py
index ef18beb67..cdd84f9be 100644
--- a/sources/shiboken2/shibokenmodule/support/signature/fix-complaints.py
+++ b/sources/shiboken2/shibokenmodule/support/signature/fix-complaints.py
@@ -49,7 +49,7 @@ you are changing messages (what I did, of course :-) .
import os
-patched_modules = "backport_inspect typing27 contextlib36"
+patched_modules = "backport_inspect typing27"
offending_words = {
"behavio""ur": "behavior",
diff --git a/sources/shiboken2/shibokenmodule/support/signature/loader.py b/sources/shiboken2/shibokenmodule/support/signature/loader.py
index 749229c3b..458759845 100644
--- a/sources/shiboken2/shibokenmodule/support/signature/loader.py
+++ b/sources/shiboken2/shibokenmodule/support/signature/loader.py
@@ -158,10 +158,6 @@ with ensure_import_support():
import typing
import inspect
inspect.formatannotation = formatannotation
- if sys.version_info[:2] == (3, 5):
- # PYSIDE-953: Use a newer contextlib.
- from support.signature import contextlib36 as contextlib
- sys.modules["contextlib"] = contextlib
else:
import inspect
namespace = inspect.__dict__
diff --git a/sources/shiboken2/tests/libsample/nontypetemplate.h b/sources/shiboken2/tests/libsample/nontypetemplate.h
index 4e2100626..5a9e670c6 100644
--- a/sources/shiboken2/tests/libsample/nontypetemplate.h
+++ b/sources/shiboken2/tests/libsample/nontypetemplate.h
@@ -37,6 +37,7 @@
template <int Size> class IntArray
{
public:
+ explicit IntArray(const int *data) { std::copy(data, data + Size, m_array); }
explicit IntArray(int v) { std::fill(m_array, m_array + Size, v); }
int sum() const { return std::accumulate(m_array, m_array + Size, int(0)); }
diff --git a/sources/shiboken2/tests/samplebinding/nontypetemplate_test.py b/sources/shiboken2/tests/samplebinding/nontypetemplate_test.py
index 9adfa2441..a7a4da72b 100644
--- a/sources/shiboken2/tests/samplebinding/nontypetemplate_test.py
+++ b/sources/shiboken2/tests/samplebinding/nontypetemplate_test.py
@@ -28,6 +28,14 @@
##
#############################################################################
+hasNumPy = False
+
+try:
+ import numpy
+ hasNumPy = True
+except ImportError:
+ pass
+
import unittest
from sample import IntArray2, IntArray3
@@ -40,5 +48,12 @@ class NonTypeTemplateTest(unittest.TestCase):
array3 = IntArray3(5)
self.assertEqual(array3.sum(), 15)
+ def testArrayInitializer(self):
+ if not hasNumPy:
+ return
+ array3 = IntArray3(numpy.array([1, 2, 3], dtype = 'int32'))
+ self.assertEqual(array3.sum(), 6)
+
+
if __name__ == '__main__':
unittest.main()
diff --git a/sources/shiboken2/tests/samplebinding/typesystem_sample.xml b/sources/shiboken2/tests/samplebinding/typesystem_sample.xml
index 9b967fc53..78ceaab43 100644
--- a/sources/shiboken2/tests/samplebinding/typesystem_sample.xml
+++ b/sources/shiboken2/tests/samplebinding/typesystem_sample.xml
@@ -521,8 +521,17 @@
</value-type>
<value-type name="IntArray" generate="no"/>
- <value-type name="IntArray2"/>
- <value-type name="IntArray3"/>
+ <value-type name="IntArray2">
+ <modify-function signature="IntArray2(const int*)">
+ <modify-argument index="1"><array/></modify-argument>
+ </modify-function>
+ </value-type>
+
+ <value-type name="IntArray3">
+ <modify-function signature="IntArray3(const int*)">
+ <modify-argument index="1"><array/></modify-argument>
+ </modify-function>
+ </value-type>
<enum-type name="OverloadedFuncEnum"/>
<!-- BUG: