diff options
author | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2020-09-21 08:43:01 +0200 |
---|---|---|
committer | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2020-09-21 08:43:01 +0200 |
commit | 98eb59226aca550ae086c00b9c8023f47c44d2b2 (patch) | |
tree | 7e8a136347b5eb52ca0592b33aea09af97bf978a | |
parent | 968e9adeccddfc7e3bc376e7b7606b376d8feecf (diff) | |
parent | 8728594d6b2e0f3df3e3726b67cf23715dfdcbe3 (diff) |
Merge remote-tracking branch 'origin/5.15' into dev
Change-Id: Ia31df23a16575f9ecefe13ec85fb70197d103278
-rw-r--r-- | build_scripts/qp5_tool.py | 4 | ||||
-rw-r--r-- | examples/scriptableapplication/pythonutils.cpp | 2 | ||||
-rw-r--r-- | sources/pyside2/PySide2/Qt3DCore/typesystem_3dcore.xml | 2 | ||||
-rw-r--r-- | sources/pyside2/PySide2/QtUiTools/typesystem_uitools.xml | 4 | ||||
-rw-r--r-- | sources/pyside2/libpyside/pysidesignal.cpp | 103 | ||||
-rw-r--r-- | sources/pyside2/libpyside/pysidesignal.h | 26 | ||||
-rw-r--r-- | sources/pyside2/libpyside/pysidesignal_p.h | 6 | ||||
-rw-r--r-- | sources/pyside2/tests/QtUiTools/uiloader_test.py | 38 | ||||
-rw-r--r-- | sources/shiboken2/ApiExtractor/typesystem.h | 4 | ||||
-rw-r--r-- | sources/shiboken2/ApiExtractor/typesystemparser.cpp | 14 | ||||
-rw-r--r-- | sources/shiboken2/doc/typesystem_specifying_types.rst | 8 | ||||
-rw-r--r-- | sources/shiboken2/generator/shiboken2/cppgenerator.cpp | 5 |
12 files changed, 115 insertions, 101 deletions
diff --git a/build_scripts/qp5_tool.py b/build_scripts/qp5_tool.py index 6fa5e1c66..1358b21c2 100644 --- a/build_scripts/qp5_tool.py +++ b/build_scripts/qp5_tool.py @@ -271,7 +271,9 @@ def read_config_python_binary(): binary = read_config(PYTHON_KEY) if binary: return binary - return 'python3' if which('python3') else 'python' + # Use 'python3' unless virtualenv is set + use_py3 = (not os.environ.get('VIRTUAL_ENV') and which('python3')) + return 'python3' if use_py3 else 'python' def get_config_file(base_name): diff --git a/examples/scriptableapplication/pythonutils.cpp b/examples/scriptableapplication/pythonutils.cpp index d8c38026f..c5e18f256 100644 --- a/examples/scriptableapplication/pythonutils.cpp +++ b/examples/scriptableapplication/pythonutils.cpp @@ -100,6 +100,8 @@ static void initVirtualEnvironment() if (QOperatingSystemVersion::currentType() == QOperatingSystemVersion::Windows && (PY_MAJOR_VERSION > 3 || (PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 8))) { qputenv("PYTHONPATH", virtualEnvPath + "\\Lib\\site-packages"); + } else { + qputenv("PYTHONHOME", virtualEnvPath); } } diff --git a/sources/pyside2/PySide2/Qt3DCore/typesystem_3dcore.xml b/sources/pyside2/PySide2/Qt3DCore/typesystem_3dcore.xml index 30c190b66..61b128f73 100644 --- a/sources/pyside2/PySide2/Qt3DCore/typesystem_3dcore.xml +++ b/sources/pyside2/PySide2/Qt3DCore/typesystem_3dcore.xml @@ -42,7 +42,7 @@ <typesystem package="PySide2.Qt3DCore"> <load-typesystem name="QtGui/typesystem_gui.xml" generate="no"/> - <namespace-type name="Qt3DCore"> + <namespace-type name="Qt3DCore" generate-using="no"> <enum-type name="ChangeFlag" flags="ChangeFlags"/> <object-type name="QAbstractAspect"/> <object-type name="QAbstractFrontEndNodeManager" since="6.0"> diff --git a/sources/pyside2/PySide2/QtUiTools/typesystem_uitools.xml b/sources/pyside2/PySide2/QtUiTools/typesystem_uitools.xml index 85092a5c2..31f0b8343 100644 --- a/sources/pyside2/PySide2/QtUiTools/typesystem_uitools.xml +++ b/sources/pyside2/PySide2/QtUiTools/typesystem_uitools.xml @@ -90,6 +90,7 @@ <modify-function signature="createAction(QObject*,const QString&)"> <modify-argument index="return"> <parent index="1" action="add"/> + <define-ownership class="native" owner="c++"/> <define-ownership class="target" owner="default"/> </modify-argument> </modify-function> @@ -97,6 +98,7 @@ <modify-function signature="createActionGroup(QObject*,const QString&)"> <modify-argument index="return"> <parent index="1" action="add"/> + <define-ownership class="native" owner="c++"/> <define-ownership class="target" owner="default"/> </modify-argument> </modify-function> @@ -104,6 +106,7 @@ <modify-function signature="createLayout(const QString&,QObject*,const QString&)"> <modify-argument index="return"> <parent index="2" action="add"/> + <define-ownership class="native" owner="c++"/> <define-ownership class="target" owner="default"/> </modify-argument> </modify-function> @@ -111,6 +114,7 @@ <modify-function signature="createWidget(const QString&,QWidget*,const QString&)"> <modify-argument index="return"> <parent index="2" action="add"/> + <define-ownership class="native" owner="c++"/> <define-ownership class="target" owner="default"/> </modify-argument> </modify-function> diff --git a/sources/pyside2/libpyside/pysidesignal.cpp b/sources/pyside2/libpyside/pysidesignal.cpp index 195bedaa4..a834c841e 100644 --- a/sources/pyside2/libpyside/pysidesignal.cpp +++ b/sources/pyside2/libpyside/pysidesignal.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2020 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of Qt for Python. @@ -107,10 +107,10 @@ static PyMethodDef MetaSignal_methods[] = { }; static PyType_Slot PySideMetaSignalType_slots[] = { - {Py_tp_methods, (void *)MetaSignal_methods}, - {Py_tp_base, (void *)&PyType_Type}, - {Py_tp_free, (void *)PyObject_GC_Del}, - {Py_tp_dealloc, (void *)Sbk_object_dealloc}, + {Py_tp_methods, reinterpret_cast<void *>(MetaSignal_methods)}, + {Py_tp_base, reinterpret_cast<void *>(&PyType_Type)}, + {Py_tp_free, reinterpret_cast<void *>(PyObject_GC_Del)}, + {Py_tp_dealloc, reinterpret_cast<void *>(Sbk_object_dealloc)}, {0, 0} }; static PyType_Spec PySideMetaSignalType_spec = { @@ -124,7 +124,7 @@ static PyType_Spec PySideMetaSignalType_spec = { }; -PyTypeObject *PySideMetaSignalTypeF(void) +static PyTypeObject *PySideMetaSignalTypeF(void) { static PyTypeObject *type = nullptr; if (!type) { @@ -136,13 +136,13 @@ PyTypeObject *PySideMetaSignalTypeF(void) } static PyType_Slot PySideSignalType_slots[] = { - {Py_mp_subscript, (void *)signalGetItem}, - {Py_tp_call, (void *)signalCall}, - {Py_tp_str, (void *)signalToString}, - {Py_tp_init, (void *)signalTpInit}, - {Py_tp_new, (void *)PyType_GenericNew}, - {Py_tp_free, (void *)signalFree}, - {Py_tp_dealloc, (void *)Sbk_object_dealloc}, + {Py_mp_subscript, reinterpret_cast<void *>(signalGetItem)}, + {Py_tp_call, reinterpret_cast<void *>(signalCall)}, + {Py_tp_str, reinterpret_cast<void *>(signalToString)}, + {Py_tp_init, reinterpret_cast<void *>(signalTpInit)}, + {Py_tp_new, reinterpret_cast<void *>(PyType_GenericNew)}, + {Py_tp_free, reinterpret_cast<void *>(signalFree)}, + {Py_tp_dealloc, reinterpret_cast<void *>(Sbk_object_dealloc)}, {0, 0} }; static PyType_Spec PySideSignalType_spec = { @@ -175,13 +175,12 @@ static PyMethodDef SignalInstance_methods[] = { }; static PyType_Slot PySideSignalInstanceType_slots[] = { - //{Py_tp_as_mapping, (void *)&SignalInstance_as_mapping}, - {Py_mp_subscript, (void *)signalInstanceGetItem}, - {Py_tp_call, (void *)signalInstanceCall}, - {Py_tp_methods, (void *)SignalInstance_methods}, - {Py_tp_new, (void *)PyType_GenericNew}, - {Py_tp_free, (void *)signalInstanceFree}, - {Py_tp_dealloc, (void *)Sbk_object_dealloc}, + {Py_mp_subscript, reinterpret_cast<void *>(signalInstanceGetItem)}, + {Py_tp_call, reinterpret_cast<void *>(signalInstanceCall)}, + {Py_tp_methods, reinterpret_cast<void *>(SignalInstance_methods)}, + {Py_tp_new, reinterpret_cast<void *>(PyType_GenericNew)}, + {Py_tp_free, reinterpret_cast<void *>(signalInstanceFree)}, + {Py_tp_dealloc, reinterpret_cast<void *>(Sbk_object_dealloc)}, {0, 0} }; static PyType_Spec PySideSignalInstanceType_spec = { @@ -200,7 +199,7 @@ PyTypeObject *PySideSignalInstanceTypeF(void) return type; } -int signalTpInit(PyObject *self, PyObject *args, PyObject *kwds) +static int signalTpInit(PyObject *self, PyObject *args, PyObject *kwds) { static PyObject *emptyTuple = nullptr; static const char *kwlist[] = {"name", "arguments", nullptr}; @@ -256,7 +255,7 @@ int signalTpInit(PyObject *self, PyObject *args, PyObject *kwds) return 0; } -void signalFree(void *self) +static void signalFree(void *self) { auto pySelf = reinterpret_cast<PyObject *>(self); auto data = reinterpret_cast<PySideSignal *>(self); @@ -268,7 +267,7 @@ void signalFree(void *self) Py_TYPE(pySelf)->tp_base->tp_free(self); } -PyObject *signalGetItem(PyObject *self, PyObject *key) +static PyObject *signalGetItem(PyObject *self, PyObject *key) { auto data = reinterpret_cast<PySideSignal *>(self); QByteArray sigKey; @@ -283,12 +282,12 @@ PyObject *signalGetItem(PyObject *self, PyObject *key) } -PyObject *signalToString(PyObject *self) +static PyObject *signalToString(PyObject *self) { return signalGetItem(self, 0); } -void signalInstanceFree(void *self) +static void signalInstanceFree(void *self) { auto pySelf = reinterpret_cast<PyObject *>(self); auto data = reinterpret_cast<PySideSignalInstance *>(self); @@ -306,7 +305,7 @@ void signalInstanceFree(void *self) Py_TYPE(pySelf)->tp_base->tp_free(self); } -PyObject *signalInstanceConnect(PyObject *self, PyObject *args, PyObject *kwds) +static PyObject *signalInstanceConnect(PyObject *self, PyObject *args, PyObject *kwds) { PyObject *slot = nullptr; PyObject *type = nullptr; @@ -426,12 +425,12 @@ PyObject *signalInstanceConnect(PyObject *self, PyObject *args, PyObject *kwds) return 0; } -int argCountInSignature(const char *signature) +static int argCountInSignature(const char *signature) { return QByteArray(signature).count(",") + 1; } -PyObject *signalInstanceEmit(PyObject *self, PyObject *args) +static PyObject *signalInstanceEmit(PyObject *self, PyObject *args) { PySideSignalInstance *source = reinterpret_cast<PySideSignalInstance *>(self); @@ -470,7 +469,7 @@ PyObject *signalInstanceEmit(PyObject *self, PyObject *args) return PyObject_CallObject(pyMethod, tupleArgs); } -PyObject *signalInstanceGetItem(PyObject *self, PyObject *key) +static PyObject *signalInstanceGetItem(PyObject *self, PyObject *key) { auto data = reinterpret_cast<PySideSignalInstance *>(self); const auto sigName = data->d->signalName; @@ -490,7 +489,7 @@ PyObject *signalInstanceGetItem(PyObject *self, PyObject *key) return 0; } -PyObject *signalInstanceDisconnect(PyObject *self, PyObject *args) +static PyObject *signalInstanceDisconnect(PyObject *self, PyObject *args) { auto source = reinterpret_cast<PySideSignalInstance *>(self); Shiboken::AutoDecRef pyArgs(PyList_New(0)); @@ -543,7 +542,7 @@ PyObject *signalInstanceDisconnect(PyObject *self, PyObject *args) return 0; } -PyObject *signalCall(PyObject *self, PyObject *args, PyObject *kw) +static PyObject *signalCall(PyObject *self, PyObject *args, PyObject *kw) { auto signal = reinterpret_cast<PySideSignal *>(self); @@ -575,7 +574,7 @@ PyObject *signalCall(PyObject *self, PyObject *args, PyObject *kw) return callFunc(homonymousMethod, args, kw); } -PyObject *signalInstanceCall(PyObject *self, PyObject *args, PyObject *kw) +static PyObject *signalInstanceCall(PyObject *self, PyObject *args, PyObject *kw) { auto PySideSignal = reinterpret_cast<PySideSignalInstance *>(self); if (!PySideSignal->d->homonymousMethod) { @@ -700,12 +699,12 @@ QByteArray getTypeName(PyObject *type) return QByteArray(); } -QByteArray buildSignature(const QByteArray &name, const QByteArray &signature) +static QByteArray buildSignature(const QByteArray &name, const QByteArray &signature) { return QMetaObject::normalizedSignature(name + '(' + signature + ')'); } -QByteArray parseSignature(PyObject *args) +static QByteArray parseSignature(PyObject *args) { if (args && (Shiboken::String::check(args) || !PySequence_Check(args))) return getTypeName(args); @@ -723,22 +722,12 @@ QByteArray parseSignature(PyObject *args) return signature; } -void appendSignature(PySideSignal *self, const SignalSignature &signature) +static void appendSignature(PySideSignal *self, const SignalSignature &signature) { self->data->signatures.append({signature.m_parameterTypes, signature.m_attributes}); } -PySideSignalInstance *initialize(PySideSignal *self, PyObject *name, PyObject *object) -{ - PySideSignalInstance *instance = PyObject_New(PySideSignalInstance, PySideSignalInstanceTypeF()); - auto sbkObj = reinterpret_cast<SbkObject *>(object); - if (!Shiboken::Object::wasCreatedByPython(sbkObj)) - Py_INCREF(object); // PYSIDE-79: this flag was crucial for a wrapper call. - instanceInitialize(instance, name, self, object, 0); - return instance; -} - -void instanceInitialize(PySideSignalInstance *self, PyObject *name, PySideSignal *data, PyObject *source, int index) +static void instanceInitialize(PySideSignalInstance *self, PyObject *name, PySideSignal *data, PyObject *source, int index) { self->d = new PySideSignalInstancePrivate; PySideSignalInstancePrivate *selfPvt = self->d; @@ -764,6 +753,16 @@ void instanceInitialize(PySideSignalInstance *self, PyObject *name, PySideSignal } } +PySideSignalInstance *initialize(PySideSignal *self, PyObject *name, PyObject *object) +{ + PySideSignalInstance *instance = PyObject_New(PySideSignalInstance, PySideSignalInstanceTypeF()); + auto sbkObj = reinterpret_cast<SbkObject *>(object); + if (!Shiboken::Object::wasCreatedByPython(sbkObj)) + Py_INCREF(object); // PYSIDE-79: this flag was crucial for a wrapper call. + instanceInitialize(instance, name, self, object, 0); + return instance; +} + bool connect(PyObject *source, const char *signal, PyObject *callback) { Shiboken::AutoDecRef pyMethod(PyObject_GetAttr(source, @@ -847,6 +846,12 @@ static bool compareSignals(const SignalSignature &sig1, const SignalSignature &) return sig1.m_parameterTypes.isEmpty(); } +static PyObject *buildQtCompatible(const QByteArray &signature) +{ + const auto ba = QT_SIGNAL_SENTINEL + signature; + return Shiboken::String::fromStringAndSize(ba, ba.size()); +} + void registerSignals(SbkObjectType *pyObj, const QMetaObject *metaObject) { typedef QHash<QByteArray, QList<SignalSignature> > SignalSigMap; @@ -887,12 +892,6 @@ void registerSignals(SbkObjectType *pyObj, const QMetaObject *metaObject) } } -PyObject *buildQtCompatible(const QByteArray &signature) -{ - const auto ba = QT_SIGNAL_SENTINEL + signature; - return Shiboken::String::fromStringAndSize(ba, ba.size()); -} - PyObject *getObject(PySideSignalInstance *signal) { return signal->d->source; diff --git a/sources/pyside2/libpyside/pysidesignal.h b/sources/pyside2/libpyside/pysidesignal.h index a6742227f..973644b0a 100644 --- a/sources/pyside2/libpyside/pysidesignal.h +++ b/sources/pyside2/libpyside/pysidesignal.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2020 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of Qt for Python. @@ -65,19 +65,19 @@ extern "C" struct PYSIDE_API PySideSignalInstance { PyObject_HEAD - PySideSignalInstancePrivate* d; + PySideSignalInstancePrivate *d; }; }; // extern "C" namespace PySide { namespace Signal { -PYSIDE_API bool checkType(PyObject* type); +PYSIDE_API bool checkType(PyObject *type); /** * Register all C++ signals of a QObject on Python type. */ -PYSIDE_API void registerSignals(SbkObjectType* pyObj, const QMetaObject* metaObject); +PYSIDE_API void registerSignals(SbkObjectType *pyObj, const QMetaObject *metaObject); /** * This function creates a Signal object which stays attached to QObject class based on a list of QMetaMethods @@ -86,7 +86,7 @@ PYSIDE_API void registerSignals(SbkObjectType* pyObj, const QMetaObject* metaObj * @param methods a list of QMetaMethod wich contains the supported signature * @return Return a new reference to PyObject* of type PySideSignal **/ -PYSIDE_API PySideSignalInstance* newObjectFromMethod(PyObject* source, const QList<QMetaMethod>& methods); +PYSIDE_API PySideSignalInstance *newObjectFromMethod(PyObject *source, const QList<QMetaMethod> &methods); /** * This function initializes the Signal object by creating a PySideSignalInstance @@ -96,7 +96,7 @@ PYSIDE_API PySideSignalInstance* newObjectFromMethod(PyObject* source, const QLi * @param object the PyObject where the signal will be attached * @return Return a new reference to PySideSignalInstance **/ -PYSIDE_API PySideSignalInstance* initialize(PySideSignal* signal, PyObject* name, PyObject* object); +PYSIDE_API PySideSignalInstance *initialize(PySideSignal *signal, PyObject *name, PyObject *object); /** * This function is used to retrieve the object in which the signal is attached @@ -104,7 +104,7 @@ PYSIDE_API PySideSignalInstance* initialize(PySideSignal* signal, PyObject* name * @param self The Signal object * @return Return the internal reference to the parent object of the signal **/ -PYSIDE_API PyObject* getObject(PySideSignalInstance* signal); +PYSIDE_API PyObject *getObject(PySideSignalInstance *signal); /** * This function is used to retrieve the signal signature @@ -112,7 +112,7 @@ PYSIDE_API PyObject* getObject(PySideSignalInstance* signal); * @param self The Signal object * @return Return the signal signature **/ -PYSIDE_API const char* getSignature(PySideSignalInstance* signal); +PYSIDE_API const char *getSignature(PySideSignalInstance *signal); /** * This function is used to retrieve the signal signature @@ -120,14 +120,14 @@ PYSIDE_API const char* getSignature(PySideSignalInstance* signal); * @param self The Signal object * @return Return the signal signature **/ -PYSIDE_API void updateSourceObject(PyObject* source); +PYSIDE_API void updateSourceObject(PyObject *source); /** * This function verifies if the signature is a QtSignal base on SIGNAL flag * @param signature The signal signature * @return Return true if this is a Qt Signal, otherwise return false **/ -PYSIDE_API bool isQtSignal(const char* signature); +PYSIDE_API bool isQtSignal(const char *signature); /** * This function is similar to isQtSignal, however if it fails, it'll raise a Python error instead. @@ -135,7 +135,7 @@ PYSIDE_API bool isQtSignal(const char* signature); * @param signature The signal signature * @return Return true if this is a Qt Signal, otherwise return false **/ -PYSIDE_API bool checkQtSignal(const char* signature); +PYSIDE_API bool checkQtSignal(const char *signature); /** * This function is used to retrieve the signature base on Signal and receiver callback @@ -145,7 +145,7 @@ PYSIDE_API bool checkQtSignal(const char* signature); * @param encodeName Used to specify if the returned signature will be encoded with Qt signal/slot style * @return Return the callback signature **/ -PYSIDE_API QString getCallbackSignature(const char* signal, QObject* receiver, PyObject* callback, bool encodeName); +PYSIDE_API QString getCallbackSignature(const char *signal, QObject *receiver, PyObject *callback, bool encodeName); /** * This function parses the signature and then returns a list of argument types. @@ -155,7 +155,7 @@ PYSIDE_API QString getCallbackSignature(const char* signal, QObject* receiver, P * @return Return true if this is a Qt Signal, otherwise return false * @todo replace return type by QList<QByteArray> **/ -QStringList getArgsFromSignature(const char* signature, bool* isShortCircuit = 0); +QStringList getArgsFromSignature(const char *signature, bool *isShortCircuit = 0); } // namespace Signal } // namespace PySide diff --git a/sources/pyside2/libpyside/pysidesignal_p.h b/sources/pyside2/libpyside/pysidesignal_p.h index 8027f4459..337feaa8a 100644 --- a/sources/pyside2/libpyside/pysidesignal_p.h +++ b/sources/pyside2/libpyside/pysidesignal_p.h @@ -83,10 +83,10 @@ struct PySideSignalInstancePrivate namespace PySide { namespace Signal { - void init(PyObject* module); - bool connect(PyObject* source, const char* signal, PyObject* callback); + void init(PyObject *module); + bool connect(PyObject *source, const char *signal, PyObject *callback); QByteArray getTypeName(PyObject *); - QString codeCallbackName(PyObject* callback, const QString& funcName); + QString codeCallbackName(PyObject *callback, const QString &funcName); QByteArray voidType(); }} //namespace PySide diff --git a/sources/pyside2/tests/QtUiTools/uiloader_test.py b/sources/pyside2/tests/QtUiTools/uiloader_test.py index 48b401426..2fceb45c1 100644 --- a/sources/pyside2/tests/QtUiTools/uiloader_test.py +++ b/sources/pyside2/tests/QtUiTools/uiloader_test.py @@ -39,18 +39,25 @@ from helper.usesqapplication import UsesQApplication from PySide2.QtWidgets import QWidget from PySide2.QtUiTools import QUiLoader -def get_file_path(): - for path in file_path: - if os.path.exists(path): - return path - return "" -class QUioaderTeste(UsesQApplication): +class OverridingLoader(QUiLoader): + def createWidget(self, class_name, parent=None, name=''): + if class_name == 'QWidget': + w = QWidget(parent) + w.setObjectName(name) + return w + return QUiLoader.createWidget(self, class_name, parent, name) + + +class QUiLoaderTester(UsesQApplication): + def setUp(self): + UsesQApplication.setUp(self) + self._filePath = os.path.join(os.path.dirname(__file__), 'test.ui') + def testLoadFile(self): - filePath = os.path.join(os.path.dirname(__file__), 'test.ui') loader = QUiLoader() parent = QWidget() - w = loader.load(filePath, parent) + w = loader.load(self._filePath, parent) self.assertNotEqual(w, None) self.assertEqual(len(parent.children()), 1) @@ -59,18 +66,13 @@ class QUioaderTeste(UsesQApplication): self.assertNotEqual(child, None) self.assertEqual(w.findChild(QWidget, "grandson_object"), child.findChild(QWidget, "grandson_object")) - def testLoadFileUnicodeFilePath(self): - filePath = str(os.path.join(os.path.dirname(__file__), 'test.ui')) - loader = QUiLoader() - parent = QWidget() - w = loader.load(filePath, parent) - self.assertNotEqual(w, None) - self.assertEqual(len(parent.children()), 1) + def testLoadFileOverride(self): + # PYSIDE-1070, override QUiLoader::createWidget() with parent=None crashes + loader = OverridingLoader() + w = loader.load(self._filePath) + self.assertNotEqual(w, None) - child = w.findChild(QWidget, "child_object") - self.assertNotEqual(child, None) - self.assertEqual(w.findChild(QWidget, "grandson_object"), child.findChild(QWidget, "grandson_object")) if __name__ == '__main__': unittest.main() diff --git a/sources/shiboken2/ApiExtractor/typesystem.h b/sources/shiboken2/ApiExtractor/typesystem.h index 3fb326b76..f82b0a2ba 100644 --- a/sources/shiboken2/ApiExtractor/typesystem.h +++ b/sources/shiboken2/ApiExtractor/typesystem.h @@ -1527,6 +1527,9 @@ public: void formatDebug(QDebug &d) const override; #endif + bool generateUsing() const { return m_generateUsing; } + void setGenerateUsing(bool generateUsing) { m_generateUsing = generateUsing; } + protected: NamespaceTypeEntry(const NamespaceTypeEntry &); @@ -1536,6 +1539,7 @@ private: TypeSystem::Visibility m_visibility = TypeSystem::Visibility::Auto; bool m_hasPattern = false; bool m_inlineNamespace = false; + bool m_generateUsing = true; // Whether to generate "using namespace" into wrapper }; class ValueTypeEntry : public ComplexTypeEntry diff --git a/sources/shiboken2/ApiExtractor/typesystemparser.cpp b/sources/shiboken2/ApiExtractor/typesystemparser.cpp index d23e96c77..948a28796 100644 --- a/sources/shiboken2/ApiExtractor/typesystemparser.cpp +++ b/sources/shiboken2/ApiExtractor/typesystemparser.cpp @@ -67,6 +67,7 @@ static inline QString flagsAttribute() { return QStringLiteral("flags"); } static inline QString forceAbstractAttribute() { return QStringLiteral("force-abstract"); } static inline QString forceIntegerAttribute() { return QStringLiteral("force-integer"); } static inline QString formatAttribute() { return QStringLiteral("format"); } +static inline QString generateUsingAttribute() { return QStringLiteral("generate-using"); } static inline QString classAttribute() { return QStringLiteral("class"); } static inline QString generateAttribute() { return QStringLiteral("generate"); } static inline QString genericClassAttribute() { return QStringLiteral("generic-class"); } @@ -1020,7 +1021,6 @@ bool TypeSystemParser::importFileElement(const QXmlStreamAttributes &atts) static bool convertBoolean(QStringView value, const QString &attributeName, bool defaultValue) { -#ifdef QTBUG_69389_FIXED if (value.compare(trueAttributeValue(), Qt::CaseInsensitive) == 0 || value.compare(yesAttributeValue(), Qt::CaseInsensitive) == 0) { return true; @@ -1029,16 +1029,6 @@ static bool convertBoolean(QStringView value, const QString &attributeName, bool || value.compare(noAttributeValue(), Qt::CaseInsensitive) == 0) { return false; } -#else - if (QtPrivate::compareStrings(value, trueAttributeValue(), Qt::CaseInsensitive) == 0 - || QtPrivate::compareStrings(value, yesAttributeValue(), Qt::CaseInsensitive) == 0) { - return true; - } - if (QtPrivate::compareStrings(value, falseAttributeValue(), Qt::CaseInsensitive) == 0 - || QtPrivate::compareStrings(value, noAttributeValue(), Qt::CaseInsensitive) == 0) { - return false; - } -#endif const QString warn = QStringLiteral("Boolean value '%1' not supported in attribute '%2'. Use 'yes' or 'no'. Defaulting to '%3'.") .arg(value) .arg(attributeName, @@ -1376,6 +1366,8 @@ NamespaceTypeEntry * } else if (attributeName == generateAttribute()) { if (!convertBoolean(attributes->takeAt(i).value(), generateAttribute(), true)) visibility = TypeSystem::Visibility::Invisible; + } else if (attributeName == generateUsingAttribute()) { + result->setGenerateUsing(convertBoolean(attributes->takeAt(i).value(), generateUsingAttribute(), true)); } } diff --git a/sources/shiboken2/doc/typesystem_specifying_types.rst b/sources/shiboken2/doc/typesystem_specifying_types.rst index 27267faab..221519541 100644 --- a/sources/shiboken2/doc/typesystem_specifying_types.rst +++ b/sources/shiboken2/doc/typesystem_specifying_types.rst @@ -155,6 +155,7 @@ namespace-type <namespace-type name="..." visible="true | auto | false" generate="yes | no" + generate-using="yes | no" package="..." since="..." revision="..." /> @@ -173,6 +174,13 @@ namespace-type The *optional* **generate** is a legacy attribute. Specifying **no** is equivalent to **visible="false"**. + The *optional* **generate-using** attribute specifies whether + ``using namespace`` is generated into the wrapper code for classes within + the namespace (default: **yes**). This ensures for example that not fully + qualified enumeration values of default argument values compile. + However, in rare cases, it might cause ambiguities and can then be turned + off. + The **package** attribute can be used to override the package of the type system. The *optional* **since** value is used to specify the API version of this type. diff --git a/sources/shiboken2/generator/shiboken2/cppgenerator.cpp b/sources/shiboken2/generator/shiboken2/cppgenerator.cpp index 7217595ee..831d05d6a 100644 --- a/sources/shiboken2/generator/shiboken2/cppgenerator.cpp +++ b/sources/shiboken2/generator/shiboken2/cppgenerator.cpp @@ -404,8 +404,9 @@ void CppGenerator::generateClass(QTextStream &s, const GeneratorContext &classCo { const AbstractMetaClass *context = metaClass->enclosingClass(); while (context) { - if (context->isNamespace() && !context->enclosingClass()) { - s << "using namespace " << context->qualifiedCppName() << ";\n"; + if (context->isNamespace() && !context->enclosingClass() + && static_cast<const NamespaceTypeEntry *>(context->typeEntry())->generateUsing()) { + s << "\nusing namespace " << context->qualifiedCppName() << ";\n"; break; } context = context->enclosingClass(); |