Skip to content

Commit 0aaf841

Browse files
committed
Save version 1.0.0
Signed-off-by: Ihor Nehrutsa <Ihor.Nehrutsa@gmail.com>
1 parent 4ed3df9 commit 0aaf841

2 files changed

Lines changed: 304 additions & 0 deletions

File tree

python-stdlib/enum/enum_0.py

Lines changed: 212 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,212 @@
1+
# enum.py
2+
# version="1.0.0"
3+
4+
_Err = "no such attribute: "
5+
6+
7+
class int_value(int):
8+
@property
9+
def value(self) -> int:
10+
return self
11+
12+
def __call__(self) -> int:
13+
return self
14+
15+
16+
class str_value(str):
17+
@property
18+
def value(self) -> str:
19+
return self
20+
21+
def __call__(self) -> str:
22+
return self
23+
24+
25+
class bool_value(bool):
26+
@property
27+
def value(self) -> bool:
28+
return self
29+
30+
def __call__(self) -> bool:
31+
return self
32+
33+
34+
class float_value(float):
35+
@property
36+
def value(self) -> float:
37+
return self
38+
39+
def __call__(self) -> float:
40+
return self
41+
42+
43+
def get_class_value(value):
44+
if type(value) is int:
45+
return int_value(value)
46+
elif type(value) is bool:
47+
return bool_value(value)
48+
elif type(value) is float:
49+
return float_value(value)
50+
elif type(value) is str:
51+
return str_value(value)
52+
else:
53+
return value
54+
55+
56+
def enum(**kw_args): # `**kw_args` kept backwards compatible as in the Internet examples
57+
return Enum(kw_args)
58+
59+
60+
class Enum(dict):
61+
def __init__(self, arg=None): # `arg` is dict() compatible
62+
super().__init__()
63+
self._arg = None
64+
if not arg is None:
65+
self.append(arg)
66+
self._is_enums_from_class = False
67+
self._get_enums_from_class()
68+
69+
def _update(self, key, value):
70+
self.update({key: get_class_value(value)})
71+
72+
def append(self, arg=None, **kw_args):
73+
if len(kw_args):
74+
for key, value in kw_args.items():
75+
self._update(key, value)
76+
if type(arg) == type(dict()):
77+
for key, value in arg.items():
78+
self._update(key, value)
79+
else:
80+
self._arg = arg # for __str__()
81+
return self
82+
83+
def __repr__(self):
84+
d = self.copy()
85+
try:
86+
d.pop("_arg")
87+
except:
88+
pass
89+
return str(d)
90+
91+
def __str__(self):
92+
value = None
93+
try:
94+
value = self._arg
95+
except:
96+
pass
97+
if not value is None:
98+
if self.is_value(value):
99+
self._arg = None
100+
return value
101+
raise ValueError(_Err + f"{value}")
102+
return self.__qualname__ + "(" + self.__repr__() + ")"
103+
104+
def is_value(self, value):
105+
if value in self.values():
106+
return True
107+
return False
108+
109+
def key_from_value(self, value):
110+
for key in self:
111+
if self.get(key) == value:
112+
return self.__qualname__ + "." + key
113+
raise ValueError(_Err + f"{value}")
114+
115+
def __call__(self, value):
116+
if self.is_value(value):
117+
return value
118+
raise ValueError(_Err + f"{value}")
119+
120+
def __getattr__(self, key):
121+
try:
122+
if key in self:
123+
return self[key]
124+
else:
125+
raise KeyError(_Err + f"{key}")
126+
except:
127+
raise KeyError(_Err + f"{key}")
128+
129+
def __setattr__(self, key, value):
130+
if key == "_arg":
131+
self[key] = value
132+
return
133+
try:
134+
self[key] = get_class_value(value)
135+
except:
136+
raise KeyError(_Err + f"{key}")
137+
138+
def __delattr__(self, key):
139+
try:
140+
if key in self:
141+
del self[key]
142+
else:
143+
raise KeyError(_Err + f"{key}")
144+
except:
145+
raise KeyError(_Err + f"{key}")
146+
147+
def __len__(self):
148+
return len(tuple(self.keys()))
149+
150+
def __dir__(self):
151+
return dir(Enum)
152+
153+
def _get_enums_from_class(self):
154+
## Class XX(Enum):
155+
## X1 = 1
156+
## X2 = 2
157+
158+
if not self._is_enums_from_class:
159+
keys = dir(eval(self.__qualname__))
160+
161+
def try_remove(item):
162+
try:
163+
keys.remove(item)
164+
except:
165+
pass
166+
167+
for item in dir(dict):
168+
try_remove(item)
169+
170+
_list = [
171+
"__init__",
172+
"__class__init__",
173+
"__call__",
174+
"__Errases__",
175+
"__module__",
176+
"__qualname__",
177+
"__len__",
178+
"__lt__",
179+
"__le__",
180+
"__eq__",
181+
"__ne__",
182+
"__gt__",
183+
"__ge__",
184+
"__dir__",
185+
"__delattr__",
186+
"__getattr__",
187+
"__setattr__",
188+
"__str__",
189+
"__repr__",
190+
"_get_enums_from_class",
191+
"_arg",
192+
"_update",
193+
"is_value",
194+
"key_from_value",
195+
"append",
196+
]
197+
for item in _list:
198+
try_remove(item)
199+
module = ""
200+
if self.__module__ != "__main__":
201+
module = self.__module__ + "."
202+
for key in keys:
203+
try:
204+
value = eval(f"{module}{self.__qualname__}.{key}")
205+
except:
206+
value = eval(f"{self.__qualname__}.{key}")
207+
self._update(key, value)
208+
keys.clear()
209+
del keys
210+
self._is_enums_from_class = True # 1 !!!
211+
self.pop("_is_enums_from_class") # 2 !!!
212+
return self

