Skip to content

Instantly share code, notes, and snippets.

@ZechCodes
Last active September 20, 2023 15:04
Show Gist options
  • Save ZechCodes/487ddc09e50bbc1a2eab14e72cdd7a82 to your computer and use it in GitHub Desktop.
Save ZechCodes/487ddc09e50bbc1a2eab14e72cdd7a82 to your computer and use it in GitHub Desktop.
Experimenting with creating enums with auto values dynamically without having to assign `auto()`. This is a terrible idea and results in code that at times could be ambiguous. A fun excersize.
import inspect
from enum import Enum, auto, EnumType
class EnumCaptureDict(dict):
def __getitem__(self, item):
if item in self or (item.startswith("__") and item.endswith("__")):
return super().__getitem__(item)
frame = inspect.currentframe().f_back
if item in frame.f_back.f_locals:
return frame.f_back.f_locals[item]
if item in frame.f_globals:
return frame.f_globals[item]
if hasattr(frame.f_globals["__builtins__"], item):
return getattr(frame.f_globals["__builtins__"], item)
self[item] = auto()
return self[item]
class EnumMCS(EnumType):
@classmethod
def __prepare__(mcs, cls, bases):
d = super().__prepare__(cls, bases)
d.__class__ = type("EnumCaptureDict", (EnumCaptureDict, d.__class__), {})
return d
def test():
Bob = "BOBOB"
def wrapper():
nonlocal Bob
class Test(str, Enum, metaclass=EnumMCS):
@staticmethod
def _generate_next_value_(name, start, count, last_values):
return name
Bob = Bob
Alice
Charlie
return Test
return wrapper()
Test = test()
assert repr(Test.Bob) == "<Test.Bob: 'BOBOB'>"
assert repr(Test.Bob.value) == "'BOBOB'"
assert repr(Test.Alice) == "<Test.Alice: 'Alice'>"
assert repr(Test.Alice.value) == "'Alice'"
print("It works!")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment