Skip to content
Permalink
Browse files

Fix crash when trying to use meta enums on some platforms

Keeping references to static meta objects and meta enums around seems
to avoid the crash

(cherry picked from commit 278ccb8)
  • Loading branch information
nyalldawson committed Nov 20, 2020
1 parent f5bc8c9 commit d72e36dd9fceda259db4cb4f615344fbf0f89e66
Showing with 16 additions and 5 deletions.
  1. +13 −2 python/core/additions/metaenum.py
  2. +3 −3 tests/src/python/test_core_additions.py
@@ -17,6 +17,9 @@
***************************************************************************
"""

META_OBJECT_BY_ENUM_CLASS = {}
META_ENUM_BY_ENUM_CLASS = {}


def metaEnumFromValue(enumValue, baseClass=None, raiseException=True):
"""
@@ -39,6 +42,11 @@ def metaEnumFromType(enumClass, baseClass=None, raiseException=True):
:param raiseException: if False, no exception will be raised and None will be return in case of failure
:return: the QMetaEnum if it succeeds, None otherwise
"""
global META_OBJECT_BY_ENUM_CLASS
global META_ENUM_BY_ENUM_CLASS
if enumClass in META_ENUM_BY_ENUM_CLASS:
return META_ENUM_BY_ENUM_CLASS[enumClass]

if enumClass == int:
if raiseException:
raise TypeError("enumClass is an int, while it should be an enum")
@@ -54,8 +62,11 @@ def metaEnumFromType(enumClass, baseClass=None, raiseException=True):
raise ValueError("Enum type does not implement baseClass method. Provide the base class as argument.")

try:
idx = baseClass.staticMetaObject.indexOfEnumerator(enumClass.__name__)
meta_enum = baseClass.staticMetaObject.enumerator(idx)
meta_object = baseClass.staticMetaObject
META_OBJECT_BY_ENUM_CLASS[enumClass] = meta_object
idx = meta_object.indexOfEnumerator(enumClass.__name__)
meta_enum = meta_object.enumerator(idx)
META_ENUM_BY_ENUM_CLASS[enumClass] = meta_enum
except AttributeError:
if raiseException:
raise TypeError("could not get the metaEnum for {}".format(enumClass.__name__))
@@ -27,10 +27,10 @@ def testMetaEnum(self):
self.assertIsNotNone(me)
self.assertEqual(me.valueToKey(QgsTolerance.Pixels), 'Pixels')

# if using same variable twice (e.g. me = me2), this seg faults
me2 = metaEnumFromValue(QgsTolerance.Pixels, QgsTolerance)
# check that using same variable twice doesn't segfault
me = metaEnumFromValue(QgsTolerance.Pixels, QgsTolerance)
self.assertIsNotNone(me)
self.assertEqual(me2.valueToKey(QgsTolerance.Pixels), 'Pixels')
self.assertEqual(me.valueToKey(QgsTolerance.Pixels), 'Pixels')

# do not raise error
self.assertIsNone(metaEnumFromValue(1, QgsTolerance, False))

0 comments on commit d72e36d

Please sign in to comment.
You can’t perform that action at this time.