kopia lustrzana https://github.com/micropython/micropython-lib
Merge 6ab2ebe906
into 6e24cffe95
commit
7a79648a32
|
@ -0,0 +1,211 @@
|
|||
# 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
|
|
@ -0,0 +1,3 @@
|
|||
metadata(version="1.0.0")
|
||||
|
||||
module("enum.py")
|
|
@ -0,0 +1,91 @@
|
|||
# enum_test.py
|
||||
|
||||
from enum import Enum, enum
|
||||
|
||||
|
||||
class Direction(Enum):
|
||||
CW = "CW"
|
||||
CCW = "CCW"
|
||||
|
||||
|
||||
class State(Direction):
|
||||
Stop = 1
|
||||
Run = 2
|
||||
Ready = 3
|
||||
Disabled = False
|
||||
Enabled = True
|
||||
|
||||
|
||||
state = Enum()
|
||||
print(state)
|
||||
state = Direction()
|
||||
print(state)
|
||||
state = State()
|
||||
print(state)
|
||||
state = State({"X": 1.0, "Y": 2.0})
|
||||
print(state)
|
||||
state.Idle = 10
|
||||
state.Triggered = 20
|
||||
state.Lockout = 30
|
||||
print(state)
|
||||
|
||||
print("Direction(Direction.CCW):", Direction(Direction.CCW))
|
||||
print("Direction('CW'):", Direction("CW"))
|
||||
print("state(10):", state(10))
|
||||
|
||||
print("state('CW'):", state("CW"))
|
||||
print("type(state('CW')):", type(state("CW")))
|
||||
|
||||
print("state.key_from_value(20):", state.key_from_value(20))
|
||||
print("len(state):", len(state))
|
||||
|
||||
print("state.Idle:", state.Idle)
|
||||
print("type(state.Idle):", type(state.Idle))
|
||||
|
||||
current_state = state.Idle
|
||||
print("current_state:", current_state)
|
||||
if current_state == state.Idle:
|
||||
print(" Idle state")
|
||||
if current_state != state.Triggered:
|
||||
print(" Not a triggered state")
|
||||
current_state = state.Idle
|
||||
print("current_state:", current_state)
|
||||
print("state.key_from_value(current_state):", state.key_from_value(current_state))
|
||||
|
||||
state2 = eval(str(state))
|
||||
print(state2)
|
||||
print("state == state2:", state == state2)
|
||||
|
||||
del state.Triggered
|
||||
print(state)
|
||||
print("state == state2:", state == state2)
|
||||
|
||||
print("state.keys():", state.keys())
|
||||
print("state.values():", state.values())
|
||||
print("state.items():", state.items())
|
||||
|
||||
try:
|
||||
del state.stop
|
||||
except Exception as e:
|
||||
print("Exception:", e)
|
||||
|
||||
assert current_state == state.Idle
|
||||
assert current_state != state.Disabled
|
||||
assert state.Idle != state.Disabled
|
||||
print(
|
||||
"State(State.Ready):",
|
||||
State(State.Ready),
|
||||
"type(State.Ready):",
|
||||
type(State(State.Ready)),
|
||||
"type(State.Ready):",
|
||||
type(State.Ready),
|
||||
)
|
||||
assert int(str(State(State.Ready))) == State.Ready
|
||||
assert int(str(State(State.Ready))) != State.Disabled
|
||||
print("will raise exception")
|
||||
try:
|
||||
del state.Triggered
|
||||
except Exception as e:
|
||||
print("Exception:", e)
|
||||
|
||||
print("OK")
|
|
@ -54,6 +54,7 @@ function ci_package_tests_run {
|
|||
python-stdlib/base64/test_base64.py \
|
||||
python-stdlib/binascii/test_binascii.py \
|
||||
python-stdlib/collections-defaultdict/test_defaultdict.py \
|
||||
python-stdlib/enum/test_enum.py \
|
||||
python-stdlib/functools/test_partial.py \
|
||||
python-stdlib/functools/test_reduce.py \
|
||||
python-stdlib/heapq/test_heapq.py \
|
||||
|
|
Ładowanie…
Reference in New Issue