How about a pure method for converting to enum? Just stash this in a util lib. Or you could put it on a base Enum class and have target_enum default to self.
Could also tweak this to raise an exception instead of using the default value, but the default worked better for my specific case.
from enum import Enum
def to_enum(v,target_enum,default = None):
'''
if v is given enum, return it
if v is an int, convert to enum via int convert
if v is str convert to enum via string convert
'''
ret = default
if v is None:
return ret
if v in target_enum:
return v
try:
return target_enum(int(v))
except Exception:
pass
try:
return target_enum[str(v)]
except Exception:
pass
return ret
Here is the unittest class for it.
import unittest
from enum import Enum,unique
class EnumTest(Enum):
T0 = 0
T1 = 1
class EnumTest2(Enum):
T0 = 0
T1 = 1
class EnumUtilTest(unittest.TestCase):
def test_to_enum(self):
'''str, int, and Enum should be convertable '''
r = Util.to_enum(1,EnumTest)
self.assertEqual(r,EnumTest.T1)
r = Util.to_enum('T1',EnumTest)
self.assertEqual(r,EnumTest.T1)
r = Util.to_enum(EnumTest.T1,EnumTest)
self.assertEqual(r,EnumTest.T1)
r = Util.to_enum('1',EnumTest)
self.assertEqual(r,EnumTest.T1)
def test_to_enum_fail(self):
'''Return None if convert fails'''
self.assertIsNone(Util.to_enum( None,EnumTest ))
self.assertIsNone(Util.to_enum( 'abd',EnumTest ))
self.assertIsNone(Util.to_enum( 123,EnumTest ))
self.assertIsNone(Util.to_enum( EnumTest2.T1,EnumTest ))
def test_to_enum_default(self):
'''test default param'''
r = Util.to_enum(EnumTest2.T1,EnumTest,EnumTest.T0)
self.assertEqual(r,EnumTest.T0)
if __name__ == '__main__':
unittest.main()