bpo-34750: [Enum] add `_EnumDict.update()` support (GH-23725)
This allows easier Enum construction in unusual cases, such as including dynamic member definitions into a class definition: # created dynamically foo_defines = {'FOO_CAT': 'aloof', 'BAR_DOG': 'friendly', 'FOO_HORSE': 'big'} class Foo(Enum): vars().update({ k: v for k, v in foo_defines.items() if k.startswith('FOO_') }) def upper(self): # example method return self.value.upper()
This commit is contained in:
parent
efb13be72c
commit
a658287179
12
Lib/enum.py
12
Lib/enum.py
|
@ -136,7 +136,7 @@ class _EnumDict(dict):
|
|||
key = '_order_'
|
||||
elif key in self._member_names:
|
||||
# descriptor overwriting an enum?
|
||||
raise TypeError('Attempted to reuse key: %r' % key)
|
||||
raise TypeError('%r already defined as: %r' % (key, self[key]))
|
||||
elif key in self._ignore:
|
||||
pass
|
||||
elif not _is_descriptor(value):
|
||||
|
@ -157,6 +157,16 @@ class _EnumDict(dict):
|
|||
self._last_values.append(value)
|
||||
super().__setitem__(key, value)
|
||||
|
||||
def update(self, members, **more_members):
|
||||
try:
|
||||
for name in members.keys():
|
||||
self[name] = members[name]
|
||||
except AttributeError:
|
||||
for name, value in members:
|
||||
self[name] = value
|
||||
for name, value in more_members.items():
|
||||
self[name] = value
|
||||
|
||||
|
||||
# Dummy value for Enum as EnumMeta explicitly checks for it, but of course
|
||||
# until EnumMeta finishes running the first time the Enum class doesn't exist.
|
||||
|
|
|
@ -2186,6 +2186,34 @@ class TestEnum(unittest.TestCase):
|
|||
self.assertEqual([Strings.ONE, Strings.TWO], ['one', 'two'])
|
||||
|
||||
|
||||
def test_dynamic_members_with_static_methods(self):
|
||||
#
|
||||
foo_defines = {'FOO_CAT': 'aloof', 'BAR_DOG': 'friendly', 'FOO_HORSE': 'big'}
|
||||
class Foo(Enum):
|
||||
vars().update({
|
||||
k: v
|
||||
for k, v in foo_defines.items()
|
||||
if k.startswith('FOO_')
|
||||
})
|
||||
def upper(self):
|
||||
return self.value.upper()
|
||||
self.assertEqual(list(Foo), [Foo.FOO_CAT, Foo.FOO_HORSE])
|
||||
self.assertEqual(Foo.FOO_CAT.value, 'aloof')
|
||||
self.assertEqual(Foo.FOO_HORSE.upper(), 'BIG')
|
||||
#
|
||||
with self.assertRaisesRegex(TypeError, "'FOO_CAT' already defined as: 'aloof'"):
|
||||
class FooBar(Enum):
|
||||
vars().update({
|
||||
k: v
|
||||
for k, v in foo_defines.items()
|
||||
if k.startswith('FOO_')
|
||||
},
|
||||
**{'FOO_CAT': 'small'},
|
||||
)
|
||||
def upper(self):
|
||||
return self.value.upper()
|
||||
|
||||
|
||||
class TestOrder(unittest.TestCase):
|
||||
|
||||
def test_same_members(self):
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
[Enum] `_EnumDict.update()` is now supported
|
Loading…
Reference in New Issue