]> granicus.if.org Git - python/commitdiff
Close #18924: Block naive attempts to change an Enum member.
authorEthan Furman <ethan@stoneleaf.us>
Fri, 6 Sep 2013 14:16:48 +0000 (07:16 -0700)
committerEthan Furman <ethan@stoneleaf.us>
Fri, 6 Sep 2013 14:16:48 +0000 (07:16 -0700)
Lib/enum.py
Lib/test/test_enum.py

index 8219005bb61996d82445decb3cb3aa936f6bdba8..82058ae9249a251d5494d56a68a551cdee442a99 100644 (file)
@@ -263,6 +263,19 @@ class EnumMeta(type):
     def __repr__(cls):
         return "<enum %r>" % cls.__name__
 
+    def __setattr__(cls, name, value):
+        """Block attempts to reassign Enum members.
+
+        A simple assignment to the class namespace only changes one of the
+        several possible ways to get an Enum member from the Enum class,
+        resulting in an inconsistent Enumeration.
+
+        """
+        member_map = cls.__dict__.get('_member_map_', {})
+        if name in member_map:
+            raise AttributeError('Cannot reassign members.')
+        super().__setattr__(name, value)
+
     def _create_(cls, class_name, names=None, *, module=None, type=None):
         """Convenience method to create a new Enum class.
 
index 2a589f5a3b396483b4bb3e6746112d3dfff95db4..018e3fdab77f48a9999cae05b365e3068af7e53c 100644 (file)
@@ -152,6 +152,11 @@ class TestEnum(unittest.TestCase):
         with self.assertRaises(AttributeError):
             Season.SPRING.value = 2
 
+    def test_changing_member(self):
+        Season = self.Season
+        with self.assertRaises(AttributeError):
+            Season.WINTER = 'really cold'
+
     def test_invalid_names(self):
         with self.assertRaises(ValueError):
             class Wrong(Enum):