I have the following code, which works as expected on 3.9 and 3.10:
from enum import Enum
class Environment(Enum):
DEV = ()
INT = ()
PROD = ()
def __init__(self):
self._value_ = self.name.lower()
def __str__(self):
return self.name
def get_url(self):
if self is Environment.DEV:
return 'http://localhost'
else:
return f'https://{self.value}.my.domain'
Here is the result in a REPL:
>>> Environment.DEV.get_url()
'http://localhost'
>>> Environment.INT.get_url()
'https://int.my.domain'
>>> Environment.PROD.get_url()
'https://prod.my.domain'
I did this because I read that defining an __init__
method for enums allows passing tuples when assigning values, and I wanted to avoid the redundant/error prone explicit declarations such as:
DEV = 'DEV'
INT = 'INT'
PROD = 'PROD'
Now, when I run the same code on Python 3.11 or 3.12, every call to get_url
returns the localhost URL. Trying it out in the REPL, we get:
>>> Environment.DEV.get_url()
'http://localhost'
>>> Environment.INT.get_url()
'http://localhost'
>>> Environment.PROD.get_url()
'http://localhost'
I even noticed that all of the enum values are equal to the first one:
>>> Environment.DEV
<Environment.DEV: 'dev'>
>>> Environment.INT
<Environment.DEV: 'dev'>
>>> Environment.PROD
<Environment.DEV: 'dev'>
Has something changed in python 3.11 which makes using empty tuples at assignation forbidden/broken? How could I get the same result in those versions, i.e. declare the enum values without having to explicitly pass any argument to __init__
?
You could use
auto()
and_generate_next_value_
:This will automatically generate values based on the names.
Note that while
_generate_next_value_
is currently documented as a staticmethod, applying the staticmethod decorator is optional, and didn't work on previous versions - previous versions required a bare function.