Enum should use __class_getitem__
EnumMeta implements its own __getitem__ function which doesn't respect __class_getitem__. Now that __class_getitem__ exists, this behavior feels unintuitive. For instance ``` class Directions(enum.Enum): LEFT = "LEFT" RIGHT = "RIGHT" def __class_getitem__(cls, name): return super().__class_getitem__(name.upper()) # fails with KeyError -- __class_getitem__ never called assert Directions["left"] == Directions["LEFT"] == Directions.LEFT ``` doesn't work, and the only way to implement this behavior is something like ``` class MyEnumMeta(enum.EnumMeta): def __getitem__(cls, name): return cls.__class_getitem__(name) class MyEnum(enum.Enum, metaclass=MyEnumMeta): def __class_getitem__(cls, name): return cls._member_map_[name] class Directions(MyEnum): ... ``` there might be some compatibility issues with code written between 3.4 and 3.11, but not supporting __class_getitem__ feels like it violates the principle of least surprise with the more recent data models.
Although ENUMs are already complicated enough, this proposals frees up messing with the EnumMeta metaclass in some cases - it makes sense. I've subclassed EnumMeta once for adding some feature in a project, and it never feels the "quite right" thing to do. On Tue, Apr 26, 2022 at 6:12 PM Stefan Nelson-Lindall < stefan.nelsonlindall@gmail.com> wrote:
EnumMeta implements its own __getitem__ function which doesn't respect __class_getitem__. Now that __class_getitem__ exists, this behavior feels unintuitive. For instance
``` class Directions(enum.Enum): LEFT = "LEFT" RIGHT = "RIGHT"
def __class_getitem__(cls, name): return super().__class_getitem__(name.upper())
# fails with KeyError -- __class_getitem__ never called assert Directions["left"] == Directions["LEFT"] == Directions.LEFT ```
doesn't work, and the only way to implement this behavior is something like
``` class MyEnumMeta(enum.EnumMeta): def __getitem__(cls, name): return cls.__class_getitem__(name)
class MyEnum(enum.Enum, metaclass=MyEnumMeta): def __class_getitem__(cls, name): return cls._member_map_[name]
class Directions(MyEnum): ... ```
there might be some compatibility issues with code written between 3.4 and 3.11, but not supporting __class_getitem__ feels like it violates the principle of least surprise with the more recent data models. _______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/4VURZ4... Code of Conduct: http://python.org/psf/codeofconduct/
participants (2)
-
Joao S. O. Bueno
-
Stefan Nelson-Lindall