]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-93910: [Enum] restore member.member restriction while keeping performance boost...
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Sun, 17 Jul 2022 04:53:41 +0000 (21:53 -0700)
committerGitHub <noreply@github.com>
Sun, 17 Jul 2022 04:53:41 +0000 (21:53 -0700)
(cherry picked from commit c20186c3972ff38577c4c5e32ca86748210983d2)

Co-authored-by: Ethan Furman <ethan@stoneleaf.us>
Lib/enum.py
Lib/test/test_enum.py

index e5971917cef46be289b2959194eb1606bb279ac7..b19d40cbc5ed9b57ca9c3624a9dd8720879445b3 100644 (file)
@@ -1114,6 +1114,14 @@ class Enum(metaclass=EnumType):
     def __init__(self, *args, **kwds):
         pass
 
+    def __getattribute__(self, name):
+        self_dict = super().__getattribute__('__dict__')
+        cls = super().__getattribute__('__class__')
+        value = super().__getattribute__(name)
+        if isinstance(value, cls) and name not in self_dict and name in self._member_names_:
+            raise AttributeError("<enum '%s'> member has no attribute %r" % (cls.__name__, name))
+        return super().__getattribute__(name)
+
     def _generate_next_value_(name, start, count, last_values):
         """
         Generate the next value when not given.
index f9a662746fb1a0d27fd6423d5910816867527c47..74f31bec50c4f78de0f15d5d7a0b468d9e167e57 100644 (file)
@@ -2611,7 +2611,6 @@ class TestSpecial(unittest.TestCase):
         self.assertEqual(Private._Private__corporal, 'Radar')
         self.assertEqual(Private._Private__major_, 'Hoolihan')
 
-    @unittest.skip("Accessing all values retained for performance reasons, see GH-93910")
     def test_exception_for_member_from_member_access(self):
         with self.assertRaisesRegex(AttributeError, "<enum .Di.> member has no attribute .NO."):
             class Di(Enum):
@@ -2619,6 +2618,12 @@ class TestSpecial(unittest.TestCase):
                 NO = 0
             nope = Di.YES.NO
 
+    def test_no_exception_for_overridden_member_from_member_access(self):
+        class Di(Enum):
+            YES = 1
+            NO = 0
+        Di.YES.NO = Di.NO
+        nope = Di.YES.NO
 
     def test_dynamic_members_with_static_methods(self):
         #