aboutsummaryrefslogtreecommitdiffstats
path: root/sources/pyside2/libpyside/pysideqenum.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'sources/pyside2/libpyside/pysideqenum.cpp')
-rw-r--r--sources/pyside2/libpyside/pysideqenum.cpp258
1 files changed, 0 insertions, 258 deletions
diff --git a/sources/pyside2/libpyside/pysideqenum.cpp b/sources/pyside2/libpyside/pysideqenum.cpp
deleted file mode 100644
index 07a548cb6..000000000
--- a/sources/pyside2/libpyside/pysideqenum.cpp
+++ /dev/null
@@ -1,258 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** 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 Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** 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-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <shiboken.h>
-
-#include "pysideqenum.h"
-#include "dynamicqmetaobject.h"
-#include "pyside_p.h"
-
-
-///////////////////////////////////////////////////////////////
-//
-// PYSIDE-957: Create QEnum dynamically from Python Enum
-//
-//
-extern "C" {
-
-using namespace Shiboken;
-
-static PyObject *analyzePyEnum(PyObject *pyenum, PyObject *container = nullptr)
-{
- /*
- * This is the straight-forward implementation of QEnum/QFlag. It does no
- * longer create an equivalent Qt enum but takes the Python enum as-is.
- *
- * It parses an Enum/Flag derived Python enum completely so that
- * registering can be done without error checks. This would be impossible
- * in MetaObjectBuilderPrivate::parsePythonType.
- */
- AutoDecRef members(PyObject_GetAttr(pyenum, Shiboken::PyMagicName::members()));
- if (members.isNull())
- return nullptr;
- AutoDecRef items(PyMapping_Items(members));
- if (items.isNull())
- return nullptr;
- int iflag = PySide::QEnum::isFlag(pyenum);
- if (iflag < 0)
- return nullptr;
- Py_ssize_t nr_items = PySequence_Length(items);
- if (nr_items < 0)
- return nullptr;
-
- for (Py_ssize_t idx = 0; idx < nr_items; ++idx) {
- AutoDecRef item(PySequence_GetItem(items, idx));
- if (item.isNull())
- return nullptr;
-
- // The item should be a 2-element sequence of the key name and an
- // object containing the value.
- AutoDecRef key(PySequence_GetItem(item, 0));
- AutoDecRef member(PySequence_GetItem(item, 1));
- if (key.isNull() || member.isNull())
- return nullptr;
- if (!Shiboken::String::check(key)) {
- // '%.200s' is the safety stringbuffer size of most CPython functions.
- PyErr_Format(PyExc_TypeError,
- "QEnum expected a string mapping as __members__, got '%.200s'",
- Py_TYPE(key)->tp_name);
- return nullptr;
- }
-
- // Get the value.
- AutoDecRef value(PyObject_GetAttr(member, Shiboken::PyName::value()));
- if (value.isNull())
- return nullptr;
- if (!PyInt_Check(value)) { // int/long cheating
- PyErr_Format(PyExc_TypeError,
- "QEnum expected an int value as '%.200s', got '%.200s'",
- Shiboken::String::toCString(key), Py_TYPE(value)->tp_name);
- return nullptr;
- }
- }
- Py_RETURN_NONE;
-}
-
-static Py_ssize_t get_lineno()
-{
- PyObject *frame = reinterpret_cast<PyObject *>(PyEval_GetFrame()); // borrowed ref
- AutoDecRef ob_lineno(PyObject_GetAttr(frame, Shiboken::PyName::f_lineno()));
- if (ob_lineno.isNull() || !PyInt_Check(ob_lineno)) // int/long cheating
- return -1;
- return PyInt_AsSsize_t(ob_lineno); // int/long cheating
-}
-
-static bool is_module_code()
-{
- PyObject *frame = reinterpret_cast<PyObject *>(PyEval_GetFrame()); // borrowed ref
- AutoDecRef ob_code(PyObject_GetAttr(frame, Shiboken::PyName::f_code()));
- if (ob_code.isNull())
- return false;
- AutoDecRef ob_name(PyObject_GetAttr(ob_code, Shiboken::PyName::co_name()));
- if (ob_name.isNull())
- return false;
- const char *codename = Shiboken::String::toCString(ob_name);
- return strcmp(codename, "<module>") == 0;
-}
-
-} // extern "C"
-
-namespace PySide { namespace QEnum {
-
-static std::map<int, PyObject *> enumCollector;
-
-int isFlag(PyObject *obType)
-{
- /*
- * Find out if this is an Enum or a Flag derived class.
- * It checks also if things come from the enum module and if it is
- * an Enum or Flag class at all.
- *
- * The function is called in MetaObjectBuilderPrivate::parsePythonType
- * again to obtain the flag value.
- */
- if (!PyType_Check(obType)) {
- PyErr_Format(PyExc_TypeError, "a class argument was expected, not a '%.200s' instance",
- Py_TYPE(obType)->tp_name);
- return -1;
- };
- auto *type = reinterpret_cast<PyTypeObject *>(obType);
- PyObject *mro = type->tp_mro;
- Py_ssize_t i, n = PyTuple_GET_SIZE(mro);
- bool right_module = false;
- bool have_enum = false;
- bool have_flag = false;
- bool have_members = PyObject_HasAttr(obType, PyMagicName::members());
- for (i = 0; i < n; i++) {
- obType = PyTuple_GET_ITEM(mro, i);
- type = reinterpret_cast<PyTypeObject *>(obType);
- AutoDecRef mod(PyObject_GetAttr(obType, PyMagicName::module()));
- QByteArray cmod = String::toCString(mod);
- QByteArray cname = type->tp_name;
- if (cmod == "enum") {
- right_module = true;
- if (cname == "Enum")
- have_enum = true;
- else if (cname == "Flag")
- have_flag = true;
- }
- }
- if (!right_module || !(have_enum || have_flag) || !have_members) {
- PyErr_Format(PyExc_TypeError, "type %.200s does not inherit from 'Enum' or 'Flag'",
- type->tp_name);
- return -1;
- }
- return bool(have_flag);
-}
-
-PyObject *QEnumMacro(PyObject *pyenum, bool flag)
-{
- /*
- * This is the official interface of 'QEnum'. It first calls 'analyzePyEnum'.
- * When called as toplevel enum, it simply returns after some checks.
- * Otherwise, 'pyenum' is stored for later use by the meta class registation.
- */
- int computedFlag = isFlag(pyenum);
- if (computedFlag < 0)
- return nullptr;
- if (bool(computedFlag) != flag) {
- AutoDecRef name(PyObject_GetAttr(pyenum, PyMagicName::qualname()));
- auto cname = String::toCString(name);
- const char *e = "Enum";
- const char *f = "Flag";
- PyErr_Format(PyExc_TypeError, "expected '%s' but got '%s' (%.200s)",
- flag ? f : e, flag ? e : f, cname);
- return nullptr;
- }
- auto ok = analyzePyEnum(pyenum);
- if (ok == nullptr)
- return nullptr;
- if (is_module_code()) {
- // This is a toplevel enum which we resolve immediately.
- Py_INCREF(pyenum);
- return pyenum;
- }
-
- Py_ssize_t lineno = get_lineno();
- if (lineno < 0)
- return nullptr;
- // Handle the rest via line number and the meta class.
- Py_INCREF(pyenum);
- Py_XDECREF(enumCollector[lineno]);
- enumCollector[lineno] = pyenum;
- Py_RETURN_NONE;
-}
-
-std::vector<PyObject *> resolveDelayedQEnums(PyTypeObject *containerType)
-{
- /*
- * This is the internal interface of 'QEnum'.
- * It is called at the end of the meta class call 'SbkObjectTypeTpNew' via
- * MetaObjectBuilderPrivate::parsePythonType and resolves the collected
- * Python Enum arguments. The result is then registered.
- */
- if (enumCollector.empty())
- return {};
- PyObject *obContainerType = reinterpret_cast<PyObject *>(containerType);
- Py_ssize_t lineno = get_lineno();
-
- std::vector<PyObject *> result;
-
- auto it = enumCollector.begin();
- while (it != enumCollector.end()) {
- int nr = it->first;
- PyObject *pyenum = it->second;
- if (nr >= lineno) {
- AutoDecRef name(PyObject_GetAttr(pyenum, PyMagicName::name()));
- if (name.isNull() || PyObject_SetAttr(obContainerType, name, pyenum) < 0)
- return {};
- result.push_back(pyenum);
- it = enumCollector.erase(it);
- } else {
- ++it;
- }
- }
- return result;
-}
-
-} // namespace Enum
-} // namespace Shiboken
-
-//
-///////////////////////////////////////////////////////////////