aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@qt.io>2020-09-02 10:52:18 +0200
committerFriedemann Kleint <Friedemann.Kleint@qt.io>2020-09-30 08:21:03 +0000
commit0f922f604297a2022527f04a696da121396ddc0a (patch)
tree5a40599046ff6ab940aff6d639530237ce08c4d8
parent7af97fa4136d66bbad6c7907de6e7bd823de2e43 (diff)
Add QStringView/QByteArrayView
View types as function parameters cannot be converted in the standard way shiboken does it: QStringView cppArg0; pythonToCpp(pyArg, &cppArg0); since they reference some other data. Introduce a new "viewOn" member to type system entry for them. It causes the function arguments to be replaced by their viewed-on types (stringview->string) via metatype. Add a test in libsample and a test for QUuid::fromString(QStringView). Test returning QStringView via QRegularExpressionMatch::capturedView(). Task-number: QTBUG-84319 Task-number: PYSIDE-1339 Task-number: PYSIDE-904 Task-number: PYSIDE-487 Change-Id: Iddb4ea268a54928d290e29012e2738772fae83f0 Reviewed-by: Cristian Maureira-Fredes <cristian.maureira-fredes@qt.io>
-rw-r--r--sources/pyside2/PySide2/QtCore/typesystem_core_common.xml13
-rw-r--r--sources/pyside2/PySide2/glue/qtcore.cpp4
-rw-r--r--sources/pyside2/tests/QtCore/qregularexpression_test.py1
-rw-r--r--sources/pyside2/tests/QtCore/quuid_test.py3
-rw-r--r--sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp11
-rw-r--r--sources/shiboken2/ApiExtractor/abstractmetalang.cpp5
-rw-r--r--sources/shiboken2/ApiExtractor/abstractmetalang.h10
-rw-r--r--sources/shiboken2/ApiExtractor/messages.cpp6
-rw-r--r--sources/shiboken2/ApiExtractor/messages.h2
-rw-r--r--sources/shiboken2/ApiExtractor/typedatabase.cpp2
-rw-r--r--sources/shiboken2/ApiExtractor/typesystem.h7
-rw-r--r--sources/shiboken2/ApiExtractor/typesystemparser.cpp52
-rw-r--r--sources/shiboken2/ApiExtractor/typesystemparser.h4
-rw-r--r--sources/shiboken2/doc/typesystem_specifying_types.rst8
-rw-r--r--sources/shiboken2/generator/shiboken2/cppgenerator.cpp20
-rw-r--r--sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/mapping.py1
-rw-r--r--sources/shiboken2/tests/libsample/virtualmethods.cpp5
-rw-r--r--sources/shiboken2/tests/libsample/virtualmethods.h5
-rw-r--r--sources/shiboken2/tests/samplebinding/typesystem_sample.xml1
-rw-r--r--sources/shiboken2/tests/samplebinding/virtualmethods_test.py5
20 files changed, 144 insertions, 21 deletions
diff --git a/sources/pyside2/PySide2/QtCore/typesystem_core_common.xml b/sources/pyside2/PySide2/QtCore/typesystem_core_common.xml
index 2cbfe638b..46e3c6fe6 100644
--- a/sources/pyside2/PySide2/QtCore/typesystem_core_common.xml
+++ b/sources/pyside2/PySide2/QtCore/typesystem_core_common.xml
@@ -253,6 +253,13 @@
</conversion-rule>
</primitive-type>
+ <primitive-type name="QStringView" target-lang-api-name="PyUnicode" view-on="QString">
+ <include file-name="QStringView" location="global"/>
+ <conversion-rule>
+ <native-to-target file="../glue/qtcore.cpp" snippet="return-pyunicode"/>
+ </conversion-rule>
+ </primitive-type>
+
<primitive-type name="QChar">
<conversion-rule>
<native-to-target file="../glue/qtcore.cpp" snippet="return-pyunicode-qchar"/>
@@ -2022,6 +2029,12 @@
<inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qbytearray-msetitem"/>
</add-function>
</value-type>
+ <primitive-type name="QByteArrayView" view-on="QByteArray" since="6.0">
+ <conversion-rule>
+ <native-to-target file="../glue/qtcore.cpp" snippet="return-pybytes"/>
+ </conversion-rule>
+ </primitive-type>
+
<value-type name="QTextBoundaryFinder">
<enum-type name="BoundaryReason" flags="BoundaryReasons"/>
<enum-type name="BoundaryType"/>
diff --git a/sources/pyside2/PySide2/glue/qtcore.cpp b/sources/pyside2/PySide2/glue/qtcore.cpp
index 45e0e8c25..eb8d6dff4 100644
--- a/sources/pyside2/PySide2/glue/qtcore.cpp
+++ b/sources/pyside2/PySide2/glue/qtcore.cpp
@@ -1839,6 +1839,10 @@ int usec = PyDateTime_TIME_GET_MICROSECOND(%in);
return PyBool_FromLong((bool)%in);
// @snippet return-pybool
+// @snippet return-pybytes
+return PyBytes_FromStringAndSize(%in.constData(), %in.size());
+// @snippet return-pybytes
+
// @snippet return-pylong
return PyLong_FromLong(%in);
// @snippet return-pylong
diff --git a/sources/pyside2/tests/QtCore/qregularexpression_test.py b/sources/pyside2/tests/QtCore/qregularexpression_test.py
index fb2e9c24c..50c755d0e 100644
--- a/sources/pyside2/tests/QtCore/qregularexpression_test.py
+++ b/sources/pyside2/tests/QtCore/qregularexpression_test.py
@@ -48,6 +48,7 @@ class QRegularExpressionTest(unittest.TestCase):
match = re.match('word1 word2 word3')
self.assertTrue(match.isValid())
self.assertEqual(match.captured(1), 'word2')
+ self.assertEqual(match.capturedView(1), 'word2')
def testMatchIterator(self):
re = QRegularExpression('(\w+)')
diff --git a/sources/pyside2/tests/QtCore/quuid_test.py b/sources/pyside2/tests/QtCore/quuid_test.py
index da34429f9..ecb4a9562 100644
--- a/sources/pyside2/tests/QtCore/quuid_test.py
+++ b/sources/pyside2/tests/QtCore/quuid_test.py
@@ -43,7 +43,8 @@ from PySide2.QtCore import QUuid
class QUuidTest(unittest.TestCase):
def testFromString(self):
uuidString = '{fc69b59e-cc34-4436-a43c-ee95d128b8c5}'
- uuid = QUuid(uuidString)
+# testing overload QUUid::fromString(QStringView)
+ uuid = QUuid.fromString(uuidString)
self.assertTrue(not uuid.isNull())
self.assertEqual(uuid.toString(), uuidString)
diff --git a/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp b/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp
index 899d910bc..d06a338a3 100644
--- a/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp
+++ b/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp
@@ -1884,6 +1884,17 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(const Functio
return nullptr;
}
+ // Add view substitution for simple view types of function arguments
+ // std::string_view -> std::string for foo(std::string_view)
+ auto viewOnTypeEntry = metaType->typeEntry()->viewOn();
+ if (viewOnTypeEntry != nullptr && metaType->indirections() == 0
+ && metaType->arrayElementType() == nullptr
+ && !metaType->hasInstantiations()) {
+ auto viewOn = new AbstractMetaType(*metaType);
+ viewOn->setTypeEntry(viewOnTypeEntry);
+ metaType->setViewOn(viewOn);
+ }
+
auto *metaArgument = new AbstractMetaArgument;
metaArgument->setType(metaType);
diff --git a/sources/shiboken2/ApiExtractor/abstractmetalang.cpp b/sources/shiboken2/ApiExtractor/abstractmetalang.cpp
index 7d98d9ae8..edb449b04 100644
--- a/sources/shiboken2/ApiExtractor/abstractmetalang.cpp
+++ b/sources/shiboken2/ApiExtractor/abstractmetalang.cpp
@@ -194,10 +194,13 @@ AbstractMetaType::AbstractMetaType() :
{
}
+AbstractMetaType::AbstractMetaType(const AbstractMetaType &rhs) = default;
+
AbstractMetaType::~AbstractMetaType()
{
qDeleteAll(m_children);
m_instantiations.clear();
+ delete m_viewOn;
}
QString AbstractMetaType::package() const
@@ -449,6 +452,8 @@ QDebug operator<<(QDebug d, const AbstractMetaType *at)
}
}
d << '>';
+ if (at->viewOn())
+ d << ", views " << at->viewOn()->name();
}
} else {
d << '0';
diff --git a/sources/shiboken2/ApiExtractor/abstractmetalang.h b/sources/shiboken2/ApiExtractor/abstractmetalang.h
index 648c792b3..0e187fbcf 100644
--- a/sources/shiboken2/ApiExtractor/abstractmetalang.h
+++ b/sources/shiboken2/ApiExtractor/abstractmetalang.h
@@ -303,6 +303,7 @@ public:
Q_DECLARE_FLAGS(ComparisonFlags, ComparisonFlag);
AbstractMetaType();
+ AbstractMetaType(const AbstractMetaType &);
~AbstractMetaType();
QString package() const;
@@ -530,6 +531,12 @@ public:
bool compare(const AbstractMetaType &rhs, ComparisonFlags = {}) const;
+ // View on: Type to use for function argument conversion, fex
+ // std::string_view -> std::string for foo(std::string_view);
+ // cf TypeEntry::viewOn()
+ const AbstractMetaType *viewOn() const { return m_viewOn; }
+ void setViewOn(const AbstractMetaType *v) { m_viewOn = v; }
+
private:
TypeUsagePattern determineUsagePattern() const;
QString formatSignature(bool minimal) const;
@@ -545,6 +552,7 @@ private:
int m_arrayElementCount = -1;
const AbstractMetaType *m_arrayElementType = nullptr;
const AbstractMetaType *m_originalTemplateType = nullptr;
+ const AbstractMetaType *m_viewOn = nullptr;
Indirections m_indirections;
TypeUsagePattern m_pattern = InvalidPattern;
@@ -555,8 +563,6 @@ private:
ReferenceType m_referenceType = NoReference;
AbstractMetaTypeList m_children;
-
- Q_DISABLE_COPY(AbstractMetaType)
};
Q_DECLARE_OPERATORS_FOR_FLAGS(AbstractMetaType::ComparisonFlags);
diff --git a/sources/shiboken2/ApiExtractor/messages.cpp b/sources/shiboken2/ApiExtractor/messages.cpp
index 55c51ffa4..a660f7e76 100644
--- a/sources/shiboken2/ApiExtractor/messages.cpp
+++ b/sources/shiboken2/ApiExtractor/messages.cpp
@@ -649,6 +649,12 @@ QString msgIncorrectlyNestedName(const QString &name)
+ name + QLatin1String(").");
}
+QString msgCannotFindView(const QString &viewedName, const QString &name)
+{
+ return QLatin1String("Unable to find viewed type ") + viewedName
+ + QLatin1String(" for ") + name;
+}
+
// qtdocgenerator.cpp
QString msgTagWarning(const QXmlStreamReader &reader, const QString &context,
diff --git a/sources/shiboken2/ApiExtractor/messages.h b/sources/shiboken2/ApiExtractor/messages.h
index 6c173dc09..55481270c 100644
--- a/sources/shiboken2/ApiExtractor/messages.h
+++ b/sources/shiboken2/ApiExtractor/messages.h
@@ -179,6 +179,8 @@ QString msgNoRootTypeSystemEntry();
QString msgIncorrectlyNestedName(const QString &name);
+QString msgCannotFindView(const QString &viewedName, const QString &name);
+
QString msgCyclicDependency(const QString &funcName, const QString &graphName,
const QVector<const AbstractMetaFunction *> &involvedConversions);
diff --git a/sources/shiboken2/ApiExtractor/typedatabase.cpp b/sources/shiboken2/ApiExtractor/typedatabase.cpp
index 6aa5513fa..87f5c49df 100644
--- a/sources/shiboken2/ApiExtractor/typedatabase.cpp
+++ b/sources/shiboken2/ApiExtractor/typedatabase.cpp
@@ -894,6 +894,8 @@ void TypeEntry::formatDebug(QDebug &d) const
FORMAT_BOOL("stream", m_stream)
FORMAT_LIST_SIZE("codeSnips", m_codeSnips)
FORMAT_NONEMPTY_STRING("conversionRule", m_conversionRule)
+ if (m_viewOn)
+ d << ", views=" << m_viewOn->name();
if (!m_version.isNull() && m_version > QVersionNumber(0, 0))
d << ", version=" << m_version;
if (m_revision)
diff --git a/sources/shiboken2/ApiExtractor/typesystem.h b/sources/shiboken2/ApiExtractor/typesystem.h
index fa3eae9fc..00f56c51e 100644
--- a/sources/shiboken2/ApiExtractor/typesystem.h
+++ b/sources/shiboken2/ApiExtractor/typesystem.h
@@ -863,6 +863,12 @@ public:
void setCustomConversion(CustomConversion* customConversion);
CustomConversion* customConversion() const;
+ // View on: Type to use for function argument conversion, fex
+ // std::string_view -> std::string for foo(std::string_view).
+ // cf AbstractMetaType::viewOn()
+ TypeEntry *viewOn() const { return m_viewOn; }
+ void setViewOn(TypeEntry *v) { m_viewOn = v; }
+
virtual TypeEntry *clone() const;
void useAsTypedef(const TypeEntry *source);
@@ -898,6 +904,7 @@ private:
CustomConversion *m_customConversion = nullptr;
SourceLocation m_sourceLocation; // XML file
uint m_codeGeneration = GenerateAll;
+ TypeEntry *m_viewOn = nullptr;
int m_revision = 0;
int m_sbkIndex = 0;
Type m_type;
diff --git a/sources/shiboken2/ApiExtractor/typesystemparser.cpp b/sources/shiboken2/ApiExtractor/typesystemparser.cpp
index b71a247f3..7323e01f6 100644
--- a/sources/shiboken2/ApiExtractor/typesystemparser.cpp
+++ b/sources/shiboken2/ApiExtractor/typesystemparser.cpp
@@ -1112,16 +1112,44 @@ bool TypeSystemParser::checkRootElement()
return ok;
}
-void TypeSystemParser::applyCommonAttributes(const QXmlStreamReader &reader, TypeEntry *type,
- QXmlStreamAttributes *attributes) const
+static TypeEntry *findViewedType(const QString &name)
+{
+ const auto range = TypeDatabase::instance()->entries().equal_range(name);
+ for (auto i = range.first; i != range.second; ++i) {
+ switch (i.value()->type()) {
+ case TypeEntry::BasicValueType:
+ case TypeEntry::PrimitiveType:
+ case TypeEntry::ContainerType:
+ case TypeEntry::ObjectType:
+ return i.value();
+ default:
+ break;
+ }
+ }
+ return nullptr;
+}
+
+bool TypeSystemParser::applyCommonAttributes(const QXmlStreamReader &reader, TypeEntry *type,
+ QXmlStreamAttributes *attributes)
{
type->setSourceLocation(SourceLocation(m_currentFile,
reader.lineNumber()));
type->setCodeGeneration(m_generate);
- const int revisionIndex =
- indexOfAttribute(*attributes, u"revision");
- if (revisionIndex != -1)
- type->setRevision(attributes->takeAt(revisionIndex).value().toInt());
+ for (int i = attributes->size() - 1; i >= 0; --i) {
+ const auto name = attributes->at(i).qualifiedName();
+ if (name == u"revision") {
+ type->setRevision(attributes->takeAt(i).value().toInt());
+ } else if (name == u"view-on") {
+ const QString name = attributes->takeAt(i).value().toString();
+ TypeEntry *views = findViewedType(name);
+ if (views == nullptr) {
+ m_error = msgCannotFindView(name, type->name());
+ return false;
+ }
+ type->setViewOn(views);
+ }
+ }
+ return true;
}
FlagsTypeEntry *
@@ -1146,7 +1174,8 @@ FlagsTypeEntry *
}
ftype->setOriginalName(flagName);
- applyCommonAttributes(reader, ftype, attributes);
+ if (!applyCommonAttributes(reader, ftype, attributes))
+ return nullptr;
QStringList lst = flagName.split(colonColon());
const QString targetLangFlagName = QStringList(lst.mid(0, lst.size() - 1)).join(QLatin1Char('.'));
@@ -1225,7 +1254,8 @@ SmartPointerTypeEntry *
auto *type = new SmartPointerTypeEntry(name, getter, smartPointerType,
refCountMethodName, since, currentParentTypeEntry());
- applyCommonAttributes(reader, type, attributes);
+ if (!applyCommonAttributes(reader, type, attributes))
+ return nullptr;
m_smartPointerInstantiations.insert(type, instantiations);
return type;
}
@@ -1238,7 +1268,8 @@ PrimitiveTypeEntry *
if (!checkRootElement())
return nullptr;
auto *type = new PrimitiveTypeEntry(name, since, currentParentTypeEntry());
- applyCommonAttributes(reader, type, attributes);
+ if (!applyCommonAttributes(reader, type, attributes))
+ return nullptr;
for (int i = attributes->size() - 1; i >= 0; --i) {
const auto name = attributes->at(i).qualifiedName();
if (name == targetLangNameAttribute()) {
@@ -1282,7 +1313,8 @@ ContainerTypeEntry *
return nullptr;
}
auto *type = new ContainerTypeEntry(name, containerType, since, currentParentTypeEntry());
- applyCommonAttributes(reader, type, attributes);
+ if (!applyCommonAttributes(reader, type, attributes))
+ return nullptr;
return type;
}
diff --git a/sources/shiboken2/ApiExtractor/typesystemparser.h b/sources/shiboken2/ApiExtractor/typesystemparser.h
index 3eaa74f04..130d8d3d2 100644
--- a/sources/shiboken2/ApiExtractor/typesystemparser.h
+++ b/sources/shiboken2/ApiExtractor/typesystemparser.h
@@ -169,8 +169,8 @@ private:
const TypeEntry *currentParentTypeEntry() const;
bool checkRootElement();
- void applyCommonAttributes(const QXmlStreamReader &reader, TypeEntry *type,
- QXmlStreamAttributes *attributes) const;
+ bool applyCommonAttributes(const QXmlStreamReader &reader, TypeEntry *type,
+ QXmlStreamAttributes *attributes);
PrimitiveTypeEntry *
parsePrimitiveTypeEntry(const QXmlStreamReader &, const QString &name,
const QVersionNumber &since, QXmlStreamAttributes *);
diff --git a/sources/shiboken2/doc/typesystem_specifying_types.rst b/sources/shiboken2/doc/typesystem_specifying_types.rst
index 221519541..3b40ef236 100644
--- a/sources/shiboken2/doc/typesystem_specifying_types.rst
+++ b/sources/shiboken2/doc/typesystem_specifying_types.rst
@@ -108,6 +108,7 @@ primitive-type
target-name="..."
default-constructor="..."
preferred-conversion="yes | no" />
+ view-on="..."
</typesystem>
The **name** attribute is the name of the primitive in C++, the optional,
@@ -139,6 +140,13 @@ primitive-type
used only for classes declared as primitive types and not for primitive C++
types, but that depends on the application using *ApiExtractor*.
+ The *optional* **view-on** attribute specifies that the type is a view
+ class like std::string_view or QStringView which has a constructor
+ accepting another type like std::string or QString. Since typically
+ no values can be assigned to view classes, no target-to-native conversion
+ can be generated for them. Instead, an instance of the viewed class should
+ be instantiated and passed to functions using the view class
+ for argument types.
.. _namespace:
diff --git a/sources/shiboken2/generator/shiboken2/cppgenerator.cpp b/sources/shiboken2/generator/shiboken2/cppgenerator.cpp
index 8e9b480cc..89e97093b 100644
--- a/sources/shiboken2/generator/shiboken2/cppgenerator.cpp
+++ b/sources/shiboken2/generator/shiboken2/cppgenerator.cpp
@@ -2389,6 +2389,8 @@ void CppGenerator::writeTypeCheck(QTextStream &s, const OverloadData *overloadDa
// This condition trusts that the OverloadData object will arrange for
// PyInt type to come after the more precise numeric types (e.g. float and bool)
const AbstractMetaType *argType = overloadData->argType();
+ if (auto viewOn = argType->viewOn())
+ argType = viewOn;
bool numberType = numericTypes.count() == 1 || ShibokenGenerator::isPyInt(argType);
QString customType = (overloadData->hasArgumentTypeReplace() ? overloadData->argumentTypeReplaced() : QString());
bool rejectNull = shouldRejectNullPointerArgument(overloadData->referenceFunction(), overloadData->argPos());
@@ -2419,12 +2421,15 @@ const AbstractMetaType *CppGenerator::getArgumentType(const AbstractMetaFunction
return nullptr;
}
- const AbstractMetaType *argType = nullptr;
QString typeReplaced = func->typeReplaced(argPos);
- if (typeReplaced.isEmpty())
- argType = (argPos == 0) ? func->type() : func->arguments().at(argPos-1)->type();
- else
- argType = buildAbstractMetaTypeFromString(typeReplaced);
+ if (typeReplaced.isEmpty()) {
+ if (argPos == 0)
+ return func->type();
+ auto argType = func->arguments().at(argPos - 1)->type();
+ return argType->viewOn() ? argType->viewOn() : argType;
+ }
+
+ auto argType = buildAbstractMetaTypeFromString(typeReplaced);
if (!argType && !m_knownPythonTypes.contains(typeReplaced)) {
qCWarning(lcShiboken).noquote().nospace()
<< QString::fromLatin1("Unknown type '%1' used as argument type replacement "\
@@ -4804,7 +4809,10 @@ void CppGenerator::writeSignatureInfo(QTextStream &s, const AbstractMetaFunction
args << QLatin1String("self");
const AbstractMetaArgumentList &arguments = f->arguments();
for (const AbstractMetaArgument *arg : arguments) {
- QString strArg = arg->type()->pythonSignature();
+ const auto *metaType = arg->type();
+ if (auto viewOn = metaType->viewOn())
+ metaType = viewOn;
+ QString strArg = metaType->pythonSignature();
if (!arg->defaultValueExpression().isEmpty()) {
strArg += QLatin1Char('=');
QString e = arg->defaultValueExpression();
diff --git a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/mapping.py b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/mapping.py
index 4af214c8d..7a93fcbe9 100644
--- a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/mapping.py
+++ b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/mapping.py
@@ -255,6 +255,7 @@ type_map.update({
"qreal": float,
"QSet": typing.Set,
"QString": str,
+ "QStringView": str,
"QStringList": StringList,
"quint16": int,
"quint32": int,
diff --git a/sources/shiboken2/tests/libsample/virtualmethods.cpp b/sources/shiboken2/tests/libsample/virtualmethods.cpp
index 8f9c8f64d..705835c0b 100644
--- a/sources/shiboken2/tests/libsample/virtualmethods.cpp
+++ b/sources/shiboken2/tests/libsample/virtualmethods.cpp
@@ -63,6 +63,11 @@ const Str & VirtualMethods::returnConstRef() const
return result;
}
+int VirtualMethods::stringViewLength(std::string_view in) const
+{
+ return int(in.size());
+}
+
double VirtualDaughter2::virtualMethod0(Point pt, int val, Complex cpx, bool b)
{
return 42 + VirtualMethods::virtualMethod0(pt, val, cpx, b);
diff --git a/sources/shiboken2/tests/libsample/virtualmethods.h b/sources/shiboken2/tests/libsample/virtualmethods.h
index 4b2d25805..577f6919e 100644
--- a/sources/shiboken2/tests/libsample/virtualmethods.h
+++ b/sources/shiboken2/tests/libsample/virtualmethods.h
@@ -36,6 +36,9 @@
#include "libsamplemacros.h"
#include "strlist.h"
+#include <string_view>
+#include <string>
+
class LIBSAMPLE_API VirtualMethods
{
public:
@@ -108,6 +111,8 @@ public:
virtual const Str & returnConstRef() const;
+ virtual int stringViewLength(std::string_view in) const;
+
protected:
// PYSIDE-1388: Protected hack with final classes (see VirtualFinalDaughter).
void protectedMethod() {}
diff --git a/sources/shiboken2/tests/samplebinding/typesystem_sample.xml b/sources/shiboken2/tests/samplebinding/typesystem_sample.xml
index e4963721b..66ae6d0a1 100644
--- a/sources/shiboken2/tests/samplebinding/typesystem_sample.xml
+++ b/sources/shiboken2/tests/samplebinding/typesystem_sample.xml
@@ -25,6 +25,7 @@
<primitive-type name="long long"/>
<primitive-type name="unsigned long long"/>
<primitive-type name="std::string"/>
+ <primitive-type name="std::string_view" view-on="std::string"/>
<primitive-type name="ObjectType::Identifier"/>
<primitive-type name="Foo::HANDLE" target-lang-api-name="PyLong"/>
diff --git a/sources/shiboken2/tests/samplebinding/virtualmethods_test.py b/sources/shiboken2/tests/samplebinding/virtualmethods_test.py
index 2d3198071..07b79c489 100644
--- a/sources/shiboken2/tests/samplebinding/virtualmethods_test.py
+++ b/sources/shiboken2/tests/samplebinding/virtualmethods_test.py
@@ -133,6 +133,11 @@ class VirtualMethodsTest(unittest.TestCase):
self.assertTrue(eevd.grand_grand_daughter_name_called)
self.assertEqual(eevd.name().prepend(self.prefix_from_codeinjection), name)
+ def testStringView(self):
+ virtual_methods = VirtualMethods()
+ self.assertEqual(virtual_methods.stringViewLength('bla'), 3)
+
+
class PrettyErrorMessageTest(unittest.TestCase):
def testIt(self):
obj = ExtendedVirtualMethods()