Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[3.12] gh-109022: [Enum] require names=() to create empty enum type (GH-109048) #109122

Merged
merged 1 commit into from
Sep 12, 2023

Conversation

miss-islington
Copy link
Contributor

@miss-islington miss-islington commented Sep 8, 2023

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]

…ythonGH-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]>
@Yhg1s
Copy link
Member

Yhg1s commented Sep 8, 2023

I don't consider this a suitable change at this stage. (In fact, I wouldn't consider this a suitable change after beta 1). How is this not an API break? How can this be backward-compatible enough for a patch release?

If it really is backward-compatible enough to include in a patch release (which requires some convincing), does it need to go into 3.12.0, or can it be delayed to 3.12.1? If it needs to go into 3.12.0, we'll need a new release candidate.

@ethanfurman
Copy link
Member

Short answer: it's restoring 3.11 behavior.

Python 3.11.4+ (heads/3.11:0aa3b9d76c, Aug  8 2023, 10:35:56) [GCC 9.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from enum import Enum
>>> huh = Enum('bar')
Traceback (most recent call last):
  ...
ValueError: 'bar' is not a valid Enum
>>> huh = Enum('bar', names=())
>>> huh
<enum 'bar'>

Long answer:

When something like MyEnum(12) is executed, EnumType.__call__(cls, value, names, ...) is called and has to determine whether this is a value lookup on an already defined enum, or an attempt to create a new enum type.

In 3.11- this decision was based on whether names was populated (empty names --> value lookup). However, this led to confusing error messages when a value was a tuple:

from enum import Enum

class MyTupleEnum(Enum):
    first = 1, 10
>>> MyTupleEnum(1, 10)
Traceback (most recent call last):
  ...
TypeError: <enum 1> cannot extend <enum 'MyTupleEnum'>

Since enums with members cannot be further subclassed, a better check in EnumType.__call__ is whether the enum already has members, but that led to the current bug:

Python 3.12.0rc2+ (heads/3.12:fff524ede8, Sep  8 2023, 06:47:36) [GCC 9.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from enum import Enum
>>> Enum('bar')
<enum 'bar'>

The bug here is that it looks like a value lookup (and has been a value lookup since enum's inception), and it used to be an error, but now it is actually creating a new enum type.

In 3.11-, creating a new enum using the functional syntax required supplying names; in 3.12, the edge case is creating a new enum, but without members and without any new behavior, will work without supplying names -- and that's the bug.


Having said all that, it is an edge case, and can probably wait until 3.12.1.

@ethanfurman ethanfurman self-assigned this Sep 10, 2023
@ethanfurman
Copy link
Member

@Yhg1s, The reason this is not an API break is two-fold:

  • the error crept in with the last bug-fix in rc1;
  • names is still a positional-or-keyword argument -- I just show it in the keyword form because it's easier to read.

@Yhg1s
Copy link
Member

Yhg1s commented Sep 12, 2023

It's not exactly restoring 3.11 behaviour, since it raises a ValueError in 3.11, but I see it raised TypeError in earlier 3.12 pre-releases as well.

@Yhg1s Yhg1s merged commit ca848bb into python:3.12 Sep 12, 2023
@miss-islington miss-islington deleted the backport-c74e440-3.12 branch September 12, 2023 13:53
@ethanfurman
Copy link
Member

@Yhg1s, thanks for merging! And thanks for all your work (even if you hadn't merged) -- I appreciate your thoroughness.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type-bug An unexpected behavior, bug, or error
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants