diff options
author | Christian Tismer <tismer@stackless.com> | 2022-04-10 17:22:14 +0200 |
---|---|---|
committer | Christian Tismer <tismer@stackless.com> | 2022-05-23 22:45:33 +0200 |
commit | aecfffcd0169e8e9e6cebf4db2dce19afeb3b051 (patch) | |
tree | b63262c350a8fda944db9703e55f9e4a11116564 /sources/pyside6 | |
parent | 8472a2b6eb32e6238e82f5778add908652b2cd82 (diff) |
PyEnum: Implement Switchable Qt Enums Using Python Enums
The mapping from Qt Enum to Python Enum was considered
to be difficult. Actually, it is easier than thought.
As a minimum invasive approach, this implementation
changes very little in the first place. The generation
process of enums stays almost unchanged, which simplifies
handling of the generated code very much.
At the end of each generated Enum, we call a special
function that grabs the newly generated enum, reads all
items and produces a Python class that replaces
the enum in-place.
We don't generate Python code, but the functional API to create
the new enums. There are lots of more optimizations possible,
but this concept solves the issue nice and quickly.
A harder problem was the need to map all QFlag structures
to enum.Flag structures from Python. This caused a sometimes
hacky coding because both the old and the new version are
supported. This will be totally cleaned up when we
remove the old implementation.
Task-number: PYSIDE-1735
Change-Id: I66991312f2d7b137f110a4db30702b8f3bf518dd
Reviewed-by: Christian Tismer <tismer@stackless.com>
(cherry picked from commit 37b5b3e2db07d4256aa17376d231a76ea3c393cd)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
Diffstat (limited to 'sources/pyside6')
-rw-r--r-- | sources/pyside6/PySide6/templates/gui_common.xml | 3 | ||||
-rw-r--r-- | sources/pyside6/libpyside/pysideqflags.cpp | 26 |
2 files changed, 29 insertions, 0 deletions
diff --git a/sources/pyside6/PySide6/templates/gui_common.xml b/sources/pyside6/PySide6/templates/gui_common.xml index b802054a8..ee132a77f 100644 --- a/sources/pyside6/PySide6/templates/gui_common.xml +++ b/sources/pyside6/PySide6/templates/gui_common.xml @@ -61,6 +61,9 @@ break; } } + // PySIDE-1735: Enums are now implemented in Python, so we need to avoid asserts. + if (PyErr_Occurred()) + break; auto xpm = new const char*[lineCount]; for (Py_ssize_t line = 0; line < lineCount; ++line) diff --git a/sources/pyside6/libpyside/pysideqflags.cpp b/sources/pyside6/libpyside/pysideqflags.cpp index 84e87f038..8cc6b0b30 100644 --- a/sources/pyside6/libpyside/pysideqflags.cpp +++ b/sources/pyside6/libpyside/pysideqflags.cpp @@ -49,6 +49,11 @@ extern "C" { struct PySideQFlagsTypePrivate { SbkConverter *converter; + // PYSIDE-1735: These fields are just there for comatibility with the enumstructure. + // We need to switch between flags and enum at runtine. + // This will vanish completely when we no longer support two implementations. + const char *_cppName; + PyTypeObject *_replacementType; }; /** * Type of all QFlags @@ -145,6 +150,19 @@ extern "C" { PepType_PFTP_delete(flagsType); Sbk_object_dealloc(self); } + + /// PYSIDE-1735: Support for redirection to the new Python enum.Flag . + static PyTypeObject *getEnumMeta() + { + static auto *mod = PyImport_ImportModule("enum"); + if (mod) { + static auto *EnumMeta = PyObject_GetAttrString(mod, "EnumMeta"); + if (EnumMeta) + return reinterpret_cast<PyTypeObject *>(EnumMeta); + } + Py_FatalError("Python module 'enum' not found"); + return nullptr; + } } namespace PySide @@ -194,6 +212,14 @@ namespace QFlags PySideQFlagsObject *newObject(long value, PyTypeObject *type) { + // PYSIDE-1735: In case of a new Python enum, we must redirect to the + // enum.Flag implementation. + static PyTypeObject *enumMeta = getEnumMeta(); + if (Py_TYPE(type) == enumMeta) { + // We are cheating: This is an enum type. + auto *flag_enum = PyObject_CallFunction(reinterpret_cast<PyObject *>(type), "i", value); + return reinterpret_cast<PySideQFlagsObject *>(flag_enum); + } PySideQFlagsObject *qflags = PyObject_New(PySideQFlagsObject, type); qflags->ob_value = value; return qflags; |