Skip to content

Commit

Permalink
[3.12] gh-109022: [Enum] require names=() to create empty enum type (
Browse files Browse the repository at this point in the history
…GH-109048) (#109122)

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 c74e440)

Co-authored-by: Ethan Furman <[email protected]>
  • Loading branch information
miss-islington and ethanfurman authored Sep 12, 2023
1 parent d533ab1 commit ca848bb
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 4 deletions.
5 changes: 5 additions & 0 deletions Lib/enum.py
Original file line number Diff line number Diff line change
Expand Up @@ -739,6 +739,11 @@ def __call__(cls, value, names=None, *values, module=None, qualname=None, type=N
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,
Expand Down
11 changes: 7 additions & 4 deletions Lib/test/test_enum.py
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,7 @@ def __str__(self):
return self.name.title()
def __format__(self, spec):
return ''.join(reversed(self.name))
self.NewBaseEnum = NewBaseEnum
class NewSubEnum(NewBaseEnum):
first = auto()
self.NewSubEnum = NewSubEnum
Expand Down Expand Up @@ -342,10 +343,8 @@ def __str__(self):
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
Expand Down Expand Up @@ -561,6 +560,10 @@ class SubEnum(SuperEnum):
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)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Enum: require ``names=()`` or ``type=...`` to create an empty enum using
the functional syntax.

0 comments on commit ca848bb

Please sign in to comment.