[Python-checkins] gh-101541: [Enum] create flag psuedo-member without calling original __new__ (GH-101590)

ethanfurman webhook-mailer at python.org
Sun Feb 5 22:29:25 EST 2023


https://github.com/python/cpython/commit/ef7c2bfcf1fd618438f981ace64499a99ae9fae0
commit: ef7c2bfcf1fd618438f981ace64499a99ae9fae0
branch: main
author: Ethan Furman <ethan at stoneleaf.us>
committer: ethanfurman <ethan at stoneleaf.us>
date: 2023-02-05T19:29:06-08:00
summary:

gh-101541: [Enum] create flag psuedo-member without calling original __new__ (GH-101590)

files:
A Misc/NEWS.d/next/Library/2023-02-05-14-39-49.gh-issue-101541.Mo3ppp.rst
M Lib/enum.py
M Lib/test/test_enum.py

diff --git a/Lib/enum.py b/Lib/enum.py
index adb61519abe9..d14e91a9b017 100644
--- a/Lib/enum.py
+++ b/Lib/enum.py
@@ -1429,12 +1429,11 @@ def _missing_(cls, value):
                     % (cls.__name__, value, unknown, bin(unknown))
                     )
         # normal Flag?
-        __new__ = getattr(cls, '__new_member__', None)
-        if cls._member_type_ is object and not __new__:
+        if cls._member_type_ is object:
             # construct a singleton enum pseudo-member
             pseudo_member = object.__new__(cls)
         else:
-            pseudo_member = (__new__ or cls._member_type_.__new__)(cls, value)
+            pseudo_member = cls._member_type_.__new__(cls, value)
         if not hasattr(pseudo_member, '_value_'):
             pseudo_member._value_ = value
         if member_value:
diff --git a/Lib/test/test_enum.py b/Lib/test/test_enum.py
index 1e653e94f6b5..0a2e0c14d268 100644
--- a/Lib/test/test_enum.py
+++ b/Lib/test/test_enum.py
@@ -2855,6 +2855,46 @@ class NTEnum(Enum):
                 [TTuple(id=0, a=0, blist=[]), TTuple(id=1, a=2, blist=[4]), TTuple(id=2, a=4, blist=[0, 1, 2])],
                 )
 
+    def test_flag_with_custom_new(self):
+        class FlagFromChar(IntFlag):
+            def __new__(cls, c):
+                value = 1 << c
+                self = int.__new__(cls, value)
+                self._value_ = value
+                return self
+            #
+            a = ord('a')
+        #
+        self.assertEqual(FlagFromChar.a, 158456325028528675187087900672)
+        self.assertEqual(FlagFromChar.a|1, 158456325028528675187087900673)
+        #
+        #
+        class FlagFromChar(Flag):
+            def __new__(cls, c):
+                value = 1 << c
+                self = object.__new__(cls)
+                self._value_ = value
+                return self
+            #
+            a = ord('a')
+            z = 1
+        #
+        self.assertEqual(FlagFromChar.a.value, 158456325028528675187087900672)
+        self.assertEqual((FlagFromChar.a|FlagFromChar.z).value, 158456325028528675187087900674)
+        #
+        #
+        class FlagFromChar(int, Flag, boundary=KEEP):
+            def __new__(cls, c):
+                value = 1 << c
+                self = int.__new__(cls, value)
+                self._value_ = value
+                return self
+            #
+            a = ord('a')
+        #
+        self.assertEqual(FlagFromChar.a, 158456325028528675187087900672)
+        self.assertEqual(FlagFromChar.a|1, 158456325028528675187087900673)
+
 class TestOrder(unittest.TestCase):
     "test usage of the `_order_` attribute"
 
diff --git a/Misc/NEWS.d/next/Library/2023-02-05-14-39-49.gh-issue-101541.Mo3ppp.rst b/Misc/NEWS.d/next/Library/2023-02-05-14-39-49.gh-issue-101541.Mo3ppp.rst
new file mode 100644
index 000000000000..0f149e80dc54
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2023-02-05-14-39-49.gh-issue-101541.Mo3ppp.rst
@@ -0,0 +1 @@
+[Enum] - fix psuedo-flag creation



More information about the Python-checkins mailing list