]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.12] gh-109022: [Enum] require `names=()` to create empty enum type (GH-109048...
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Tue, 12 Sep 2023 13:53:16 +0000 (06:53 -0700)
committerGitHub <noreply@github.com>
Tue, 12 Sep 2023 13:53:16 +0000 (15:53 +0200)
gh-109022: [Enum] require `names=()` to create empty enum type (GH-109048)

add guard so that ``Enum('bar')`` raises a TypeError instead of
creating a new enum class called `bar`.  To create the new but
empty class, use:

    huh = Enum('bar', names=())
(cherry picked from commit c74e440168fab9bf91346471087a394af13fa2db)

Co-authored-by: Ethan Furman <ethan@stoneleaf.us>
Lib/enum.py
Lib/test/test_enum.py
Misc/NEWS.d/next/Library/2023-09-06-19-33-41.gh-issue-108682.35Xnc5.rst [new file with mode: 0644]

index 9c0af9e56d8ee5e61510217f64fa60796d7d3054..c207dc234c0da26db6319f747fc5b63923b1ad36 100644 (file)
@@ -739,6 +739,11 @@ class EnumType(type):
                 value = (value, names) + values
             return cls.__new__(cls, value)
         # otherwise, functional API: we're creating a new Enum type
+        if names is None and type is None:
+            # no body? no data-type? possibly wrong usage
+            raise TypeError(
+                    f"{cls} has no members; specify `names=()` if you meant to create a new, empty, enum"
+                    )
         return cls._create_(
                 class_name=value,
                 names=names,
index dc60caccaa435c201bf0d0c31edc3f2809fe0158..14f16f7f26efc33c9790de08e2847fca3784b46f 100644 (file)
@@ -276,6 +276,7 @@ class _EnumTests:
                     return self.name.title()
                 def __format__(self, spec):
                     return ''.join(reversed(self.name))
+            self.NewBaseEnum = NewBaseEnum
             class NewSubEnum(NewBaseEnum):
                 first = auto()
             self.NewSubEnum = NewSubEnum
@@ -342,10 +343,8 @@ class _EnumTests:
                 return self.name.title()
             def __format__(self, spec):
                 return ''.join(reversed(self.name))
-            NewBaseEnum = self.enum_type('NewBaseEnum', dict(__format__=__format__, __str__=__str__))
-            class NewSubEnum(NewBaseEnum):
-                first = auto()
-            self.NewSubEnum = NewBaseEnum('NewSubEnum', 'first')
+            self.NewBaseEnum = self.enum_type('NewBaseEnum', dict(__format__=__format__, __str__=__str__))
+            self.NewSubEnum = self.NewBaseEnum('NewSubEnum', 'first')
             #
             def _generate_next_value_(name, start, last, values):
                 pass
@@ -561,6 +560,10 @@ class _EnumTests:
         self.assertTrue('description' not in dir(SubEnum))
         self.assertTrue('description' in dir(SubEnum.sample), dir(SubEnum.sample))
 
+    def test_empty_enum_has_no_values(self):
+        with self.assertRaisesRegex(TypeError, "<.... 'NewBaseEnum'> has no members"):
+            self.NewBaseEnum(7)
+
     def test_enum_in_enum_out(self):
         Main = self.MainEnum
         self.assertIs(Main(Main.first), Main.first)
diff --git a/Misc/NEWS.d/next/Library/2023-09-06-19-33-41.gh-issue-108682.35Xnc5.rst b/Misc/NEWS.d/next/Library/2023-09-06-19-33-41.gh-issue-108682.35Xnc5.rst
new file mode 100644 (file)
index 0000000..8c13d43
--- /dev/null
@@ -0,0 +1,2 @@
+Enum: require ``names=()`` or ``type=...`` to create an empty enum using
+the functional syntax.