Skip to content

Commit 65dab15

Browse files
gh-92647: [Enum] use final status to determine lookup or create (GH-99500)
* use final status to determine lookup or create * 📜🤖 Added by blurb_it. Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com>
1 parent 3c57971 commit 65dab15

File tree

3 files changed

+28
-7
lines changed

3 files changed

+28
-7
lines changed

Lib/enum.py

+9-4
Original file line numberDiff line numberDiff line change
@@ -692,14 +692,16 @@ def __bool__(cls):
692692
"""
693693
return True
694694

695-
def __call__(cls, value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None):
695+
def __call__(cls, value, names=None, *values, module=None, qualname=None, type=None, start=1, boundary=None):
696696
"""
697697
Either returns an existing member, or creates a new enum class.
698698
699699
This method is used both when an enum class is given a value to match
700700
to an enumeration member (i.e. Color(3)) and for the functional API
701701
(i.e. Color = Enum('Color', names='RED GREEN BLUE')).
702702
703+
The value lookup branch is chosen if the enum is final.
704+
703705
When used for the functional API:
704706
705707
`value` will be the name of the new class.
@@ -717,12 +719,15 @@ def __call__(cls, value, names=None, *, module=None, qualname=None, type=None, s
717719
718720
`type`, if set, will be mixed in as the first base class.
719721
"""
720-
if names is None: # simple value lookup
722+
if cls._member_map_:
723+
# simple value lookup if members exist
724+
if names:
725+
value = (value, names) + values
721726
return cls.__new__(cls, value)
722727
# otherwise, functional API: we're creating a new Enum type
723728
return cls._create_(
724-
value,
725-
names,
729+
class_name=value,
730+
names=names,
726731
module=module,
727732
qualname=qualname,
728733
type=type,

Lib/test/test_enum.py

+18-3
Original file line numberDiff line numberDiff line change
@@ -1321,6 +1321,21 @@ def test_programmatic_function_type_from_subclass_with_start(self):
13211321
self.assertIn(e, MinorEnum)
13221322
self.assertIs(type(e), MinorEnum)
13231323

1324+
def test_programmatic_function_is_value_call(self):
1325+
class TwoPart(Enum):
1326+
ONE = 1, 1.0
1327+
TWO = 2, 2.0
1328+
THREE = 3, 3.0
1329+
self.assertRaisesRegex(ValueError, '1 is not a valid .*TwoPart', TwoPart, 1)
1330+
self.assertIs(TwoPart((1, 1.0)), TwoPart.ONE)
1331+
self.assertIs(TwoPart(1, 1.0), TwoPart.ONE)
1332+
class ThreePart(Enum):
1333+
ONE = 1, 1.0, 'one'
1334+
TWO = 2, 2.0, 'two'
1335+
THREE = 3, 3.0, 'three'
1336+
self.assertIs(ThreePart((3, 3.0, 'three')), ThreePart.THREE)
1337+
self.assertIs(ThreePart(3, 3.0, 'three'), ThreePart.THREE)
1338+
13241339
def test_intenum_from_bytes(self):
13251340
self.assertIs(IntStooges.from_bytes(b'\x00\x03', 'big'), IntStooges.MOE)
13261341
with self.assertRaises(ValueError):
@@ -1463,7 +1478,7 @@ class MoreColor(Color):
14631478
class EvenMoreColor(Color, IntEnum):
14641479
chartruese = 7
14651480
#
1466-
with self.assertRaisesRegex(TypeError, "<enum .Foo.> cannot extend <enum .Color.>"):
1481+
with self.assertRaisesRegex(ValueError, "\(.Foo., \(.pink., .black.\)\) is not a valid .*Color"):
14671482
Color('Foo', ('pink', 'black'))
14681483

14691484
def test_exclude_methods(self):
@@ -4181,7 +4196,7 @@ class TestEnumTypeSubclassing(unittest.TestCase):
41814196
Help on class Color in module %s:
41824197
41834198
class Color(enum.Enum)
4184-
| Color(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)
4199+
| Color(value, names=None, *values, module=None, qualname=None, type=None, start=1, boundary=None)
41854200
|
41864201
| Method resolution order:
41874202
| Color
@@ -4237,7 +4252,7 @@ class Color(enum.Enum)
42374252
Help on class Color in module %s:
42384253
42394254
class Color(enum.Enum)
4240-
| Color(value, names=None, *, module=None, qualname=None, type=None, start=1)
4255+
| Color(value, names=None, *values, module=None, qualname=None, type=None, start=1)
42414256
|
42424257
| Method resolution order:
42434258
| Color
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Use final status of an enum to determine lookup or creation branch of functional API.

0 commit comments

Comments
 (0)