From 174caeebd3398cc70f8e4acb57b224ca1220a964 Mon Sep 17 00:00:00 2001 From: MMGen Date: Sat, 19 Oct 2019 17:27:24 +0000 Subject: [PATCH] MMGenImmutableAttr: allow callable dtype arg, remove 'no_type_check' option --- mmgen/altcoins/eth/tw.py | 4 ++-- mmgen/main_autosign.py | 2 +- mmgen/obj.py | 14 ++++++++------ mmgen/tw.py | 4 ++-- mmgen/tx.py | 18 +----------------- test/objattrtest.py | 5 ++--- test/objattrtest_py_d/oat_common.py | 1 + 7 files changed, 17 insertions(+), 31 deletions(-) diff --git a/mmgen/altcoins/eth/tw.py b/mmgen/altcoins/eth/tw.py index 3937911c..c101394b 100755 --- a/mmgen/altcoins/eth/tw.py +++ b/mmgen/altcoins/eth/tw.py @@ -298,8 +298,8 @@ Actions: [q]uit view, [p]rint to file, pager [v]iew, [w]ide view, class MMGenTwUnspentOutput(MMGenListItem): txid = MMGenListItemAttr('txid','CoinTxID') vout = MMGenListItemAttr('vout',int,typeconv=False) - amt = MMGenImmutableAttr('amt',g.proto.coin_amt.__name__) - amt2 = MMGenListItemAttr('amt2',g.proto.coin_amt.__name__) + amt = MMGenImmutableAttr('amt',lambda:g.proto.coin_amt,typeconv=False) + amt2 = MMGenListItemAttr('amt2',lambda:g.proto.coin_amt,typeconv=False) label = MMGenListItemAttr('label','TwComment',reassign_ok=True) twmmid = MMGenImmutableAttr('twmmid','TwMMGenID') addr = MMGenImmutableAttr('addr','CoinAddr') diff --git a/mmgen/main_autosign.py b/mmgen/main_autosign.py index 48545989..df23ebae 100755 --- a/mmgen/main_autosign.py +++ b/mmgen/main_autosign.py @@ -278,7 +278,7 @@ def print_summary(signed_txs): msg(fs.format( tx.txid.fmt(width=t_wid,color=True) if nm is non_mmgen[0] else ' '*t_wid, nm.addr.fmt(width=a_wid,color=True), - nm._amt.hl() + ' ' + yellow(tx.coin))) + nm.amt.hl() + ' ' + yellow(tx.coin))) else: msg('No non-MMGen outputs') diff --git a/mmgen/obj.py b/mmgen/obj.py index 8bd3597d..d8bb1244 100755 --- a/mmgen/obj.py +++ b/mmgen/obj.py @@ -187,11 +187,12 @@ class Int(int,Hilite): pass # Reassignment and deletion forbidden class MMGenImmutableAttr(object): # Descriptor - def __init__(self,name,dtype,typeconv=True,no_type_check=False,set_none_ok=False): + ok_dtypes = (str,type,type(None),type(lambda:0)) + + def __init__(self,name,dtype,typeconv=True,set_none_ok=False): self.typeconv = typeconv - self.no_type_check = no_type_check self.set_none_ok = set_none_ok - assert isinstance(dtype,(str,type,type(None))),'{!r}: invalid dtype arg'.format(dtype) + assert isinstance(dtype,self.ok_dtypes),'{!r}: invalid dtype arg'.format(dtype) self.name = name self.dtype = dtype @@ -201,7 +202,6 @@ class MMGenImmutableAttr(object): # Descriptor # forbid all reassignment def set_attr_ok(self,instance): return not self.name in instance.__dict__ -# return not hasattr(instance,self.name) def __set__(self,instance,value): if not self.set_attr_ok(instance): @@ -212,8 +212,10 @@ class MMGenImmutableAttr(object): # Descriptor 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 or self.no_type_check: + 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: m = "Attribute '{}' of {} instance must of type {}" diff --git a/mmgen/tw.py b/mmgen/tw.py index d6fb3e7f..4486a16e 100755 --- a/mmgen/tw.py +++ b/mmgen/tw.py @@ -63,8 +63,8 @@ Actions: [q]uit view, [p]rint to file, pager [v]iew, [w]ide view, add [l]abel: class MMGenTwUnspentOutput(MMGenListItem): txid = MMGenListItemAttr('txid','CoinTxID') vout = MMGenListItemAttr('vout',int,typeconv=False) - amt = MMGenImmutableAttr('amt',g.proto.coin_amt.__name__) - amt2 = MMGenListItemAttr('amt2',g.proto.coin_amt.__name__) + amt = MMGenImmutableAttr('amt',lambda:g.proto.coin_amt,typeconv=False) + amt2 = MMGenListItemAttr('amt2',lambda:g.proto.coin_amt,typeconv=False) label = MMGenListItemAttr('label','TwComment',reassign_ok=True) twmmid = MMGenImmutableAttr('twmmid','TwMMGenID') addr = MMGenImmutableAttr('addr','CoinAddr') diff --git a/mmgen/tx.py b/mmgen/tx.py index c37b829e..ecdfbbef 100755 --- a/mmgen/tx.py +++ b/mmgen/tx.py @@ -220,7 +220,7 @@ class DeserializedTX(dict,MMGenObject): class MMGenTxIO(MMGenListItem): vout = MMGenListItemAttr('vout',int,typeconv=False) - _amt = MMGenImmutableAttr('amt',None,no_type_check=True,typeconv=False) + amt = MMGenImmutableAttr('amt',lambda:g.proto.coin_amt,typeconv=False) label = MMGenListItemAttr('label','TwComment',reassign_ok=True) mmid = MMGenListItemAttr('mmid','MMGenID') addr = MMGenImmutableAttr('addr','CoinAddr') @@ -228,22 +228,6 @@ class MMGenTxIO(MMGenListItem): txid = MMGenListItemAttr('txid','CoinTxID') have_wif = MMGenListItemAttr('have_wif',bool,typeconv=False,delete_ok=True) - valid_attrs_extra = {'amt'} - - # Setting self.amt is runtime-dependent, so make it a property - # Make underlying self._amt an MMGenImmutableAttr to prevent reassignment - @property - def amt(self): - if type(self._amt) != g.proto.coin_amt: - raise ValueError('{}: invalid coin_amt type (must be {})'.format(type(self._amt),g.proto.coin_amt)) - return self._amt - - @amt.setter - def amt(self,val): - if type(val) != g.proto.coin_amt: - raise ValueError('{}: invalid coin_amt type (must be {})'.format(type(val),g.proto.coin_amt)) - self._amt = val - class MMGenTxInput(MMGenTxIO): scriptPubKey = MMGenListItemAttr('scriptPubKey','HexStr') sequence = MMGenListItemAttr('sequence',int,typeconv=False) diff --git a/test/objattrtest.py b/test/objattrtest.py index 4971ddea..19ed19cb 100755 --- a/test/objattrtest.py +++ b/test/objattrtest.py @@ -51,8 +51,6 @@ opts_data = { } cmd_args = opts.init(opts_data) -init_coin(g.coin) -from mmgen.tw import * pd = namedtuple('permission_bits', ['read_ok','delete_ok','reassign_ok']) @@ -121,7 +119,7 @@ def test_attr(data,obj,attrname,dobj,bits,attrval_type): msg_r(' {}={!r}'.format(k,d[k])) if opt.show_nonstandard_init: - for k,v in (('typeconv',False),('no_type_check',True),('set_none_ok',True)): + for k,v in (('typeconv',False),('set_none_ok',True)): if d[k] == v: msg_r(' {}={}'.format(k,v)) @@ -161,4 +159,5 @@ def do_loop(): msg(clr('Testing {}'.format(obj))) test_object(test_data,obj) +init_coin(g.coin) do_loop() diff --git a/test/objattrtest_py_d/oat_common.py b/test/objattrtest_py_d/oat_common.py index 6023c15c..0d4a989d 100755 --- a/test/objattrtest_py_d/oat_common.py +++ b/test/objattrtest_py_d/oat_common.py @@ -15,6 +15,7 @@ from mmgen.seed import * from mmgen.protocol import * from mmgen.addr import * from mmgen.tx import * +from mmgen.tw import * from collections import namedtuple atd = namedtuple('attrtest_entry',['attrs','args','kwargs'])