AttrCtrl,Lockable: forbid relocking, perform additional check

This commit is contained in:
The MMGen Project 2021-08-10 19:38:20 +00:00
commit d7b0133bf4
Signed by: mmgen
GPG key ID: 3F8B1861E32B7DA2
2 changed files with 24 additions and 1 deletions

View file

@ -24,7 +24,7 @@ class AttrCtrlMeta(type):
def __call__(cls,*args,**kwargs):
instance = super().__call__(*args,**kwargs)
if instance._autolock:
instance._lock = True
instance.lock()
return instance
class AttrCtrl(metaclass=AttrCtrlMeta):
@ -45,7 +45,10 @@ class AttrCtrl(metaclass=AttrCtrlMeta):
self._lock = True
def __setattr__(self,name,value):
if self._lock:
assert name != '_lock', 'lock can be set only once'
def do_error(name,value,ref_val):
raise AttributeError(
f'{value!r}: invalid value for attribute {name!r}'
@ -84,6 +87,13 @@ class Lockable(AttrCtrl):
_set_ok = ()
_reset_ok = ()
def lock(self):
for name in ('_set_ok','_reset_ok'):
for attr in getattr(self,name):
assert hasattr(self,attr), (
f'attribute {attr!r} in {name!r} not found in {type(self).__name__} object {id(self)}' )
super().lock()
def __setattr__(self,name,value):
if self._lock and hasattr(self,name):
val = getattr(self,name)

View file

@ -16,6 +16,7 @@ class unit_test(object):
qmsg_r('Testing class AttrCtrl...')
class MyAttrCtrl(AttrCtrl):
_autolock = False
foo = 'fooval'
ac = MyAttrCtrl()
ac.lock()
@ -23,7 +24,11 @@ class unit_test(object):
ac.foo = 'new fooval'
ac.foo = 'new fooval2'
class MyAttrCtrlAutolock(AttrCtrl): pass
aca = MyAttrCtrlAutolock()
class MyAttrCtrlClsCheck(AttrCtrl):
_autolock = False
_use_class_attr = True
foo = 'fooval'
bar = None
@ -97,6 +102,10 @@ class unit_test(object):
assert lca._lock == True
assert lca.foo == True
class MyLockableBad(Lockable):
_set_ok = ('foo','bar')
foo = 1
qmsg('OK')
qmsg_r('Checking error handling...')
vmsg('')
@ -119,6 +128,8 @@ class unit_test(object):
def bad15(): lc.epsilon = [0]
def bad16(): lca.foo = None
def bad17(): lb = MyLockableBad()
def bad18(): aca.lock()
ut.process_bad_data((
('attr (1)', 'AttributeError', 'has no attr', bad1 ),
@ -137,6 +148,8 @@ class unit_test(object):
("attr (can't reset)", 'AttributeError', 'reset', bad14 ),
("attr (can't reset)", 'AttributeError', 'reset', bad15 ),
("attr (can't set)", 'AttributeError', 'read-only', bad16 ),
("attr (bad _set_ok)", 'AssertionError', 'not found in',bad17 ),
("call to lock()", 'AssertionError', 'only once', bad18 ),
))
qmsg('OK')