Skip to content

Commit 5d9c81b

Browse files
committed
Allow usage of EnumDict without setting a private attr. Add tests.
1 parent 162ebf0 commit 5d9c81b

File tree

2 files changed

+35
-3
lines changed

2 files changed

+35
-3
lines changed

Lib/enum.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,7 @@ def __init__(self):
346346
self._last_values = []
347347
self._ignore = []
348348
self._auto_called = False
349+
self._cls_name = None
349350

350351
def __setitem__(self, key, value):
351352
"""
@@ -356,7 +357,7 @@ def __setitem__(self, key, value):
356357
357358
Single underscore (sunder) names are reserved.
358359
"""
359-
if _is_private(self._cls_name, key):
360+
if self._cls_name is not None and _is_private(self._cls_name, key):
360361
# do nothing, name will be a normal attribute
361362
pass
362363
elif _is_sunder(key):
@@ -404,7 +405,7 @@ def __setitem__(self, key, value):
404405
value = value.value
405406
elif _is_descriptor(value):
406407
pass
407-
elif _is_internal_class(self._cls_name, value):
408+
elif self._cls_name is not None and _is_internal_class(self._cls_name, value):
408409
# do nothing, name will be a normal attribute
409410
pass
410411
else:

Lib/test/test_enum.py

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
from enum import Enum, EnumMeta, IntEnum, StrEnum, EnumType, Flag, IntFlag, unique, auto
1515
from enum import STRICT, CONFORM, EJECT, KEEP, _simple_enum, _test_simple_enum
1616
from enum import verify, UNIQUE, CONTINUOUS, NAMED_FLAGS, ReprEnum
17-
from enum import member, nonmember, _iter_bits_lsb
17+
from enum import member, nonmember, _iter_bits_lsb, EnumDict
1818
from io import StringIO
1919
from pickle import dumps, loads, PicklingError, HIGHEST_PROTOCOL
2020
from test import support
@@ -5414,6 +5414,37 @@ def test_convert_repr_and_str(self):
54145414
self.assertEqual(format(test_type.CONVERT_STRING_TEST_NAME_A), '5')
54155415

54165416

5417+
class TestEnumDict(unittest.TestCase):
5418+
def test_enum_dict_in_metaclass(self):
5419+
"""Test that EnumDict is usable as a class namespace"""
5420+
class Meta(type):
5421+
@classmethod
5422+
def __prepare__(metacls, cls, bases, **kwds):
5423+
return EnumDict()
5424+
5425+
class MyClass(metaclass=Meta):
5426+
a = 1
5427+
5428+
with self.assertRaises(TypeError):
5429+
a = 2 # duplicate
5430+
5431+
with self.assertRaises(ValueError):
5432+
_a_sunder_ = 3
5433+
5434+
def test_enum_dict_standalone(self):
5435+
"""Test that EnumDict is usable on its own"""
5436+
enumdict = EnumDict()
5437+
enumdict['a'] = 1
5438+
5439+
with self.assertRaises(TypeError):
5440+
enumdict['a'] = 'other value'
5441+
5442+
# Only MutableMapping interface is overridden for now.
5443+
# If this starts passing, update the documentation.
5444+
enumdict |= {'a': 'other value'}
5445+
self.assertEqual(enumdict['a'], 'other value')
5446+
5447+
54175448
# helpers
54185449

54195450
def enum_dir(cls):

0 commit comments

Comments
 (0)