From 64a9972b40b8258a6e37498da6279f4e40a88e2d Mon Sep 17 00:00:00 2001 From: Ethan Furman Date: Sun, 22 Sep 2013 16:18:19 -0700 Subject: [PATCH] Close #19025: Better error message when trying to delete an Enum member. Also slight code reorg for PEP 8 guidelines. --- Lib/enum.py | 14 ++++++++++++-- Lib/test/test_enum.py | 21 +++++++++++++++++++++ 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/Lib/enum.py b/Lib/enum.py index 86f94d905ff..0a7afc45c0b 100644 --- a/Lib/enum.py +++ b/Lib/enum.py @@ -231,8 +231,17 @@ class EnumMeta(type): def __contains__(cls, member): return isinstance(member, cls) and member.name in cls._member_map_ + def __delattr__(cls, attr): + # nicer error message when someone tries to delete an attribute + # (see issue19025). + if attr in cls._member_map_: + raise AttributeError( + "%s: cannot delete Enum member." % cls.__name__) + super().__delattr__(attr) + def __dir__(self): - return ['__class__', '__doc__', '__members__', '__module__'] + self._member_names_ + return (['__class__', '__doc__', '__members__', '__module__'] + + self._member_names_) def __getattr__(cls, name): """Return the enum member matching `name` @@ -459,7 +468,8 @@ class Enum(metaclass=EnumMeta): def __dir__(self): added_behavior = [m for m in self.__class__.__dict__ if m[0] != '_'] - return ['__class__', '__doc__', '__module__', 'name', 'value'] + added_behavior + return (['__class__', '__doc__', '__module__', 'name', 'value'] + + added_behavior) def __eq__(self, other): if type(other) is self.__class__: diff --git a/Lib/test/test_enum.py b/Lib/test/test_enum.py index 65d0de743a4..d59c5e3ea3c 100644 --- a/Lib/test/test_enum.py +++ b/Lib/test/test_enum.py @@ -172,6 +172,27 @@ class TestEnum(unittest.TestCase): with self.assertRaises(AttributeError): Season.WINTER = 'really cold' + def test_attribute_deletion(self): + class Season(Enum): + SPRING = 1 + SUMMER = 2 + AUTUMN = 3 + WINTER = 4 + + def spam(cls): + pass + + self.assertTrue(hasattr(Season, 'spam')) + del Season.spam + self.assertFalse(hasattr(Season, 'spam')) + + with self.assertRaises(AttributeError): + del Season.SPRING + with self.assertRaises(AttributeError): + del Season.DRY + with self.assertRaises(AttributeError): + del Season.SPRING.name + def test_invalid_names(self): with self.assertRaises(ValueError): class Wrong(Enum):