Skip to content

Commit

Permalink
pythongh-101541: [Enum] create flag psuedo-member without calling ori…
Browse files Browse the repository at this point in the history
…ginal __new__ (pythonGH-101590)
  • Loading branch information
ethanfurman authored Feb 6, 2023
1 parent d3e2dd6 commit ef7c2bf
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 3 deletions.
5 changes: 2 additions & 3 deletions Lib/enum.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
40 changes: 40 additions & 0 deletions Lib/test/test_enum.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[Enum] - fix psuedo-flag creation

0 comments on commit ef7c2bf

Please sign in to comment.