From 7825a6021c460dbdbae36aea2d448481df301f46 Mon Sep 17 00:00:00 2001 From: The MMGen Project Date: Wed, 20 May 2020 11:09:42 +0000 Subject: [PATCH] ImmutableAttr: move conversion logic from __set__() to __init__() --- mmgen/altcoins/eth/tw.py | 4 ++-- mmgen/obj.py | 46 ++++++++++++++++++++++++---------------- mmgen/tw.py | 4 ++-- mmgen/tx.py | 2 +- 4 files changed, 33 insertions(+), 23 deletions(-) diff --git a/mmgen/altcoins/eth/tw.py b/mmgen/altcoins/eth/tw.py index 97dd80cd..ab5ab0fd 100755 --- a/mmgen/altcoins/eth/tw.py +++ b/mmgen/altcoins/eth/tw.py @@ -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') diff --git a/mmgen/obj.py b/mmgen/obj.py index 46971382..61c55bef 100755 --- a/mmgen/obj.py +++ b/mmgen/obj.py @@ -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): """ diff --git a/mmgen/tw.py b/mmgen/tw.py index 24f416f0..f53877e8 100755 --- a/mmgen/tw.py +++ b/mmgen/tw.py @@ -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') diff --git a/mmgen/tx.py b/mmgen/tx.py index dc4fb117..67222fbb 100755 --- a/mmgen/tx.py +++ b/mmgen/tx.py @@ -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')