ImmutableAttr: move conversion logic from __set__() to __init__()

This commit is contained in:
The MMGen Project 2020-05-20 11:09:42 +00:00
commit 7825a6021c
Signed by: mmgen
GPG key ID: 3F8B1861E32B7DA2
4 changed files with 33 additions and 23 deletions

View file

@ -265,8 +265,8 @@ Actions: [q]uit view, [p]rint to file, pager [v]iew, [w]ide view,
class MMGenTwUnspentOutput(MMGenListItem):
txid = ListItemAttr('CoinTxID')
vout = ListItemAttr(int,typeconv=False)
amt = ImmutableAttr(lambda:g.proto.coin_amt,typeconv=False)
amt2 = ListItemAttr(lambda:g.proto.coin_amt,typeconv=False)
amt = ImmutableAttr(lambda val:g.proto.coin_amt(val),typeconv=False)
amt2 = ListItemAttr(lambda val:g.proto.coin_amt(val),typeconv=False)
label = ListItemAttr('TwComment',reassign_ok=True)
twmmid = ImmutableAttr('TwMMGenID')
addr = ImmutableAttr('CoinAddr')

View file

@ -231,10 +231,30 @@ class ImmutableAttr: # Descriptor
ok_dtypes = (str,type,type(None),type(lambda:0))
def __init__(self,dtype,typeconv=True,set_none_ok=False):
self.typeconv = typeconv
self.set_none_ok = set_none_ok
assert isinstance(dtype,self.ok_dtypes),'{!r}: invalid dtype arg'.format(dtype)
self.dtype = dtype
assert isinstance(dtype,self.ok_dtypes), 'ImmutableAttr_check1'
if set_none_ok: assert typeconv and type(dtype) != str, 'ImmutableAttr_check3'
if type(dtype).__name__ == 'function':
self.conv = lambda instance,value: dtype(value)
elif typeconv:
"convert this attribute's type"
if type(dtype) == str:
self.conv = lambda instance,value: globals()[dtype](value,on_fail='raise')
else:
if set_none_ok:
self.conv = lambda instance,value: None if value is None else dtype(value)
else:
self.conv = lambda instance,value: dtype(value)
else:
"check this attribute's type"
def assign_with_check(instance,value):
if type(value) == dtype:
return value
raise TypeError('Attribute {!r} of {} instance must of type {}'.format(
self.name,
type(instance).__name__,
dtype ))
self.conv = assign_with_check
def __set_name__(self,owner,name):
self.name = name
@ -248,22 +268,12 @@ class ImmutableAttr: # Descriptor
def __set__(self,instance,value):
if not self.setattr_condition(instance):
raise AttributeError('Attribute {self.name!r} of {type(instance)} instance cannot be reassigned')
if self.set_none_ok and value == None:
instance.__dict__[self.name] = None
elif self.typeconv: # convert type
instance.__dict__[self.name] = \
globals()[self.dtype](value,on_fail='raise') if type(self.dtype) == str else self.dtype(value)
else: # check type
if type(value) == self.dtype:
instance.__dict__[self.name] = value
elif callable(self.dtype) and type(value) == self.dtype():
instance.__dict__[self.name] = value
else:
raise TypeError('Attribute {self.name!r} of {type(instance)} instance must of type {self.dtype}')
raise AttributeError(f'Attribute {self.name!r} of {type(instance)} instance cannot be reassigned')
instance.__dict__[self.name] = self.conv(instance,value)
def __delete__(self,instance):
raise AttributeError('Attribute {self.name!r} of {type(instance)} instance cannot be deleted')
raise AttributeError(
f'Attribute {self.name!r} of {type(instance).__name__} instance cannot be deleted')
class ListItemAttr(ImmutableAttr):
"""

View file

@ -87,8 +87,8 @@ Actions: [q]uit view, [p]rint to file, pager [v]iew, [w]ide view, add [l]abel:
class MMGenTwUnspentOutput(MMGenListItem):
txid = ListItemAttr('CoinTxID')
vout = ListItemAttr(int,typeconv=False)
amt = ImmutableAttr(lambda:g.proto.coin_amt,typeconv=False)
amt2 = ListItemAttr(lambda:g.proto.coin_amt,typeconv=False)
amt = ImmutableAttr(lambda val:g.proto.coin_amt(val),typeconv=False)
amt2 = ListItemAttr(lambda val:g.proto.coin_amt(val),typeconv=False)
label = ListItemAttr('TwComment',reassign_ok=True)
twmmid = ImmutableAttr('TwMMGenID')
addr = ImmutableAttr('CoinAddr')

View file

@ -223,7 +223,7 @@ class DeserializedTX(dict,MMGenObject):
class MMGenTxIO(MMGenListItem):
vout = ListItemAttr(int,typeconv=False)
amt = ImmutableAttr(lambda:g.proto.coin_amt,typeconv=False)
amt = ImmutableAttr(lambda val:g.proto.coin_amt(val),typeconv=False)
label = ListItemAttr('TwComment',reassign_ok=True)
mmid = ListItemAttr('MMGenID')
addr = ImmutableAttr('CoinAddr')