kopia lustrzana https://github.com/micropython/micropython-lib
212 wiersze
5.4 KiB
Python
212 wiersze
5.4 KiB
Python
# enum.py
|
|
|
|
_Err = "no such attribute: "
|
|
|
|
|
|
class int_value(int):
|
|
@property
|
|
def value(self) -> int:
|
|
return self
|
|
|
|
def __call__(self) -> int:
|
|
return self
|
|
|
|
|
|
class str_value(str):
|
|
@property
|
|
def value(self) -> str:
|
|
return self
|
|
|
|
def __call__(self) -> str:
|
|
return self
|
|
|
|
|
|
class bool_value(bool):
|
|
@property
|
|
def value(self) -> bool:
|
|
return self
|
|
|
|
def __call__(self) -> bool:
|
|
return self
|
|
|
|
|
|
class float_value(float):
|
|
@property
|
|
def value(self) -> float:
|
|
return self
|
|
|
|
def __call__(self) -> float:
|
|
return self
|
|
|
|
|
|
def get_class_value(value):
|
|
if type(value) is int:
|
|
return int_value(value)
|
|
elif type(value) is bool:
|
|
return bool_value(value)
|
|
elif type(value) is float:
|
|
return float_value(value)
|
|
elif type(value) is str:
|
|
return str_value(value)
|
|
else:
|
|
return value
|
|
|
|
|
|
def enum(**kw_args): # `**kw_args` kept backwards compatible as in the Internet examples
|
|
return Enum(kw_args)
|
|
|
|
|
|
class Enum(dict):
|
|
def __init__(self, arg=None): # `arg` is dict() compatible
|
|
super().__init__()
|
|
self._arg = None
|
|
if not arg is None:
|
|
self.append(arg)
|
|
self._is_enums_from_class = False
|
|
self._get_enums_from_class()
|
|
|
|
def _update(self, key, value):
|
|
self.update({key: get_class_value(value)})
|
|
|
|
def append(self, arg=None, **kw_args):
|
|
if len(kw_args):
|
|
for key, value in kw_args.items():
|
|
self._update(key, value)
|
|
if type(arg) == type(dict()):
|
|
for key, value in arg.items():
|
|
self._update(key, value)
|
|
else:
|
|
self._arg = arg # for __str__()
|
|
return self
|
|
|
|
def __repr__(self):
|
|
d = self.copy()
|
|
try:
|
|
d.pop("_arg")
|
|
except:
|
|
pass
|
|
return str(d)
|
|
|
|
def __str__(self):
|
|
value = None
|
|
try:
|
|
value = self._arg
|
|
except:
|
|
pass
|
|
if not value is None:
|
|
if self.is_value(value):
|
|
self._arg = None
|
|
return value
|
|
raise ValueError(_Err + f"{value}")
|
|
return self.__qualname__ + "(" + self.__repr__() + ")"
|
|
|
|
def is_value(self, value):
|
|
if value in self.values():
|
|
return True
|
|
return False
|
|
|
|
def key_from_value(self, value):
|
|
for key in self:
|
|
if self.get(key) == value:
|
|
return self.__qualname__ + "." + key
|
|
raise ValueError(_Err + f"{value}")
|
|
|
|
def __call__(self, value):
|
|
if self.is_value(value):
|
|
return value
|
|
raise ValueError(_Err + f"{value}")
|
|
|
|
def __getattr__(self, key):
|
|
try:
|
|
if key in self:
|
|
return self[key]
|
|
else:
|
|
raise KeyError(_Err + f"{key}")
|
|
except:
|
|
raise KeyError(_Err + f"{key}")
|
|
|
|
def __setattr__(self, key, value):
|
|
if key == "_arg":
|
|
self[key] = value
|
|
return
|
|
try:
|
|
self[key] = get_class_value(value)
|
|
except:
|
|
raise KeyError(_Err + f"{key}")
|
|
|
|
def __delattr__(self, key):
|
|
try:
|
|
if key in self:
|
|
del self[key]
|
|
else:
|
|
raise KeyError(_Err + f"{key}")
|
|
except:
|
|
raise KeyError(_Err + f"{key}")
|
|
|
|
def __len__(self):
|
|
return len(tuple(self.keys()))
|
|
|
|
def __dir__(self):
|
|
return dir(Enum)
|
|
|
|
def _get_enums_from_class(self):
|
|
## Class XX(Enum):
|
|
## X1 = 1
|
|
## X2 = 2
|
|
|
|
if not self._is_enums_from_class:
|
|
keys = dir(eval(self.__qualname__))
|
|
|
|
def try_remove(item):
|
|
try:
|
|
keys.remove(item)
|
|
except:
|
|
pass
|
|
|
|
for item in dir(dict):
|
|
try_remove(item)
|
|
|
|
_list = [
|
|
"__init__",
|
|
"__class__init__",
|
|
"__call__",
|
|
"__Errases__",
|
|
"__module__",
|
|
"__qualname__",
|
|
"__len__",
|
|
"__lt__",
|
|
"__le__",
|
|
"__eq__",
|
|
"__ne__",
|
|
"__gt__",
|
|
"__ge__",
|
|
"__dir__",
|
|
"__delattr__",
|
|
"__getattr__",
|
|
"__setattr__",
|
|
"__str__",
|
|
"__repr__",
|
|
"_get_enums_from_class",
|
|
"_arg",
|
|
"_update",
|
|
"is_value",
|
|
"key_from_value",
|
|
"append",
|
|
]
|
|
for item in _list:
|
|
try_remove(item)
|
|
module = ""
|
|
if self.__module__ != "__main__":
|
|
module = self.__module__ + "."
|
|
for key in keys:
|
|
try:
|
|
value = eval(f"{module}{self.__qualname__}.{key}")
|
|
except:
|
|
value = eval(f"{self.__qualname__}.{key}")
|
|
self._update(key, value)
|
|
keys.clear()
|
|
del keys
|
|
self._is_enums_from_class = True # 1 !!!
|
|
self.pop("_is_enums_from_class") # 2 !!!
|
|
return self
|