python-stdlib/enum/test_enum_0.py

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
# test_enum.py
2+
# version="1.0.0"
3+
4+
from enum import Enum, enum
5+
6+
7+
class Direction(Enum):
8+
CW = "CW"
9+
CCW = "CCW"
10+
11+
12+
class State(Direction):
13+
Stop = 1
14+
Run = 2
15+
Ready = 3
16+
Disabled = False
17+
Enabled = True
18+
19+
20+
state = Enum()
21+
print(state)
22+
state = Direction()
23+
print(state)
24+
state = State()
25+
print(state)
26+
state = State({"X": 1.0, "Y": 2.0})
27+
print(state)
28+
state.Idle = 10
29+
state.Triggered = 20
30+
state.Lockout = 30
31+
print(state)
32+
33+
print("Direction(Direction.CCW):", Direction(Direction.CCW))
34+
print("Direction('CW'):", Direction("CW"))
35+
print("state(10):", state(10))
36+
37+
print("state('CW'):", state("CW"))
38+
print("type(state('CW')):", type(state("CW")))
39+
40+
print("state.key_from_value(20):", state.key_from_value(20))
41+
print("len(state):", len(state))
42+
43+
print("state.Idle:", state.Idle)
44+
print("type(state.Idle):", type(state.Idle))
45+
46+
current_state = state.Idle
47+
print("current_state:", current_state)
48+
if current_state == state.Idle:
49+
print(" Idle state")
50+
if current_state != state.Triggered:
51+
print(" Not a triggered state")
52+
current_state = state.Idle
53+
print("current_state:", current_state)
54+
print("state.key_from_value(current_state):", state.key_from_value(current_state))
55+
56+
state2 = eval(str(state))
57+
print(state2)
58+
print("state == state2:", state == state2)
59+
60+
del state.Triggered
61+
print(state)
62+
print("state == state2:", state == state2)
63+
64+
print("state.keys():", state.keys())
65+
print("state.values():", state.values())
66+
print("state.items():", state.items())
67+
68+
try:
69+
del state.stop
70+
except Exception as e:
71+
print("Exception:", e)
72+
73+
assert current_state == state.Idle
74+
assert current_state != state.Disabled
75+
assert state.Idle != state.Disabled
76+
print(
77+
"State(State.Ready):",
78+
State(State.Ready),
79+
"type(State.Ready):",
80+
type(State(State.Ready)),
81+
"type(State.Ready):",
82+
type(State.Ready),
83+
)
84+
assert int(str(State(State.Ready))) == State.Ready
85+
assert int(str(State(State.Ready))) != State.Disabled
86+
print("will raise exception")
87+
try:
88+
del state.Triggered
89+
except Exception as e:
90+
print("Exception:", e)
91+
92+
print("OK")

0 commit comments

Comments
 (0)