-
-
Notifications
You must be signed in to change notification settings - Fork 33.2k
Description
When using an Enum with auto()
to generate sequential integer values, introducing a member with a non-auto()
type (like a str
) causes unexpected behavior. Specifically, if a non-auto()
member is inserted after the first few auto()
members or between them, accessing any members defined with auto()
after this insertion consistently returns the value of the third Enum member, regardless of the actual member being accessed.
Example of good behavior
When all Enum members use auto()
, they each receive a unique integer value:
from enum import Enum, auto
class SOME_CLS_A(Enum):
a = auto()
b = auto()
c = auto()
d = auto()
e = auto()
f = auto()
print(SOME_CLS_A.a) # <SOME_CLS_A.a: 1>
print(SOME_CLS_A.b) # <SOME_CLS_A.b: 2>
print(SOME_CLS_A.c) # <SOME_CLS_A.c: 3>
print(SOME_CLS_A.d) # <SOME_CLS_A.d: 4>
print(SOME_CLS_A.e) # <SOME_CLS_A.e: 5>
print(SOME_CLS_A.f) # <SOME_CLS_A.f: 6>
As we can see we're getting the values as expected!
Example of bad behavior
from enum import Enum, auto
class SOME_CLS_B(Enum):
a = auto()
b = "other type than int or auto"
c = auto()
d = auto()
e = auto()
f = auto()
print(SOME_CLS_B.a) # <SOME_CLS_B.a: 1>
print(SOME_CLS_B.b) # <SOME_CLS_B.b: 'other type than int or auto'>
print(SOME_CLS_B.c) # <SOME_CLS_B.c: 2>
print(SOME_CLS_B.d) # <SOME_CLS_B.c: 2>
print(SOME_CLS_B.e) # <SOME_CLS_B.c: 2>
print(SOME_CLS_B.f) # <SOME_CLS_B.c: 2>
In this example, all Enum members from c
to f
unexpectedly refer to the value assigned to SOME_CLS_B.c
instead of receiving new, sequential values. This behavior demonstrates the issue when a non-auto()
entry is included in the enum.
Example of python3.10 execution of the same "issue" (And it's should be the fix and behave like that):
from enum import Enum, auto
class SOME_CLS_B(Enum):
a = auto()
b = "other type than int or auto"
c = auto()
d = auto()
e = auto()
f = auto()
# Testing outputs
print(SOME_CLS_B.a) # <SOME_CLS_B.a: 1>
print(SOME_CLS_B.b) # <SOME_CLS_B.b: 'other type than int or auto'>
print(SOME_CLS_B.c) # <SOME_CLS_B.c: 2>
print(SOME_CLS_B.d) # <SOME_CLS_B.d: 3>
print(SOME_CLS_B.e) # <SOME_CLS_B.e: 4>
print(SOME_CLS_B.f) # <SOME_CLS_B.f: 5>
CPython versions tested on:
3.11, 3.12, 3.13
Operating systems tested on:
Linux, Windows