Skip to content

Instantly share code, notes, and snippets.

@datavudeja
Forked from schwehr/explore_enum.py
Created February 4, 2026 15:41
Show Gist options
  • Select an option

  • Save datavudeja/13375d3ea8cc3f6cc5ae3b1a9a0621ae to your computer and use it in GitHub Desktop.

Select an option

Save datavudeja/13375d3ea8cc3f6cc5ae3b1a9a0621ae to your computer and use it in GitHub Desktop.
exploring enums in python
#!/usr/bin/env python3
"""Exploring python enum."""
import enum
# from typing import Sequence
class Simple(enum.Enum):
A = 'a'
B = 'b'
print(type(Simple)) # <class 'enum.EnumMeta'>
print(type(Simple.A)) # <enum 'Simple'>
print(type(Simple.A.value)) # <class 'str'>
print(Simple.B) # Simple.B
print(Simple.B.value) # b
print(Simple.B.name) # B
a = Simple.A
b = Simple.B
print(a == b) # Falsse
print(a != b) # True
print(Simple.A == 'a') # False
print(Simple.A == 'b') # False
print(Simple.A != 'a') # True
print(Simple.A != 'b') # True
# TypeError: '>' not supported between instances of 'Simple' and 'Simple'
# print(a > b)
# print(a < b)
print(str(b)) # Simple.B
print(repr(b)) # <Simple.B: 'b'>
# int, float, and str
class Messy(enum.Enum):
A = 'a'
B = 2
C = 3.4
D = 2
# ValueError: duplicate values found in <enum 'Messy'>: D -> B
# @enum.unique
# class Messy(enum.Enum):
# A = 'a'
# B = 2
# C = 3.4
# D = 2
class Auto(enum.Enum):
A = enum.auto()
B = enum.auto()
print('\nAuto:')
print(type(Auto)) # <class 'enum.EnumMeta'>
print(type(Auto.A)) # <enum 'Auto'>
print(type(Auto.A.value)) # <class 'int'>
print(Auto.B) # Auto.B
print(Auto.B.value) # 2
# TypeError: Attempted to reuse key: 'B'
# @enum.unique
# class AnIntEnum(enum.IntEnum):
# A = 1
# B = 2
# B = 1
# ValueError: invalid literal for int() with base 10: 'c'
# class AnIntEnum(enum.IntEnum):
# A = 1
# B = 2
# C = 'c'
class AnIntEnum(enum.IntEnum):
A = 1
B = 2
print(type(AnIntEnum)) # <class 'enum.EnumMeta'>
print(type(AnIntEnum.A)) # <enum 'AnIntEnum'>
print(type(AnIntEnum.A.value)) # <class 'int'>
print(AnIntEnum.B) # AnIntEnum.B
print(AnIntEnum.B.value) # 2
print(AnIntEnum.B.name) # B
a = AnIntEnum.A
b = AnIntEnum.B
print(a == b) # Falsse
print(a != b) # True
print(AnIntEnum.A == 'a') # False
print(AnIntEnum.A == 'b') # False
print(AnIntEnum.A != 'a') # True
print(AnIntEnum.A != 'b') # True
# TypeError: '>' not supported between instances of 'AnIntEnum' and 'AnIntEnum'
# print(a > b)
# print(a < b)
print(str(b)) # AnIntEnum.B
print(repr(b)) # <AnIntEnum.B: 2>
# Surprise... this does not raise a ValueError
class AStrEnum(str, enum.Enum):
A = 'a'
B = 2 # 2 gets turned into a str
print(type(AStrEnum)) # <class 'enum.EnumMeta'>
print(type(AStrEnum.B)) # <enum 'AStrEnum'>
print(type(AStrEnum.B.value)) # <class 'str'> <------ Yuck!
# https://github.com/python/cpython/blob/353e3b2820bed38da16140276786eef9ba33d3bd/Lib/enum.py
class ReprEnum(enum.Enum):
"""Only changes repr(), leaving str() and format() to the mixed-in type."""
class StrEnum(str, ReprEnum):
"""Enum where members are also (and must be) strings."""
def __new__(cls, *values):
"""Values must already be of type `str`."""
if len(values) > 3:
raise TypeError('too many arguments for str(): %r' % (values,))
if len(values) == 1:
# it must be a string
if not isinstance(values[0], str):
raise TypeError('%r is not a string' % (values[0],))
if len(values) >= 2:
# check that encoding argument is a string
if not isinstance(values[1], str):
raise TypeError('encoding must be a string, not %r' % (values[1],))
if len(values) == 3:
# check that errors argument is a string
if not isinstance(values[2], str):
raise TypeError('errors must be a string, not %r' % (values[2]))
value = str(*values)
member = str.__new__(cls, value)
member._value_ = value
return member
def _generate_next_value_(self, start, count, last_values):
"""Return the lower-cased version of the member name."""
return self.lower()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment