diff options
-rw-r--r-- | Lib/enum.py | 13 | ||||
-rw-r--r-- | Lib/test/test_enum.py | 21 | ||||
-rw-r--r-- | Misc/NEWS.d/next/Library/2022-11-15-04-08-25.gh-issue-92647.cZcjnJ.rst | 1 |
3 files changed, 28 insertions, 7 deletions
diff --git a/Lib/enum.py b/Lib/enum.py index a04aa79..1b683c7 100644 --- a/Lib/enum.py +++ b/Lib/enum.py @@ -692,7 +692,7 @@ class EnumType(type): """ return True - def __call__(cls, value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None): + def __call__(cls, value, names=None, *values, module=None, qualname=None, type=None, start=1, boundary=None): """ Either returns an existing member, or creates a new enum class. @@ -700,6 +700,8 @@ class EnumType(type): to an enumeration member (i.e. Color(3)) and for the functional API (i.e. Color = Enum('Color', names='RED GREEN BLUE')). + The value lookup branch is chosen if the enum is final. + When used for the functional API: `value` will be the name of the new class. @@ -717,12 +719,15 @@ class EnumType(type): `type`, if set, will be mixed in as the first base class. """ - if names is None: # simple value lookup + if cls._member_map_: + # simple value lookup if members exist + if names: + value = (value, names) + values return cls.__new__(cls, value) # otherwise, functional API: we're creating a new Enum type return cls._create_( - value, - names, + class_name=value, + names=names, module=module, qualname=qualname, type=type, diff --git a/Lib/test/test_enum.py b/Lib/test/test_enum.py index 9097a09..fb3d5ad 100644 --- a/Lib/test/test_enum.py +++ b/Lib/test/test_enum.py @@ -1321,6 +1321,21 @@ class TestSpecial(unittest.TestCase): self.assertIn(e, MinorEnum) self.assertIs(type(e), MinorEnum) + def test_programmatic_function_is_value_call(self): + class TwoPart(Enum): + ONE = 1, 1.0 + TWO = 2, 2.0 + THREE = 3, 3.0 + self.assertRaisesRegex(ValueError, '1 is not a valid .*TwoPart', TwoPart, 1) + self.assertIs(TwoPart((1, 1.0)), TwoPart.ONE) + self.assertIs(TwoPart(1, 1.0), TwoPart.ONE) + class ThreePart(Enum): + ONE = 1, 1.0, 'one' + TWO = 2, 2.0, 'two' + THREE = 3, 3.0, 'three' + self.assertIs(ThreePart((3, 3.0, 'three')), ThreePart.THREE) + self.assertIs(ThreePart(3, 3.0, 'three'), ThreePart.THREE) + def test_intenum_from_bytes(self): self.assertIs(IntStooges.from_bytes(b'\x00\x03', 'big'), IntStooges.MOE) with self.assertRaises(ValueError): @@ -1463,7 +1478,7 @@ class TestSpecial(unittest.TestCase): class EvenMoreColor(Color, IntEnum): chartruese = 7 # - with self.assertRaisesRegex(TypeError, "<enum .Foo.> cannot extend <enum .Color.>"): + with self.assertRaisesRegex(ValueError, "\(.Foo., \(.pink., .black.\)\) is not a valid .*Color"): Color('Foo', ('pink', 'black')) def test_exclude_methods(self): @@ -4181,7 +4196,7 @@ expected_help_output_with_docs = """\ Help on class Color in module %s: class Color(enum.Enum) - | Color(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None) + | Color(value, names=None, *values, module=None, qualname=None, type=None, start=1, boundary=None) | | Method resolution order: | Color @@ -4237,7 +4252,7 @@ expected_help_output_without_docs = """\ Help on class Color in module %s: class Color(enum.Enum) - | Color(value, names=None, *, module=None, qualname=None, type=None, start=1) + | Color(value, names=None, *values, module=None, qualname=None, type=None, start=1) | | Method resolution order: | Color diff --git a/Misc/NEWS.d/next/Library/2022-11-15-04-08-25.gh-issue-92647.cZcjnJ.rst b/Misc/NEWS.d/next/Library/2022-11-15-04-08-25.gh-issue-92647.cZcjnJ.rst new file mode 100644 index 0000000..c6e2a0c --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-11-15-04-08-25.gh-issue-92647.cZcjnJ.rst @@ -0,0 +1 @@ +Use final status of an enum to determine lookup or creation branch of functional API. |