From a7b11f1d3bbec7f281681df4ce36f03da5904414 Mon Sep 17 00:00:00 2001 From: The MMGen Project Date: Sat, 12 Nov 2022 13:34:40 +0000 Subject: [PATCH] move TwMMGenID, TwLabel, get_tw_label() to tw.shared --- mmgen/addrdata.py | 2 +- mmgen/main_addrimport.py | 2 +- mmgen/proto/btc/tw/addresses.py | 4 +- mmgen/proto/btc/tw/bal.py | 2 +- mmgen/proto/btc/tw/common.py | 2 +- mmgen/proto/btc/tw/json.py | 2 +- mmgen/proto/btc/tw/txhistory.py | 2 +- mmgen/proto/eth/tw/common.py | 2 +- mmgen/proto/eth/tw/json.py | 2 +- mmgen/proto/eth/tw/unspent.py | 2 +- mmgen/tw/addresses.py | 3 +- mmgen/tw/ctl.py | 2 +- mmgen/tw/shared.py | 82 +++++++++++++++++++++++++++++++++ mmgen/tw/unspent.py | 3 +- mmgen/tw/view.py | 68 +-------------------------- test/test_py_d/ts_main.py | 2 +- 16 files changed, 100 insertions(+), 82 deletions(-) create mode 100755 mmgen/tw/shared.py diff --git a/mmgen/addrdata.py b/mmgen/addrdata.py index e8c60e47..6210e5fe 100755 --- a/mmgen/addrdata.py +++ b/mmgen/addrdata.py @@ -73,7 +73,7 @@ class TwAddrData(AddrData,metaclass=AsyncInit): async def __init__(self,proto,wallet=None): from .rpc import rpc_init - from .tw.view import TwLabel + from .tw.shared import TwLabel from .globalvars import g from .seed import SeedID self.proto = proto diff --git a/mmgen/main_addrimport.py b/mmgen/main_addrimport.py index 63ddc5d1..7320fc66 100755 --- a/mmgen/main_addrimport.py +++ b/mmgen/main_addrimport.py @@ -24,7 +24,7 @@ from collections import namedtuple from .common import * from .addrlist import AddrList,KeyAddrList -from .tw.view import TwLabel +from .tw.shared import TwLabel opts_data = { 'text': { diff --git a/mmgen/proto/btc/tw/addresses.py b/mmgen/proto/btc/tw/addresses.py index c4f5a1ae..eb36a8a2 100755 --- a/mmgen/proto/btc/tw/addresses.py +++ b/mmgen/proto/btc/tw/addresses.py @@ -13,10 +13,10 @@ proto.btc.tw.addresses: Bitcoin base protocol tracking wallet address list class """ from ....tw.addresses import TwAddresses -from ....tw.view import TwLabel,get_obj +from ....tw.shared import TwLabel from ....util import msg,msg_r from ....addr import CoinAddr -from ....obj import NonNegativeInt +from ....obj import NonNegativeInt,get_obj from .common import BitcoinTwCommon class BitcoinTwAddresses(TwAddresses,BitcoinTwCommon): diff --git a/mmgen/proto/btc/tw/bal.py b/mmgen/proto/btc/tw/bal.py index a68fd3bb..b326b7c1 100755 --- a/mmgen/proto/btc/tw/bal.py +++ b/mmgen/proto/btc/tw/bal.py @@ -13,7 +13,7 @@ proto.btc.twbal: Bitcoin base protocol tracking wallet balance class """ from ....tw.bal import TwGetBalance -from ....tw.view import get_tw_label +from ....tw.shared import get_tw_label class BitcoinTwGetBalance(TwGetBalance): diff --git a/mmgen/proto/btc/tw/common.py b/mmgen/proto/btc/tw/common.py index 106f5fdc..7fdf3804 100755 --- a/mmgen/proto/btc/tw/common.py +++ b/mmgen/proto/btc/tw/common.py @@ -15,7 +15,7 @@ proto.btc.tw.common: Bitcoin base protocol tracking wallet dependency classes from ....addr import CoinAddr from ....util import die,msg,rmsg from ....obj import MMGenList -from ....tw.view import get_tw_label +from ....tw.shared import get_tw_label class BitcoinTwCommon: diff --git a/mmgen/proto/btc/tw/json.py b/mmgen/proto/btc/tw/json.py index a6b7d05f..56e79ff1 100755 --- a/mmgen/proto/btc/tw/json.py +++ b/mmgen/proto/btc/tw/json.py @@ -14,7 +14,7 @@ proto.btc.tw.json: export and import tracking wallet to JSON format from collections import namedtuple from ....tw.json import TwJSON -from ....tw.view import TwMMGenID +from ....tw.shared import TwMMGenID class BitcoinTwJSON(TwJSON): diff --git a/mmgen/proto/btc/tw/txhistory.py b/mmgen/proto/btc/tw/txhistory.py index dc107aa8..d2309402 100755 --- a/mmgen/proto/btc/tw/txhistory.py +++ b/mmgen/proto/btc/tw/txhistory.py @@ -15,7 +15,7 @@ proto.btc.tw.txhistory: Bitcoin base protocol tracking wallet transaction histor from collections import namedtuple from ....globalvars import g from ....tw.txhistory import TwTxHistory -from ....tw.view import get_tw_label,TwMMGenID +from ....tw.shared import get_tw_label,TwMMGenID from ....addr import CoinAddr from ....util import msg,msg_r from ....color import nocolor,red,pink,gray diff --git a/mmgen/proto/eth/tw/common.py b/mmgen/proto/eth/tw/common.py index 58b4a36a..a2c7f0af 100755 --- a/mmgen/proto/eth/tw/common.py +++ b/mmgen/proto/eth/tw/common.py @@ -15,7 +15,7 @@ from ....globalvars import g from ....tw.ctl import TrackingWallet from ....tw.view import TwView from ....addr import CoinAddr -from ....tw.view import TwLabel +from ....tw.shared import TwLabel class EthereumTwCommon(TwView): diff --git a/mmgen/proto/eth/tw/json.py b/mmgen/proto/eth/tw/json.py index c98c6c64..d09a40dd 100755 --- a/mmgen/proto/eth/tw/json.py +++ b/mmgen/proto/eth/tw/json.py @@ -14,7 +14,7 @@ proto.eth.tw.json: export and import tracking wallet to JSON format from collections import namedtuple from ....tw.json import TwJSON -from ....tw.view import TwMMGenID +from ....tw.shared import TwMMGenID class EthereumTwJSON(TwJSON): diff --git a/mmgen/proto/eth/tw/unspent.py b/mmgen/proto/eth/tw/unspent.py index 5b1dbf93..50a3de5e 100755 --- a/mmgen/proto/eth/tw/unspent.py +++ b/mmgen/proto/eth/tw/unspent.py @@ -20,7 +20,7 @@ proto.eth.twuo: Ethereum tracking wallet unspent outputs class """ -from ....tw.view import TwLabel +from ....tw.shared import TwLabel from ....tw.unspent import TwUnspentOutputs from .common import EthereumTwCommon diff --git a/mmgen/tw/addresses.py b/mmgen/tw/addresses.py index 6ed21b89..58fee555 100755 --- a/mmgen/tw/addresses.py +++ b/mmgen/tw/addresses.py @@ -19,7 +19,8 @@ from ..obj import MMGenListItem,ImmutableAttr,ListItemAttr,TwComment,NonNegative from ..rpc import rpc_init from ..addr import CoinAddr,MMGenID from ..color import red,green -from .view import TwView,TwMMGenID +from .view import TwView +from .shared import TwMMGenID class TwAddresses(MMGenObject,TwView,metaclass=AsyncInit): diff --git a/mmgen/tw/ctl.py b/mmgen/tw/ctl.py index 89c8a587..d4b3e23b 100755 --- a/mmgen/tw/ctl.py +++ b/mmgen/tw/ctl.py @@ -36,7 +36,7 @@ from ..objmethods import MMGenObject from ..obj import TwComment,get_obj from ..addr import CoinAddr,is_mmgen_id,is_coin_addr from ..rpc import rpc_init -from .view import TwMMGenID,TwLabel +from .shared import TwMMGenID,TwLabel addr_info = namedtuple('addr_info',['twmmid','coinaddr']) diff --git a/mmgen/tw/shared.py b/mmgen/tw/shared.py new file mode 100755 index 00000000..636a8a0c --- /dev/null +++ b/mmgen/tw/shared.py @@ -0,0 +1,82 @@ +#!/usr/bin/env python3 +# +# mmgen = Multi-Mode GENerator, a command-line cryptocurrency wallet +# Copyright (C)2013-2022 The MMGen Project +# Licensed under the GNU General Public License, Version 3: +# https://www.gnu.org/licenses +# Public project repositories: +# https://github.com/mmgen/mmgen +# https://gitlab.com/mmgen/mmgen + +""" +tw.shared: classes and functions shared by all tracking wallet classes +""" + +from ..objmethods import Hilite,InitErrors,MMGenObject +from ..obj import TwComment +from ..addr import MMGenID + +class TwMMGenID(str,Hilite,InitErrors,MMGenObject): + color = 'orange' + width = 0 + trunc_ok = False + def __new__(cls,proto,id_str): + if type(id_str) == cls: + return id_str + try: + ret = addr = disp = MMGenID(proto,id_str) + sort_key,idtype = (ret.sort_key,'mmgen') + except Exception as e: + try: + coin,addr = id_str.split(':',1) + assert coin == proto.base_coin.lower(),( + f'not a string beginning with the prefix {proto.base_coin.lower()!r}:' ) + assert addr.isascii() and addr.isalnum(), 'not an ASCII alphanumeric string' + ret,sort_key,idtype,disp = (id_str,'z_'+id_str,'non-mmgen','non-MMGen') + addr = proto.coin_addr(addr) + except Exception as e2: + return cls.init_fail(e,id_str,e2=e2) + + me = str.__new__(cls,ret) + me.obj = ret + me.disp = disp + me.addr = addr + me.sort_key = sort_key + me.type = idtype + me.proto = proto + return me + + @classmethod + def fmtc(cls,twmmid,*args,**kwargs): + return super().fmtc(twmmid.disp,*args,**kwargs) + +# non-displaying container for TwMMGenID,TwComment +class TwLabel(str,InitErrors,MMGenObject): + exc = 'BadTwLabel' + passthru_excs = ('BadTwComment',) + def __new__(cls,proto,text): + if type(text) == cls: + return text + try: + ts = text.split(None,1) + mmid = TwMMGenID(proto,ts[0]) + comment = TwComment(ts[1] if len(ts) == 2 else '') + me = str.__new__( cls, mmid + (' ' + comment if comment else '') ) + me.mmid = mmid + me.comment = comment + me.proto = proto + return me + except Exception as e: + return cls.init_fail(e,text) + +def get_tw_label(proto,s): + """ + raise an exception on a malformed comment, return None on an empty or invalid label + """ + try: + return TwLabel(proto,s) + except Exception as e: + if type(e).__name__ == 'BadTwComment': # do it this way to avoid importing .exception + raise + else: + return None diff --git a/mmgen/tw/unspent.py b/mmgen/tw/unspent.py index a92654d3..1b0107c6 100755 --- a/mmgen/tw/unspent.py +++ b/mmgen/tw/unspent.py @@ -35,7 +35,8 @@ from ..obj import ( NonNegativeInt ) from ..addr import CoinAddr,MMGenID from ..rpc import rpc_init -from .view import TwView,TwMMGenID,get_tw_label +from .view import TwView +from .shared import TwMMGenID,get_tw_label class TwUnspentOutputs(MMGenObject,TwView,metaclass=AsyncInit): diff --git a/mmgen/tw/view.py b/mmgen/tw/view.py index 170bafb9..75520978 100755 --- a/mmgen/tw/view.py +++ b/mmgen/tw/view.py @@ -25,10 +25,9 @@ from collections import namedtuple from ..globalvars import g from ..objmethods import Hilite,InitErrors,MMGenObject -from ..obj import TwComment,get_obj,MMGenIdx,MMGenList +from ..obj import get_obj,MMGenIdx,MMGenList from ..color import nocolor,yellow,green,red,blue from ..util import msg,msg_r,fmt,die,capfirst,make_timestr -from ..addr import MMGenID # base class for TwUnspentOutputs,TwAddresses,TwTxHistory: class TwView: @@ -506,68 +505,3 @@ class TwView: return None return await do_comment_add(res) - -class TwMMGenID(str,Hilite,InitErrors,MMGenObject): - color = 'orange' - width = 0 - trunc_ok = False - def __new__(cls,proto,id_str): - if type(id_str) == cls: - return id_str - try: - ret = addr = disp = MMGenID(proto,id_str) - sort_key,idtype = (ret.sort_key,'mmgen') - except Exception as e: - try: - coin,addr = id_str.split(':',1) - assert coin == proto.base_coin.lower(),( - f'not a string beginning with the prefix {proto.base_coin.lower()!r}:' ) - assert addr.isascii() and addr.isalnum(), 'not an ASCII alphanumeric string' - ret,sort_key,idtype,disp = (id_str,'z_'+id_str,'non-mmgen','non-MMGen') - addr = proto.coin_addr(addr) - except Exception as e2: - return cls.init_fail(e,id_str,e2=e2) - - me = str.__new__(cls,ret) - me.obj = ret - me.disp = disp - me.addr = addr - me.sort_key = sort_key - me.type = idtype - me.proto = proto - return me - - @classmethod - def fmtc(cls,twmmid,*args,**kwargs): - return super().fmtc(twmmid.disp,*args,**kwargs) - -# non-displaying container for TwMMGenID,TwComment -class TwLabel(str,InitErrors,MMGenObject): - exc = 'BadTwLabel' - passthru_excs = ('BadTwComment',) - def __new__(cls,proto,text): - if type(text) == cls: - return text - try: - ts = text.split(None,1) - mmid = TwMMGenID(proto,ts[0]) - comment = TwComment(ts[1] if len(ts) == 2 else '') - me = str.__new__( cls, mmid + (' ' + comment if comment else '') ) - me.mmid = mmid - me.comment = comment - me.proto = proto - return me - except Exception as e: - return cls.init_fail(e,text) - -def get_tw_label(proto,s): - """ - raise an exception on a malformed comment, return None on an empty or invalid label - """ - try: - return TwLabel(proto,s) - except Exception as e: - if type(e).__name__ == 'BadTwComment': # do it this way to avoid importing .exception - raise - else: - return None diff --git a/test/test_py_d/ts_main.py b/test/test_py_d/ts_main.py index 5d98f0ee..b3b540b7 100755 --- a/test/test_py_d/ts_main.py +++ b/test/test_py_d/ts_main.py @@ -483,7 +483,7 @@ class TestSuiteMain(TestSuiteBase,TestSuiteShared): cmd_args = self._make_txcreate_cmdline(tx_data) if cmdline_inputs: - from mmgen.tw.view import TwLabel + from mmgen.tw.shared import TwLabel cmd_args = [ '--inputs={},{},{},{},{},{}'.format( TwLabel(self.proto,dfake[0][self.lbl_id]).mmid,dfake[1]['address'],