summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEthan Furman <ethan@stoneleaf.us>2023-02-06 03:29:06 (GMT)
committerGitHub <noreply@github.com>2023-02-06 03:29:06 (GMT)
commitef7c2bfcf1fd618438f981ace64499a99ae9fae0 (patch)
treeb22306abe9e9df5cc05c3553894cd59d7b76a4a1
parentd3e2dd6e71bd8e5482973891926d5df19be687eb (diff)
downloadcpython-ef7c2bfcf1fd618438f981ace64499a99ae9fae0.zip
cpython-ef7c2bfcf1fd618438f981ace64499a99ae9fae0.tar.gz
cpython-ef7c2bfcf1fd618438f981ace64499a99ae9fae0.tar.bz2
gh-101541: [Enum] create flag psuedo-member without calling original __new__ (GH-101590)
-rw-r--r--Lib/enum.py5
-rw-r--r--Lib/test/test_enum.py40
-rw-r--r--Misc/NEWS.d/next/Library/2023-02-05-14-39-49.gh-issue-101541.Mo3ppp.rst1
3 files changed, 43 insertions, 3 deletions
diff --git a/Lib/enum.py b/Lib/enum.py
index adb6151..d14e91a 100644
--- a/Lib/enum.py
+++ b/Lib/enum.py
@@ -1429,12 +1429,11 @@ class Flag(Enum, boundary=CONFORM):
% (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 1e653e9..0a2e0c1 100644
--- a/Lib/test/test_enum.py
+++ b/Lib/test/test_enum.py
@@ -2855,6 +2855,46 @@ class TestSpecial(unittest.TestCase):
[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 0000000..0f149e8
--- /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