diff options
author | Christian Tismer <tismer@stackless.com> | 2023-06-07 13:14:37 +0200 |
---|---|---|
committer | Christian Tismer <tismer@stackless.com> | 2023-06-09 10:31:47 +0200 |
commit | 8f85f155651e36ba05c3485a2c627efb9c3ddd2c (patch) | |
tree | 5913264f890f9091299bf5cedf459ad6e15bfe6b | |
parent | 73ed532e0af50a0cfd0df2b7a7aa8a974ebbc87a (diff) |
PyEnum: Remove old Enums and prepare direct creation of new Enums
Old and new Enums are still woven into each other because
Qt itself still has the old implementation.
Remove the old Enums from Python and simplify the
generator as a first step. The PYSIDE63_OPTION_PYTHON_ENUM
is still usable but can no longer be zero.
[ChangeLog][PySide6] Old Enums are no longer supported.
Task-number: PYSIDE-1735
Change-Id: Idaacd8d5f3c0174e505f855963c1723204de3a7d
Reviewed-by: Cristian Maureira-Fredes <cristian.maureira-fredes@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
5 files changed, 23 insertions, 108 deletions
diff --git a/sources/shiboken6/generator/shiboken/cppgenerator.cpp b/sources/shiboken6/generator/shiboken/cppgenerator.cpp index 8b19ba9ad..38c3f139d 100644 --- a/sources/shiboken6/generator/shiboken/cppgenerator.cpp +++ b/sources/shiboken6/generator/shiboken/cppgenerator.cpp @@ -5778,18 +5778,10 @@ void CppGenerator::writeEnumInitialization(TextStream &s, const AbstractMetaEnum } break; case CEnum: - s << "if (!Shiboken::Enum::"; - s << ((enclosingClass || hasUpperEnclosingClass) ? "createScopedEnumItem" - : "createGlobalEnumItem"); - s << '(' << "EType" << ',' << '\n' << indent - << enclosingObjectVariable << ", \"" << mangledName << "\", " - << enumValueText << "))\n" << errorReturn << outdent; - break; case EnumClass: - s << "if (!Shiboken::Enum::createScopedEnumItem(" - << "EType" << ",\n" << indent - << "EType" << ", \"" << mangledName << "\", " - << enumValueText << "))\n" << errorReturn << outdent; + s << "if (!Shiboken::Enum::createEnumItemOld(EType,\n" << indent + << "\"" << mangledName << "\", " << enumValueText << "))\n" << errorReturn + << outdent; break; } } @@ -5799,7 +5791,7 @@ void CppGenerator::writeEnumInitialization(TextStream &s, const AbstractMetaEnum if (cppEnum.typeEntry()->flags()) { s << "// PYSIDE-1735: Mapping the flags class to the same enum class.\n" << cpythonTypeNameExt(cppEnum.typeEntry()->flags()) << " =\n" - << indent << "mapFlagsToSameEnum(FType, EType);\n" << outdent; + << indent << "EType;\n" << outdent; } writeEnumConverterInitialization(s, cppEnum); diff --git a/sources/shiboken6/libshiboken/sbkenum.cpp b/sources/shiboken6/libshiboken/sbkenum.cpp index 212e6fb73..8095ab703 100644 --- a/sources/shiboken6/libshiboken/sbkenum.cpp +++ b/sources/shiboken6/libshiboken/sbkenum.cpp @@ -381,8 +381,6 @@ static bool _init_enum() return true; } -static int useOldEnum = -1; - static PyMethodDef SbkEnumObject_Methods[] = { {"__reduce__", reinterpret_cast<PyCFunction>(enum___reduce__), METH_NOARGS, nullptr}, @@ -399,8 +397,7 @@ static PyObject *PyFlag_KEEP{}; bool PyEnumMeta_Check(PyObject *ob) { - return Py_TYPE(ob) == (useOldEnum ? SbkEnumType_TypeF() - : reinterpret_cast<PyTypeObject *>(PyEnumMeta)); + return Py_TYPE(ob) == reinterpret_cast<PyTypeObject *>(PyEnumMeta); } PyTypeObject *getPyEnumMeta() @@ -448,7 +445,6 @@ void init_enum() } int ignoreOver{}; Enum::enumOption = PyLong_AsLongAndOverflow(option, &ignoreOver); - useOldEnum = Enum::enumOption == Enum::ENOPT_OLD_ENUM; getPyEnumMeta(); isInitialized = true; } @@ -474,8 +470,7 @@ int enumIsFlag(PyObject *ob_type) // PYSIDE-1735: Helper function to ask what enum we are using bool usingNewEnum() { - init_enum(); - return !useOldEnum; + return true; } } // extern "C" @@ -525,39 +520,13 @@ bool check(PyObject *pyObj) { init_enum(); - // PYSIDE-1735: Decide dynamically if new or old enums will be used. - if (useOldEnum) - return Py_TYPE(Py_TYPE(pyObj)) == SbkEnumType_TypeF(); - static PyTypeObject *meta = getPyEnumMeta(); return Py_TYPE(Py_TYPE(pyObj)) == reinterpret_cast<PyTypeObject *>(meta); } -static PyObject *getEnumItemFromValueOld(PyTypeObject *enumType, - EnumValueType itemValue) -{ - PyObject *key, *value; - Py_ssize_t pos = 0; - PyObject *values = PyDict_GetItem(enumType->tp_dict, PyName::values()); - if (values == nullptr) - return nullptr; - - while (PyDict_Next(values, &pos, &key, &value)) { - auto *obj = reinterpret_cast<SbkEnumObject *>(value); - if (obj->ob_value == itemValue) { - Py_INCREF(value); - return value; - } - } - return nullptr; -} - PyObject *getEnumItemFromValue(PyTypeObject *enumType, EnumValueType itemValue) { init_enum(); - // PYSIDE-1735: Decide dynamically if new or old enums will be used. - if (useOldEnum) - return getEnumItemFromValueOld(enumType, itemValue); auto *obEnumType = reinterpret_cast<PyObject *>(enumType); AutoDecRef val2members(PyObject_GetAttrString(obEnumType, "_value2member_map_")); @@ -632,26 +601,10 @@ static PyObject *createEnumItem(PyTypeObject *enumType, const char *itemName, return enumItem; } -bool createGlobalEnumItem(PyTypeObject *enumType, PyObject *module, - const char *itemName, EnumValueType itemValue) +bool createEnumItemOld(PyTypeObject *enumType, const char *itemName, EnumValueType itemValue) { - PyObject *enumItem = createEnumItem(enumType, itemName, itemValue); - if (!enumItem) - return false; - int ok = useOldEnum ? PyModule_AddObject(module, itemName, enumItem) : true; - Py_DECREF(enumItem); - return ok >= 0; -} - -bool createScopedEnumItem(PyTypeObject *enumType, PyTypeObject *scope, - const char *itemName, EnumValueType itemValue) -{ - PyObject *enumItem = createEnumItem(enumType, itemName, itemValue); - if (!enumItem) - return false; - int ok = useOldEnum ? PyDict_SetItemString(scope->tp_dict, itemName, enumItem) : true; - Py_DECREF(enumItem); - return ok >= 0; + Shiboken::AutoDecRef enumItem(createEnumItem(enumType, itemName, itemValue)); + return !enumItem.isNull(); } // This exists temporary as the old way to create an enum item. @@ -699,9 +652,6 @@ PyObject *newItem(PyTypeObject *enumType, EnumValueType itemValue, const char *itemName) { init_enum(); - // PYSIDE-1735: Decide dynamically if new or old enums will be used. - if (useOldEnum) - return newItemOld(enumType, itemValue, itemName); auto *obEnumType = reinterpret_cast<PyObject *>(enumType); if (!itemName) @@ -846,10 +796,10 @@ PyTypeObject *newTypeWithName(const char *name, const char *cppName, PyTypeObject *numbers_fromFlag) { - if (!useOldEnum) - PyErr_Format(PyExc_RuntimeError, "function `%s` can no longer be used when the Python " - "Enum's have been selected", __FUNCTION__); - return newTypeWithNameOld(name, cppName, numbers_fromFlag); + // old enums are gone, remove completely? + PyErr_Format(PyExc_RuntimeError, "function `%s` can no longer be used because old " + "Enums are no longer supported", __FUNCTION__); + return nullptr; } const char *getCppName(PyTypeObject *enumType) @@ -866,10 +816,6 @@ EnumValueType getValue(PyObject *enumItem) assert(Enum::check(enumItem)); - // PYSIDE-1735: Decide dynamically if new or old enums will be used. - if (useOldEnum) - return reinterpret_cast<SbkEnumObject *>(enumItem)->ob_value; - AutoDecRef pyValue(PyObject_GetAttrString(enumItem, "value")); return PyLong_AsLongLong(pyValue); } @@ -962,10 +908,6 @@ static PyTypeObject *recordCurrentEnum(PyObject *scopeOrModule, lec.enumType = enumType; lec.flagsType = flagsType; - // PYSIDE-1735: Decide dynamically if new or old enums will be used. - if (useOldEnum) - return flagsType; - // We return nullptr as flagsType to disable flag creation. return nullptr; } @@ -1084,10 +1026,6 @@ PyTypeObject *morphLastEnumToPython() auto *enumType = lec.enumType; // This is temporary; SbkEnumType will be removed, soon. - // PYSIDE-1735: Decide dynamically if new or old enums will be used. - if (useOldEnum) - return enumType; - auto *setp = PepType_SETP(reinterpret_cast<SbkEnumType *>(enumType)); if (setp->replacementType) { // For some (yet to fix) reason, initialization of the enums can happen twice. @@ -1190,10 +1128,4 @@ PyTypeObject *morphLastEnumToPython() return newType; } -PyTypeObject *mapFlagsToSameEnum(PyTypeObject *FType, PyTypeObject *EType) -{ - // this will be switchable... - return useOldEnum ? FType : EType; -} - } // extern "C" diff --git a/sources/shiboken6/libshiboken/sbkenum.h b/sources/shiboken6/libshiboken/sbkenum.h index a39519189..b14e6dd42 100644 --- a/sources/shiboken6/libshiboken/sbkenum.h +++ b/sources/shiboken6/libshiboken/sbkenum.h @@ -57,20 +57,10 @@ namespace Enum const char *cppName, PyTypeObject *flagsType = nullptr); - /** - * Creates a new enum item for a given enum type and adds it to \p module. - * \param enumType Enum type to where the new enum item will be added. - * \param module Module to where the enum type of the new enum item belongs. - * \param itemName Name of the enum item. - * \param itemValue Numerical value of the enum item. - * \return true if everything goes fine, false if it fails. - */ - LIBSHIBOKEN_API bool createGlobalEnumItem(PyTypeObject *enumType, PyObject *module, - const char *itemName, - EnumValueType itemValue); - /// This function does the same as createGlobalEnumItem, but adds the enum to a Shiboken type or namespace. - LIBSHIBOKEN_API bool createScopedEnumItem(PyTypeObject *enumType, PyTypeObject *scope, - const char *itemName, EnumValueType itemValue); + /// Creates a new enum item for a given enum type. + LIBSHIBOKEN_API bool createEnumItemOld(PyTypeObject *enumType, + const char *itemName, + EnumValueType itemValue); LIBSHIBOKEN_API PyObject *newItem(PyTypeObject *enumType, EnumValueType itemValue, const char *itemName = nullptr); diff --git a/sources/shiboken6/libshiboken/sbkenum_p.h b/sources/shiboken6/libshiboken/sbkenum_p.h index d8477b4b3..705aa4d9d 100644 --- a/sources/shiboken6/libshiboken/sbkenum_p.h +++ b/sources/shiboken6/libshiboken/sbkenum_p.h @@ -21,7 +21,6 @@ LIBSHIBOKEN_API void initEnumFlagsDict(PyTypeObject *type); /// PYSIDE-1735: Patching the Enum / Flags implementation. Remove in 6.4 LIBSHIBOKEN_API PyTypeObject *morphLastEnumToPython(); -LIBSHIBOKEN_API PyTypeObject *mapFlagsToSameEnum(PyTypeObject *FType, PyTypeObject *EType); /// PYSIDE-1735: Make sure that we can import the Python enum implementation. LIBSHIBOKEN_API PyTypeObject *getPyEnumMeta(); @@ -35,7 +34,7 @@ LIBSHIBOKEN_API bool usingNewEnum(); namespace Shiboken { namespace Enum { enum : int { - ENOPT_OLD_ENUM = 0x00, + ENOPT_OLD_ENUM = 0x00, // no longer supported ENOPT_NEW_ENUM = 0x01, ENOPT_INHERIT_INT = 0x02, ENOPT_GLOBAL_SHORTCUT = 0x04, diff --git a/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/parser.py b/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/parser.py index 5280e1e25..fdd9a1919 100644 --- a/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/parser.py +++ b/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/parser.py @@ -64,11 +64,11 @@ def _get_flag_enum_option(): try: flag = ast.literal_eval(opt) except Exception: - flag = True + flag = False # turn a forbidden option into an error elif hasattr(sys, sysname): - flag = getattr(sys, sysname) + opt2 = flag = getattr(sys, sysname) if not isinstance(flag, int): - flag = True + flag = False # turn a forbidden option into an error p = f"\n *** Python is at version {'.'.join(map(str, pyminver or (0,)))} now." q = f"\n *** PySide is at version {'.'.join(map(str, ver[:2]))} now." # PYSIDE-1797: Emit a warning when we may remove pep384_issue33738.cpp @@ -86,6 +86,8 @@ def _get_flag_enum_option(): # normalize the sys attribute setattr(sys, sysname, flag) os.environ[envname] = str(flag) + if int(flag) == 0: + raise RuntimeError(f"Old Enums are no longer supported. int({opt or opt2}) evaluates to 0)") return flag |