summaryrefslogtreecommitdiff
path: root/game/python-extra/utils/enum.py
diff options
context:
space:
mode:
authorJesusaves <cpntb1@ymail.com>2020-12-09 13:32:01 -0300
committerJesusaves <cpntb1@ymail.com>2020-12-09 13:32:01 -0300
commit63afe4145f410a844c647d4e3f1059f568175c1e (patch)
tree15da6a890c78d73370f44f9fd5d59badfbbe60e4 /game/python-extra/utils/enum.py
downloadclient-63afe4145f410a844c647d4e3f1059f568175c1e.tar.gz
client-63afe4145f410a844c647d4e3f1059f568175c1e.tar.bz2
client-63afe4145f410a844c647d4e3f1059f568175c1e.tar.xz
client-63afe4145f410a844c647d4e3f1059f568175c1e.zip
Initial commit, forked from Spheresinit
Diffstat (limited to 'game/python-extra/utils/enum.py')
-rw-r--r--game/python-extra/utils/enum.py132
1 files changed, 132 insertions, 0 deletions
diff --git a/game/python-extra/utils/enum.py b/game/python-extra/utils/enum.py
new file mode 100644
index 0000000..8b145a4
--- /dev/null
+++ b/game/python-extra/utils/enum.py
@@ -0,0 +1,132 @@
+"""Who hasn't needed a good, old-fashioned enum now and then?"""
+
+
+class _enum(object):
+
+ def __call__(self, enum_name, *args, **kwargs):
+ if args and kwargs:
+ raise TypeError("enums can only be made from args XOR kwargs")
+
+ enum_items = {}
+
+ counter = 0
+ for name, val in kwargs.items():
+ if val is None:
+ val = counter
+ counter += 1
+ elif isinstance(val, int):
+ counter = val + 1
+
+ enum_items[name] = val
+
+ for val, name in enumerate(args, start=counter):
+ enum_items[name] = val
+
+ return type(enum_name, (Enum,), enum_items)
+
+ def from_iterable(self, iterable):
+ return self(*iterable)
+
+ def from_dict(self, dct):
+ return self(**dct)
+
+ def __iter__(self):
+ for k, v in self.__enum_items.items():
+ yield k, v
+
+ def __repr__(self):
+ return "<{}: {}>".format(self.__class__.__name__, self.__enum_items.values())
+enum = _enum()
+
+
+class EnumItem(object):
+
+ def __init__(self, parent, name, value):
+ self.__parent = parent
+ self.__name = name
+ self.__value = value
+
+ def __repr__(self):
+ return "<{}: {} [{}]>".format(self.__class__.__name__, self.name, self.value)
+
+ def __eq__(self, other):
+ if isinstance(other, self.__class__):
+ if self.parent.is_strict and self.parent != other.parent:
+ raise ValueError("can't compare EnumItems from different enums")
+ return self.value == other.value
+
+ return self.value == other
+
+ @property
+ def value(self):
+ return self.__value
+
+ @property
+ def name(self):
+ return self.__name
+
+ @property
+ def parent(self):
+ return self.__parent
+
+
+class _EnumMeta(type):
+ def __new__(cls, name, bases, attr_dict):
+
+ options = attr_dict.pop('Options', object)
+
+ attr_dict['__strict__'] = getattr(options, "strict_compare", True)
+
+ new_enum = super(_EnumMeta, cls).__new__(cls, name, bases, {})
+
+ enum_items = {}
+
+ for attr_name, attr_value in attr_dict.items():
+ if attr_name.startswith('__'):
+ super(_EnumMeta, cls).__setattr__(new_enum, attr_name, attr_value)
+ continue
+
+ if getattr(options, 'force_uppercase', False):
+ attr_dict.pop(attr_name)
+ attr_name = attr_name.upper()
+
+ enum_item = EnumItem(new_enum, attr_name, attr_value)
+
+ enum_items[attr_name] = enum_item
+ super(_EnumMeta, cls).__setattr__(new_enum, attr_name, enum_item)
+
+ if getattr(options, "frozen", True):
+ super(_EnumMeta, cls).__setattr__(new_enum, '__frozen__', True)
+ else:
+ super(_EnumMeta, cls).__setattr__(new_enum, '__frozen__', False)
+
+ if getattr(options, "strict", False):
+ super(_EnumMeta, cls).__setattr__(new_enum, '__strict__', True)
+ else:
+ super(_EnumMeta, cls).__setattr__(new_enum, '__strict__', False)
+
+ super(_EnumMeta, cls).__setattr__(new_enum, '__enum_item_map__', enum_items)
+
+ return new_enum
+
+ def __setattr__(cls, name, val):
+ if getattr(cls, "__frozen__", False):
+ raise TypeError("can't set attributes on a frozen enum")
+
+ if name in cls.__enum_item_map__:
+ val = EnumItem(cls, name, val)
+ cls.__enum_item_map__[name] = val
+
+ super(_EnumMeta, cls).__setattr__(name, val)
+
+ @property
+ def is_strict(cls):
+ return getattr(cls, "__strict__", True)
+
+ def get_name_value_map(cls):
+ e = cls.__enum_item_map__
+ return dict((e[i].name, e[i].value) for i in e)
+
+
+class Enum(_EnumMeta("EnumBase", (object, ), {})):
+ pass