]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-109022: [Enum] require `names=()` to create empty enum type (GH-109048)
authorEthan Furman <ethan@stoneleaf.us>
Fri, 8 Sep 2023 01:19:03 +0000 (18:19 -0700)
committerGitHub <noreply@github.com>
Fri, 8 Sep 2023 01:19:03 +0000 (18:19 -0700)
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=())

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 4b99e7bda2cca549d3a6e5c009e1912f9fc28038..994a7b9c73f9a71ce5c9d5aeac01e93db7a8429f 100644 (file)
@@ -730,6 +730,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 a838b93341a60856ed0bac3ac082bfb1a0bace17..8c1f285f7b3bc214cb00947de1eca911ca958f0e 100644 (file)
@@ -316,6 +316,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
@@ -382,10 +383,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
@@ -601,6 +600,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.