aboutsummaryrefslogtreecommitdiffstats
path: root/sources/pyside6/libpysideqml/pysideqmluncreatable.cpp
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@qt.io>2022-01-27 14:38:43 +0100
committerFriedemann Kleint <Friedemann.Kleint@qt.io>2022-02-09 07:34:13 +0100
commit383e0bfc56e39d5f097e7957f986eb60e8052831 (patch)
treeb4ebc641285fce121ec471ba5fa4dd6783f701bd /sources/pyside6/libpysideqml/pysideqmluncreatable.cpp
parentc69b51fc296e484c30582d5d2fdaf40619cc43fe (diff)
libpyside: Factor out helpers for class decorators with parameters
Class decorators with parameters (as opposed to parameterless decorators which are simple functions) requires Python types with call operators to be registered. Add Decorator C struct with a pointer to a class derived from DecoratorPrivate that has virtual functions for the tp_init()/tp_call() functions. Provide templates that help to create the slot arrays for the type registration. Provide predefined types for decorators with string/type parameters. Task-number: PYSIDE-1709 Change-Id: I2946b4505c01b49532af534adcedff7a51634929 Reviewed-by: Christian Tismer <tismer@stackless.com> Reviewed-by: Shyamnath Premnadh <Shyamnath.Premnadh@qt.io>
Diffstat (limited to 'sources/pyside6/libpysideqml/pysideqmluncreatable.cpp')
-rw-r--r--sources/pyside6/libpysideqml/pysideqmluncreatable.cpp109
1 files changed, 37 insertions, 72 deletions
diff --git a/sources/pyside6/libpysideqml/pysideqmluncreatable.cpp b/sources/pyside6/libpysideqml/pysideqmluncreatable.cpp
index 11edb931c..1d482d891 100644
--- a/sources/pyside6/libpysideqml/pysideqmluncreatable.cpp
+++ b/sources/pyside6/libpysideqml/pysideqmluncreatable.cpp
@@ -39,6 +39,7 @@
#include "pysideqmluncreatable.h"
#include "pysideqmltypeinfo_p.h"
+#include <pysideclassdecorator_p.h>
#include <shiboken.h>
#include <signature.h>
@@ -49,114 +50,78 @@
#include <QtCore/QtGlobal>
-struct PySideQmlUncreatablePrivate
+class PySideQmlUncreatablePrivate : public PySide::ClassDecorator::StringDecoratorPrivate
{
- std::string reason;
+public:
+ PyObject *tp_call(PyObject *self, PyObject *args, PyObject * /* kw */) override;
+ int tp_init(PyObject *self, PyObject *args, PyObject *kwds) override;
+ const char *name() const override;
};
-extern "C"
+const char *PySideQmlUncreatablePrivate::name() const
{
+ return "QmlUncreatable";
+}
// The call operator is passed the class type and registers the reason
// in the uncreatableReasonMap()
-static PyObject *classInfo_tp_call(PyObject *self, PyObject *args, PyObject * /* kw */)
+PyObject *PySideQmlUncreatablePrivate::tp_call(PyObject *self, PyObject *args, PyObject * /* kw */)
{
- if (!PyTuple_Check(args) || PyTuple_Size(args) != 1) {
- PyErr_Format(PyExc_TypeError,
- "The QmlUncreatable decorator takes exactly 1 positional argument (%zd given)",
- PyTuple_Size(args));
+ PyObject *klass = tp_call_check(args, CheckMode::WrappedType);
+ if (klass== nullptr)
return nullptr;
- }
- PyObject *klass = PyTuple_GetItem(args, 0);
- // This will sometimes segfault if you mistakenly use it on a function declaration
- if (!PyType_Check(klass)) {
- PyErr_SetString(PyExc_TypeError,
- "This decorator can only be used on class declarations");
- return nullptr;
- }
+ auto *data = DecoratorPrivate::get<PySideQmlUncreatablePrivate>(self);
- PyTypeObject *klassType = reinterpret_cast<PyTypeObject *>(klass);
- if (!Shiboken::ObjectType::checkType(klassType)) {
- PyErr_SetString(PyExc_TypeError,
- "This decorator can only be used on classes that are subclasses of QObject");
- return nullptr;
- }
-
- auto data = reinterpret_cast<PySideQmlUncreatable *>(self);
auto &info = PySide::Qml::ensureQmlTypeInfo(klass);
info.flags.setFlag(PySide::Qml::QmlTypeFlag::Uncreatable);
- info.noCreationReason = data->d->reason;
+ info.noCreationReason = data->string();
Py_INCREF(klass);
return klass;
}
-static PyObject *qmlUncreatableTpNew(PyTypeObject *subtype, PyObject * /* args */,
- PyObject * /* kwds */)
-{
- auto *me = reinterpret_cast<PySideQmlUncreatable *>(subtype->tp_alloc(subtype, 0));
- me->d = new PySideQmlUncreatablePrivate;
- return reinterpret_cast<PyObject *>(me);
-}
-
-static int qmlUncreatableTpInit(PyObject *self, PyObject *args, PyObject * /* kwds */)
+int PySideQmlUncreatablePrivate::tp_init(PyObject *self, PyObject *args, PyObject * /* kwds */)
{
- PySideQmlUncreatable *data = reinterpret_cast<PySideQmlUncreatable *>(self);
- PySideQmlUncreatablePrivate *pData = data->d;
-
- bool ok = false;
+ int result = -1;
const auto argsCount = PyTuple_Size(args);
if (argsCount == 0) {
- ok = true; // QML-generated reason
+ result = 0; // QML-generated reason
} else if (argsCount == 1) {
PyObject *arg = PyTuple_GET_ITEM(args, 0);
- if (arg == Py_None) {
- ok = true; // QML-generated reason
- } else if (PyUnicode_Check(arg)) {
- ok = true;
- Shiboken::String::toCppString(arg, &(pData->reason));
- }
+ result = arg == Py_None
+ ? 0 // QML-generated reason
+ : convertToString(self, args);
}
- if (!ok) {
+ if (result != 0) {
PyErr_Format(PyExc_TypeError,
"QmlUncreatable() takes a single string argument or no argument");
- return -1;
}
- return 0;
+ return result;
}
-static void qmlUncreatableFree(void *self)
-{
- auto pySelf = reinterpret_cast<PyObject *>(self);
- auto data = reinterpret_cast<PySideQmlUncreatable *>(self);
+extern "C" {
- delete data->d;
- Py_TYPE(pySelf)->tp_base->tp_free(self);
+PyTypeObject *createPySideQmlUncreatableType(void)
+{
+ auto typeSlots =
+ PySide::ClassDecorator::Methods<PySideQmlUncreatablePrivate>::typeSlots();
+
+ PyType_Spec PySideQmlUncreatableType_spec = {
+ "2:PySide6.QtCore.qmlUncreatable",
+ sizeof(PySideClassDecorator),
+ 0,
+ Py_TPFLAGS_DEFAULT,
+ typeSlots.data()
+ };
+ return SbkType_FromSpec(&PySideQmlUncreatableType_spec);
}
-static PyType_Slot PySideQmlUncreatableType_slots[] = {
- {Py_tp_call, reinterpret_cast<void *>(classInfo_tp_call)},
- {Py_tp_init, reinterpret_cast<void *>(qmlUncreatableTpInit)},
- {Py_tp_new, reinterpret_cast<void *>(qmlUncreatableTpNew)},
- {Py_tp_free, reinterpret_cast<void *>(qmlUncreatableFree)},
- {Py_tp_dealloc, reinterpret_cast<void *>(Sbk_object_dealloc)},
- {0, nullptr}
-};
-
-static PyType_Spec PySideQmlUncreatableType_spec = {
- "2:PySide6.QtCore.qmlUncreatable",
- sizeof(PySideQmlUncreatable),
- 0,
- Py_TPFLAGS_DEFAULT,
- PySideQmlUncreatableType_slots,
-};
-
PyTypeObject *PySideQmlUncreatable_TypeF(void)
{
- static auto *type = SbkType_FromSpec(&PySideQmlUncreatableType_spec);
+ static auto *type = createPySideQmlUncreatableType();
return type;
}