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
0 commit comments