aboutsummaryrefslogtreecommitdiffstats
path: root/sources/pyside6/libpyside/pysideclassdecorator.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'sources/pyside6/libpyside/pysideclassdecorator.cpp')
-rw-r--r--sources/pyside6/libpyside/pysideclassdecorator.cpp103
1 files changed, 103 insertions, 0 deletions
diff --git a/sources/pyside6/libpyside/pysideclassdecorator.cpp b/sources/pyside6/libpyside/pysideclassdecorator.cpp
new file mode 100644
index 000000000..ec69c5fe7
--- /dev/null
+++ b/sources/pyside6/libpyside/pysideclassdecorator.cpp
@@ -0,0 +1,103 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include <sbkpython.h>
+
+#include "pysideclassdecorator_p.h"
+#include "pysideqobject.h"
+
+#include <basewrapper.h>
+#include <sbkstring.h>
+
+namespace PySide::ClassDecorator {
+
+DecoratorPrivate::DecoratorPrivate() noexcept = default;
+DecoratorPrivate::~DecoratorPrivate() = default;
+
+DecoratorPrivate *DecoratorPrivate::getPrivate(PyObject *o)
+{
+ auto *decorator = reinterpret_cast<PySideClassDecorator *>(o);
+ return decorator->d;
+}
+
+PyObject *DecoratorPrivate::tp_call_check(PyObject *args, CheckMode checkMode) const
+{
+ if (!PyTuple_Check(args) || PyTuple_Size(args) != 1) {
+ PyErr_Format(PyExc_TypeError,
+ "The %s decorator takes exactly 1 positional argument (%zd given)",
+ name(), PyTuple_Size(args));
+ return nullptr;
+ }
+
+ PyObject *arg = PyTuple_GetItem(args, 0);
+
+ // This will sometimes segfault if you mistakenly use it on a function declaration
+ if (!PyType_Check(arg)) {
+ PyErr_Format(PyExc_TypeError,
+ "The %s decorator can only be used on class declarations", name());
+ return nullptr;
+ }
+
+ auto type = reinterpret_cast<PyTypeObject *>(arg);
+
+ if (checkMode != CheckMode::None && !Shiboken::ObjectType::checkType(type)) {
+ PyErr_Format(PyExc_TypeError,
+ "The %s decorator can only be used on wrapped types.", name());
+ return nullptr;
+ }
+
+ if (checkMode == CheckMode::QObjectType && !isQObjectDerived(type, false)) {
+ PyErr_Format(PyExc_TypeError,
+ "The %s decorator can only be used on QObject-derived types.", name());
+ return nullptr;
+ }
+
+ return arg;
+}
+
+int StringDecoratorPrivate::convertToString(PyObject *self, PyObject *args)
+{
+ int result = -1;
+ if (PyTuple_Size(args) == 1) {
+ PyObject *arg = PyTuple_GET_ITEM(args, 0);
+ if (PyUnicode_Check(arg)) {
+ auto *pData = DecoratorPrivate::get<StringDecoratorPrivate>(self);
+ result = 0;
+ pData->m_string.assign(Shiboken::String::toCString(arg));
+ }
+ }
+ return result;
+}
+
+int StringDecoratorPrivate::tp_init(PyObject *self, PyObject *args, PyObject *)
+{
+ const int result = convertToString(self, args);
+ if (result != 0)
+ PyErr_Format(PyExc_TypeError, "%s takes a single string argument.", name());
+ return result;
+}
+
+int TypeDecoratorPrivate::tp_init(PyObject *self, PyObject *args, PyObject *)
+{
+ const int result = convertToType(self, args);
+ if (result != 0)
+ PyErr_Format(PyExc_TypeError, "%s takes a single type argument.", name());
+ return result;
+}
+
+int TypeDecoratorPrivate::convertToType(PyObject *self, PyObject *args)
+{
+ int result = -1;
+ const auto argsCount = PyTuple_Size(args);
+ if (argsCount == 1) {
+ PyObject *arg = PyTuple_GET_ITEM(args, 0);
+ if (PyType_Check(arg)) {
+ result = 0;
+ auto *pData = DecoratorPrivate::get<TypeDecoratorPrivate>(self);
+ pData->m_type = reinterpret_cast<PyTypeObject *>(arg);
+ }
+ }
+ return result;
+}
+
+} // namespace PySide::ClassDecorator