From 91d8597a5d5f7b73f631da5c4d498e94ad7ce506 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 8 Jun 2021 08:47:54 +0200 Subject: shiboken6: Fix increment/decrement operators For classes that have increment/decrement operators (++/--), shiboken6 generated operators +=/-= ( __iadd__/__isub__) by calling them n times. This was mainly intended for iterators. However, when both operator++/-- and operator+=/-= were present (as introduced by qtdeclarative/f8f31dd0e1f9425ba272691c79e719ebc4bcfb94 for QJSPrimitiveValue), duplicate code and errors were generated. This requires filtering of the operator functions. Introduce a separate function type for increment/decrement operators and remove them if operators +=/-= were found. Also, when both prefix and postfix version of the increment/decrement operators are found, remove one. Extend existing class IntWrapper from libsample for testing. Add explanatory comment and use prefix increment. Change-Id: I0f8a0c79a6f74974ba327d21f35fff74962ffd3a Reviewed-by: Christian Tismer (cherry picked from commit 783720fdb308a686610b4f70e839930b60970362) Reviewed-by: Qt Cherry-pick Bot --- .../PySide6/QtGui/typesystem_gui_common.xml | 6 -- .../shiboken6/ApiExtractor/abstractmetabuilder.cpp | 6 ++ .../ApiExtractor/abstractmetafunction.cpp | 10 +++ .../shiboken6/ApiExtractor/abstractmetafunction.h | 3 + .../shiboken6/ApiExtractor/abstractmetalang.cpp | 11 +++ sources/shiboken6/ApiExtractor/abstractmetalang.h | 1 + .../ApiExtractor/abstractmetalang_enums.h | 15 ++-- .../shiboken6/ApiExtractor/parser/codemodel.cpp | 4 +- sources/shiboken6/ApiExtractor/parser/codemodel.h | 2 + .../shiboken6/generator/shiboken/cppgenerator.cpp | 59 ++++++++++++--- sources/shiboken6/tests/libsample/CMakeLists.txt | 1 + sources/shiboken6/tests/libsample/collector.cpp | 2 +- sources/shiboken6/tests/libsample/collector.h | 9 +-- sources/shiboken6/tests/libsample/intwrapper.cpp | 61 +++++++++++++++ sources/shiboken6/tests/libsample/intwrapper.h | 87 ++++++++++++++++++++++ .../tests/samplebinding/intwrapper_test.py | 61 +++++++++++++++ 16 files changed, 305 insertions(+), 33 deletions(-) create mode 100644 sources/shiboken6/tests/libsample/intwrapper.cpp create mode 100644 sources/shiboken6/tests/libsample/intwrapper.h create mode 100644 sources/shiboken6/tests/samplebinding/intwrapper_test.py diff --git a/sources/pyside6/PySide6/QtGui/typesystem_gui_common.xml b/sources/pyside6/PySide6/QtGui/typesystem_gui_common.xml index c54a7e5d7..ce546d9cc 100644 --- a/sources/pyside6/PySide6/QtGui/typesystem_gui_common.xml +++ b/sources/pyside6/PySide6/QtGui/typesystem_gui_common.xml @@ -1424,12 +1424,6 @@ - - - - diff --git a/sources/shiboken6/ApiExtractor/abstractmetabuilder.cpp b/sources/shiboken6/ApiExtractor/abstractmetabuilder.cpp index dafbed00e..cac311626 100644 --- a/sources/shiboken6/ApiExtractor/abstractmetabuilder.cpp +++ b/sources/shiboken6/ApiExtractor/abstractmetabuilder.cpp @@ -1730,6 +1730,12 @@ static inline AbstractMetaFunction::FunctionType functionTypeFromCodeModel(CodeM case CodeModel::ArithmeticOperator: result = AbstractMetaFunction::ArithmeticOperator; break; + case CodeModel::IncrementOperator: + result = AbstractMetaFunction::IncrementOperator; + break; + case CodeModel::DecrementOperator: + result = AbstractMetaFunction::DecrementOperator; + break; case CodeModel::BitwiseOperator: result = AbstractMetaFunction::BitwiseOperator; break; diff --git a/sources/shiboken6/ApiExtractor/abstractmetafunction.cpp b/sources/shiboken6/ApiExtractor/abstractmetafunction.cpp index 1b21b94b8..21677a3e5 100644 --- a/sources/shiboken6/ApiExtractor/abstractmetafunction.cpp +++ b/sources/shiboken6/ApiExtractor/abstractmetafunction.cpp @@ -1044,6 +1044,12 @@ bool AbstractMetaFunction::isComparisonOperator() const return d->m_functionType == ComparisonOperator; } +bool AbstractMetaFunction::isIncDecrementOperator() const +{ + return d->m_functionType == IncrementOperator + || d->m_functionType == DecrementOperator; +} + bool AbstractMetaFunction::isLogicalOperator() const { return d->m_functionType == LogicalOperator; @@ -1138,6 +1144,10 @@ bool AbstractMetaFunction::matches(OperatorQueryOptions query) const case AbstractMetaFunction::ArithmeticOperator: result = query.testFlag(OperatorQueryOption::ArithmeticOp); break; + case AbstractMetaFunction::IncrementOperator: + case AbstractMetaFunction::DecrementOperator: + result = query.testFlag(OperatorQueryOption::IncDecrementOp); + break; case AbstractMetaFunction::BitwiseOperator: case AbstractMetaFunction::ShiftOperator: result = query.testFlag(OperatorQueryOption::BitwiseOp); diff --git a/sources/shiboken6/ApiExtractor/abstractmetafunction.h b/sources/shiboken6/ApiExtractor/abstractmetafunction.h index 15192e6de..256a37e7e 100644 --- a/sources/shiboken6/ApiExtractor/abstractmetafunction.h +++ b/sources/shiboken6/ApiExtractor/abstractmetafunction.h @@ -73,6 +73,8 @@ public: ReferenceOperator, // operator & ArrowOperator, ArithmeticOperator, + IncrementOperator, + DecrementOperator, BitwiseOperator, LogicalOperator, ShiftOperator, @@ -204,6 +206,7 @@ public: bool isArithmeticOperator() const; bool isBitwiseOperator() const; // Includes shift operator bool isComparisonOperator() const; + bool isIncDecrementOperator() const; bool isLogicalOperator() const; bool isSubscriptOperator() const; bool isAssignmentOperator() const; // Assignment or move assignment diff --git a/sources/shiboken6/ApiExtractor/abstractmetalang.cpp b/sources/shiboken6/ApiExtractor/abstractmetalang.cpp index 20c4bb554..3c33f52bc 100644 --- a/sources/shiboken6/ApiExtractor/abstractmetalang.cpp +++ b/sources/shiboken6/ApiExtractor/abstractmetalang.cpp @@ -282,6 +282,17 @@ bool AbstractMetaClass::hasArithmeticOperatorOverload() const return false; } +bool AbstractMetaClass::hasIncDecrementOperatorOverload() const +{ + for (const auto & f: d->m_functions) { + if (f->ownerClass() == f->implementingClass() + && f->isIncDecrementOperator() && !f->isPrivate()) { + return true; + } + } + return false; +} + bool AbstractMetaClass::hasBitwiseOperatorOverload() const { for (const auto & f: d->m_functions) { diff --git a/sources/shiboken6/ApiExtractor/abstractmetalang.h b/sources/shiboken6/ApiExtractor/abstractmetalang.h index f83062dd7..daa9eba1e 100644 --- a/sources/shiboken6/ApiExtractor/abstractmetalang.h +++ b/sources/shiboken6/ApiExtractor/abstractmetalang.h @@ -166,6 +166,7 @@ public: AbstractMetaFunctionCList operatorOverloads(OperatorQueryOptions query) const; bool hasArithmeticOperatorOverload() const; + bool hasIncDecrementOperatorOverload() const; bool hasBitwiseOperatorOverload() const; bool hasComparisonOperatorOverload() const; bool hasLogicalOperatorOverload() const; diff --git a/sources/shiboken6/ApiExtractor/abstractmetalang_enums.h b/sources/shiboken6/ApiExtractor/abstractmetalang_enums.h index d2e50acba..c78e84320 100644 --- a/sources/shiboken6/ApiExtractor/abstractmetalang_enums.h +++ b/sources/shiboken6/ApiExtractor/abstractmetalang_enums.h @@ -58,13 +58,14 @@ Q_DECLARE_FLAGS(FunctionQueryOptions, FunctionQueryOption) Q_DECLARE_OPERATORS_FOR_FLAGS(FunctionQueryOptions) enum class OperatorQueryOption { - ArithmeticOp = 0x01, // Arithmetic: +, -, *, /, %, +=, -=, *=, /=, %=, ++, --, unary+, unary- - BitwiseOp = 0x02, // Bitwise: <<, <<=, >>, >>=, ~, &, &=, |, |=, ^, ^= - ComparisonOp = 0x04, // Comparison: <, <=, >, >=, !=, == - LogicalOp = 0x08, // Logical: !, &&, || - ConversionOp = 0x10, // Conversion: operator [const] TYPE() - SubscriptionOp = 0x20, // Subscription: [] - AssignmentOp = 0x40 // Assignment: = + ArithmeticOp = 0x01, // Arithmetic: +, -, *, /, %, +=, -=, *=, /=, %=, unary+, unary- + IncDecrementOp = 0x02, // ++, -- + BitwiseOp = 0x04, // Bitwise: <<, <<=, >>, >>=, ~, &, &=, |, |=, ^, ^= + ComparisonOp = 0x08, // Comparison: <, <=, >, >=, !=, == + LogicalOp = 0x10, // Logical: !, &&, || + ConversionOp = 0x20, // Conversion: operator [const] TYPE() + SubscriptionOp = 0x40, // Subscription: [] + AssignmentOp = 0x80 // Assignment: = }; Q_DECLARE_FLAGS(OperatorQueryOptions, OperatorQueryOption) diff --git a/sources/shiboken6/ApiExtractor/parser/codemodel.cpp b/sources/shiboken6/ApiExtractor/parser/codemodel.cpp index 5dda974a7..82f5e1a2c 100644 --- a/sources/shiboken6/ApiExtractor/parser/codemodel.cpp +++ b/sources/shiboken6/ApiExtractor/parser/codemodel.cpp @@ -961,8 +961,8 @@ static const NameFunctionTypeHash &nameToOperatorFunction() {u"operator/=", CodeModel::ArithmeticOperator}, {u"operator%", CodeModel::ArithmeticOperator}, {u"operator%=", CodeModel::ArithmeticOperator}, - {u"operator++", CodeModel::ArithmeticOperator}, - {u"operator--", CodeModel::ArithmeticOperator}, + {u"operator++", CodeModel::IncrementOperator}, + {u"operator--", CodeModel::DecrementOperator}, {u"operator&", CodeModel::BitwiseOperator}, {u"operator&=", CodeModel::BitwiseOperator}, {u"operator|", CodeModel::BitwiseOperator}, diff --git a/sources/shiboken6/ApiExtractor/parser/codemodel.h b/sources/shiboken6/ApiExtractor/parser/codemodel.h index c3bda9ef5..75ad60aaf 100644 --- a/sources/shiboken6/ApiExtractor/parser/codemodel.h +++ b/sources/shiboken6/ApiExtractor/parser/codemodel.h @@ -73,6 +73,8 @@ public: ReferenceOperator, // operator & ArrowOperator, ArithmeticOperator, + IncrementOperator, + DecrementOperator, BitwiseOperator, LogicalOperator, ShiftOperator, diff --git a/sources/shiboken6/generator/shiboken/cppgenerator.cpp b/sources/shiboken6/generator/shiboken/cppgenerator.cpp index 5a0d2a30f..2e9ea8d0b 100644 --- a/sources/shiboken6/generator/shiboken/cppgenerator.cpp +++ b/sources/shiboken6/generator/shiboken/cppgenerator.cpp @@ -209,21 +209,58 @@ QString CppGenerator::fileNameForContext(const GeneratorContext &context) const return fileNameBase + fileNameSuffix(); } +static bool isInplaceAdd(const AbstractMetaFunctionCPtr &func) +{ + return func->name() == u"operator+="; +} + +static bool isIncrementOperator(const AbstractMetaFunctionCPtr &func) +{ + return func->functionType() == AbstractMetaFunction::IncrementOperator; +} + +static bool isDecrementOperator(const AbstractMetaFunctionCPtr &func) +{ + return func->functionType() == AbstractMetaFunction::DecrementOperator; +} + +// Filter predicate for operator functions +static bool skipOperatorFunc(const AbstractMetaFunctionCPtr &func) +{ + if (func->isModifiedRemoved() || func->usesRValueReferences()) + return true; + const auto &name = func->name(); + return name == u"operator[]" || name == u"operator->" || name == u"operator!"; +} + QList CppGenerator::filterGroupedOperatorFunctions(const AbstractMetaClass *metaClass, OperatorQueryOptions query) { // ( func_name, num_args ) => func_list QMap, AbstractMetaFunctionCList> results; - const auto &funcs = metaClass->operatorOverloads(query); + + auto funcs = metaClass->operatorOverloads(query); + auto end = std::remove_if(funcs.begin(), funcs.end(), skipOperatorFunc); + funcs.erase(end, funcs.end()); + + // If we have operator+=, we remove the operator++/-- which would + // otherwise be used for emulating __iadd__, __isub__. + if (std::any_of(funcs.cbegin(), funcs.cend(), isInplaceAdd)) { + end = std::remove_if(funcs.begin(), funcs.end(), + [] (const AbstractMetaFunctionCPtr &func) { + return func->isIncDecrementOperator(); + }); + funcs.erase(end, funcs.end()); + } else { + // If both prefix/postfix ++/-- are present, remove one + if (std::count_if(funcs.begin(), funcs.end(), isIncrementOperator) > 1) + funcs.erase(std::find_if(funcs.begin(), funcs.end(), isIncrementOperator)); + if (std::count_if(funcs.begin(), funcs.end(), isDecrementOperator) > 1) + funcs.erase(std::find_if(funcs.begin(), funcs.end(), isDecrementOperator)); + } + for (const auto &func : funcs) { - if (func->isModifiedRemoved() - || func->usesRValueReferences() - || func->name() == QLatin1String("operator[]") - || func->name() == QLatin1String("operator->") - || func->name() == QLatin1String("operator!")) { - continue; - } int args; if (func->isComparisonOperator()) { args = -1; @@ -663,6 +700,7 @@ void CppGenerator::generateClass(TextStream &s, const GeneratorContext &classCon const QList opOverloads = filterGroupedOperatorFunctions( metaClass, OperatorQueryOption::ArithmeticOp + | OperatorQueryOption::IncDecrementOp | OperatorQueryOption::LogicalOp | OperatorQueryOption::BitwiseOp); @@ -3524,9 +3562,10 @@ void CppGenerator::writeMethodCall(TextStream &s, const AbstractMetaFunctionCPtr if (func->isReverseOperator()) std::swap(firstArg, secondArg); + // Emulate operator+=/-= (__iadd__, __isub__) by using ++/-- if (((op == QLatin1String("++")) || (op == QLatin1String("--"))) && !func->isReverseOperator()) { s << "\nfor (int i = 0; i < " << secondArg - << "; ++i, " << firstArg << op << ");\n"; + << "; ++i, " << op << firstArg << ");\n"; mc << firstArg; } else { mc << firstArg << ' ' << op << ' ' << secondArg; @@ -4113,6 +4152,7 @@ bool CppGenerator::supportsMappingProtocol(const AbstractMetaClass *metaClass) bool CppGenerator::supportsNumberProtocol(const AbstractMetaClass *metaClass) const { return metaClass->hasArithmeticOperatorOverload() + || metaClass->hasIncDecrementOperatorOverload() || metaClass->hasLogicalOperatorOverload() || metaClass->hasBitwiseOperatorOverload() || hasBoolCast(metaClass); @@ -4495,6 +4535,7 @@ void CppGenerator::writeTypeAsNumberDefinition(TextStream &s, const AbstractMeta const QList opOverloads = filterGroupedOperatorFunctions(metaClass, OperatorQueryOption::ArithmeticOp + | OperatorQueryOption::IncDecrementOp | OperatorQueryOption::LogicalOp | OperatorQueryOption::BitwiseOp); diff --git a/sources/shiboken6/tests/libsample/CMakeLists.txt b/sources/shiboken6/tests/libsample/CMakeLists.txt index f734ab935..6e436ee1f 100644 --- a/sources/shiboken6/tests/libsample/CMakeLists.txt +++ b/sources/shiboken6/tests/libsample/CMakeLists.txt @@ -16,6 +16,7 @@ exceptiontest.cpp functions.cpp handle.cpp implicitconv.cpp +intwrapper.cpp injectcode.cpp listuser.cpp modifications.cpp diff --git a/sources/shiboken6/tests/libsample/collector.cpp b/sources/shiboken6/tests/libsample/collector.cpp index 398f79918..aca24e355 100644 --- a/sources/shiboken6/tests/libsample/collector.cpp +++ b/sources/shiboken6/tests/libsample/collector.cpp @@ -57,6 +57,6 @@ int Collector::size() Collector &operator<<(Collector &s, const IntWrapper &w) { - s << w.value; + s << w.toInt(); return s; } diff --git a/sources/shiboken6/tests/libsample/collector.h b/sources/shiboken6/tests/libsample/collector.h index 6d51c624c..bc10a7481 100644 --- a/sources/shiboken6/tests/libsample/collector.h +++ b/sources/shiboken6/tests/libsample/collector.h @@ -32,6 +32,7 @@ #include #include "libsamplemacros.h" +#include "intwrapper.h" #include "objecttype.h" class LIBSAMPLE_API Collector @@ -57,14 +58,6 @@ private: }; /* Helper for testing external operators */ -class IntWrapper -{ -public: - IntWrapper(int x=0):value(x){} - - int value; -}; - LIBSAMPLE_API Collector &operator<<(Collector&, const IntWrapper&); #endif // COLLECTOR_H diff --git a/sources/shiboken6/tests/libsample/intwrapper.cpp b/sources/shiboken6/tests/libsample/intwrapper.cpp new file mode 100644 index 000000000..aa1a22874 --- /dev/null +++ b/sources/shiboken6/tests/libsample/intwrapper.cpp @@ -0,0 +1,61 @@ +/**************************************************************************** +** +** Copyright (C) 2021 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$ +** +****************************************************************************/ + + +#include "intwrapper.h" + +int IntWrapper::toInt() const +{ + return m_number; +} + +IntWrapper &IntWrapper::operator ++() +{ + ++m_number; + return *this; +} + +IntWrapper IntWrapper::operator++(int) +{ + IntWrapper result(*this); + ++m_number; + return result; +} + +IntWrapper &IntWrapper::operator--() +{ + --m_number; + return *this; +} + +IntWrapper IntWrapper::operator--(int) +{ + IntWrapper result(*this); + --m_number; + return result; +} diff --git a/sources/shiboken6/tests/libsample/intwrapper.h b/sources/shiboken6/tests/libsample/intwrapper.h new file mode 100644 index 000000000..158cff8e1 --- /dev/null +++ b/sources/shiboken6/tests/libsample/intwrapper.h @@ -0,0 +1,87 @@ +/**************************************************************************** +** +** Copyright (C) 2021 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$ +** +****************************************************************************/ + +#ifndef INTWRAPPER_H +#define INTWRAPPER_H + +#include "libsamplemacros.h" + +// Wrapper around int for testing operators +class LIBSAMPLE_API IntWrapper +{ +public: + constexpr explicit IntWrapper(int i) noexcept : m_number(i) {} + int toInt() const; + + IntWrapper &operator++(); + IntWrapper operator++(int); // Postfix + + IntWrapper &operator--(); + IntWrapper operator--(int); // Postfix + + friend constexpr inline bool operator==(IntWrapper lhs, IntWrapper rhs) noexcept + { return lhs.m_number == rhs.m_number; } + friend constexpr inline bool operator!=(IntWrapper lhs, IntWrapper rhs) noexcept + { return lhs.m_number != rhs.m_number; } + friend constexpr inline bool operator<(IntWrapper lhs, IntWrapper rhs) noexcept + { return lhs.m_number < rhs.m_number; } + friend constexpr inline bool operator>(IntWrapper lhs, IntWrapper rhs) noexcept + { return lhs.m_number > rhs.m_number; } + friend constexpr inline bool operator<=(IntWrapper lhs, IntWrapper rhs) noexcept + { return lhs.m_number <= rhs.m_number; } + friend constexpr inline bool operator>=(IntWrapper lhs, IntWrapper rhs) noexcept + { return lhs.m_number >= rhs.m_number; } + + constexpr inline IntWrapper &operator+=(IntWrapper i); + constexpr inline IntWrapper &operator-=(const IntWrapper i); + + friend constexpr inline IntWrapper operator+(IntWrapper lhs, IntWrapper rhs) noexcept + { return IntWrapper(lhs.m_number + rhs.m_number); } + friend constexpr inline IntWrapper operator-(IntWrapper lhs, IntWrapper rhs) noexcept + { return IntWrapper(lhs.m_number - rhs.m_number); } + + // FIXME: Test spaceship operator with C++ 20: + // auto operator<=>(IntWrapper) const = default; + +private: + int m_number; +}; + +constexpr inline IntWrapper &IntWrapper::operator+=(IntWrapper i) +{ + m_number += i.m_number; + return *this; +} + +constexpr inline IntWrapper &IntWrapper::operator-=(const IntWrapper i) +{ + m_number -= i.m_number; + return *this; +} + +#endif // INTWRAPPER_H diff --git a/sources/shiboken6/tests/samplebinding/intwrapper_test.py b/sources/shiboken6/tests/samplebinding/intwrapper_test.py new file mode 100644 index 000000000..a2fabf87f --- /dev/null +++ b/sources/shiboken6/tests/samplebinding/intwrapper_test.py @@ -0,0 +1,61 @@ +# -*- coding: utf-8 -*- +# +############################################################################# +## +## Copyright (C) 2021 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$ +## +############################################################################# + +import os +import sys +import unittest + +from pathlib import Path +sys.path.append(os.fspath(Path(__file__).resolve().parents[1])) +from shiboken_paths import init_paths +init_paths() + +from sample import IntWrapper + + +class IntWrapperTest(unittest.TestCase): + + def testOperators(self): + ten1 = IntWrapper(10) + ten2 = IntWrapper(10) + twenty = IntWrapper(20) + self.assertTrue(ten1 == ten2) + self.assertTrue(ten1 != twenty) + self.assertTrue(ten1 + ten2 == twenty) + self.assertTrue(ten1 - ten2 == IntWrapper(0)) + i = IntWrapper(ten1.toInt()) + i += ten2 + self.assertTrue(i == twenty) + i -= ten2 + self.assertTrue(i == ten1) + + +if __name__ == '__main__': + unittest.main() -- cgit v1.2.3