]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-92647: [Enum] use final status to determine lookup or create (GH-99500)
authorEthan Furman <ethan@stoneleaf.us>
Tue, 15 Nov 2022 16:49:22 +0000 (08:49 -0800)
committerGitHub <noreply@github.com>
Tue, 15 Nov 2022 16:49:22 +0000 (08:49 -0800)
* 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>
Lib/enum.py
Lib/test/test_enum.py
Misc/NEWS.d/next/Library/2022-11-15-04-08-25.gh-issue-92647.cZcjnJ.rst [new file with mode: 0644]

index a04aa7975366353b347655def97dbc08a9157364..1b683c702d59b4afc40d5381425cdb858637000b 100644 (file)
@@ -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,
index 9097a0936c0db7bb6a8583797f0b30eebff55014..fb3d5ad970fba5a628bf17e25f3d4ca4c75f5313 100644 (file)
@@ -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 (file)
index 0000000..c6e2a0c
--- /dev/null
@@ -0,0 +1 @@
+Use final status of an enum to determine lookup or creation branch of functional API.