From cf8973c63882980ef77043a5bcfefbb75d8de35c Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Sun, 5 Feb 2023 19:52:22 -0800 Subject: gh-101541: [Enum] create flag psuedo-member without calling original __new__ (GH-101590) (cherry picked from commit ef7c2bfcf1fd618438f981ace64499a99ae9fae0) Co-authored-by: Ethan Furman --- Lib/enum.py | 5 ++- Lib/test/test_enum.py | 40 ++++++++++++++++++++++ .../2023-02-05-14-39-49.gh-issue-101541.Mo3ppp.rst | 1 + 3 files changed, 43 insertions(+), 3 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2023-02-05-14-39-49.gh-issue-101541.Mo3ppp.rst diff --git a/Lib/enum.py b/Lib/enum.py index 7ad599b..5cff417 100644 --- a/Lib/enum.py +++ b/Lib/enum.py @@ -1430,12 +1430,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 0e2da1d..0143e85 100644 --- a/Lib/test/test_enum.py +++ b/Lib/test/test_enum.py @@ -2741,6 +2741,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 -- cgit v0.12