From: Miss Islington (bot) <31488909+miss-islington@users.noreply.github.com> Date: Sun, 17 Jul 2022 04:53:41 +0000 (-0700) Subject: gh-93910: [Enum] restore member.member restriction while keeping performance boost... X-Git-Tag: v3.11.0b5~65 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=30f28ac296e506b336e0ab56c41422a53c36d0c2;p=thirdparty%2FPython%2Fcpython.git gh-93910: [Enum] restore member.member restriction while keeping performance boost (GH-94913) (cherry picked from commit c20186c3972ff38577c4c5e32ca86748210983d2) Co-authored-by: Ethan Furman --- diff --git a/Lib/enum.py b/Lib/enum.py index e5971917cef4..b19d40cbc5ed 100644 --- a/Lib/enum.py +++ b/Lib/enum.py @@ -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(" 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. diff --git a/Lib/test/test_enum.py b/Lib/test/test_enum.py index f9a662746fb1..74f31bec50c4 100644 --- a/Lib/test/test_enum.py +++ b/Lib/test/test_enum.py @@ -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, " 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): #