Last active
September 20, 2023 15:04
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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