From 5e745f2a089265c09e00160d16bba28a6542e708 Mon Sep 17 00:00:00 2001 From: The MMGen Project Date: Mon, 1 Jun 2020 09:25:56 +0000 Subject: [PATCH] string formatting, whitespace, minor fixes throughout --- mmgen/obj.py | 67 ++++++----- mmgen/protocol.py | 2 +- mmgen/tw.py | 167 ++++++++++++++++------------ mmgen/tx.py | 2 +- test/objtest.py | 16 ++- test/objtest_py_d/ot_btc_mainnet.py | 12 -- test/test.py | 2 + 7 files changed, 155 insertions(+), 113 deletions(-) diff --git a/mmgen/obj.py b/mmgen/obj.py index 5366a5d1..fab4c5f1 100755 --- a/mmgen/obj.py +++ b/mmgen/obj.py @@ -108,13 +108,15 @@ class InitErrors(object): e2_fmt = '({}) '.format(e2.args[0]) if e2 else '' errmsg = fs.format(m,objname or cls.__name__,e2_fmt,e.args[0]) - if m2: errmsg = '{!r}\n{}'.format(m2,errmsg) + if m2: + errmsg = '{!r}\n{}'.format(m2,errmsg) from .util import die,msg if cls.on_fail == 'silent': return None # TODO: return False instead? elif cls.on_fail == 'return': - if errmsg: msg(errmsg) + if errmsg: + msg(errmsg) return None # TODO: return False instead? elif g.traceback or cls.on_fail == 'raise': if hasattr(cls,'exc'): @@ -127,8 +129,9 @@ class InitErrors(object): @classmethod def method_not_implemented(cls): import traceback - raise NotImplementedError('method {!r} not implemented for class {!r}'.format( - traceback.extract_stack()[-2].name, cls.__name__)) + raise NotImplementedError( + 'method {!r} not implemented for class {!r}'.format( + traceback.extract_stack()[-2].name, cls.__name__) ) class Hilite(object): @@ -231,8 +234,10 @@ class ImmutableAttr: # Descriptor def __init__(self,dtype,typeconv=True,set_none_ok=False,include_proto=False): assert isinstance(dtype,self.ok_dtypes), 'ImmutableAttr_check1' - if include_proto: assert typeconv and type(dtype) == str, 'ImmutableAttr_check2' - if set_none_ok: assert typeconv and type(dtype) != str, 'ImmutableAttr_check3' + if include_proto: + assert typeconv and type(dtype) == str, 'ImmutableAttr_check2' + if set_none_ok: + assert typeconv and type(dtype) != str, 'ImmutableAttr_check3' if dtype is None: 'use instance-defined conversion function for this attribute' @@ -365,14 +370,16 @@ class AddrIdxList(list,InitErrors,MMGenObject): j = i.split('-') if len(j) == 1: idx = AddrIdx(i,on_fail='raise') - if not idx: break + if not idx: + break ret.append(idx) elif len(j) == 2: beg = AddrIdx(j[0],on_fail='raise') - if not beg: break + if not beg: + break end = AddrIdx(j[1],on_fail='raise') - if not beg: break - if end < beg: break + if not beg or (end < beg): + break ret.extend([AddrIdx(x,on_fail='raise') for x in range(beg,end+1)]) else: break else: @@ -391,7 +398,8 @@ class MMGenRange(tuple,InitErrors,MMGenObject): try: if len(args) == 1: s = args[0] - if type(s) == cls: return s + if type(s) == cls: + return s assert isinstance(s,str),'not a string or string subclass' ss = s.split('-',1) first = int(ss[0]) @@ -442,7 +450,8 @@ class BTCAmt(Decimal,Hilite,InitErrors): # NB: 'from_decimal' rounds down to precision of 'min_coin_unit' def __new__(cls,num,from_unit=None,from_decimal=False,on_fail='die'): - if type(num) == cls: return num + if type(num) == cls: + return num cls.arg_chk(on_fail) try: if from_unit: @@ -480,7 +489,8 @@ class BTCAmt(Decimal,Hilite,InitErrors): cls.method_not_implemented() def fmt(self,fs=None,color=False,suf='',prec=1000): - if fs == None: fs = self.amt_fs + if fs == None: + fs = self.amt_fs s = str(int(self)) if int(self) == self else self.normalize().__format__('f') if '.' in fs: p1,p2 = list(map(int,fs.split('.',1))) @@ -576,7 +586,8 @@ class SeedID(str,Hilite,InitErrors): width = 8 trunc_ok = False def __new__(cls,seed=None,sid=None,on_fail='die'): - if type(sid) == cls: return sid + if type(sid) == cls: + return sid cls.arg_chk(on_fail) try: if seed: @@ -586,7 +597,7 @@ class SeedID(str,Hilite,InitErrors): return str.__new__(cls,make_chksum_8(seed.data)) elif sid: assert set(sid) <= set(hexdigits.upper()),'not uppercase hex digits' - assert len(sid) == cls.width,'not {} characters wide'.format(cls.width) + assert len(sid) == cls.width, f'not {cls.width} characters wide' return str.__new__(cls,sid) raise ValueError('no arguments provided') except Exception as e: @@ -596,7 +607,8 @@ class SubSeedIdx(str,Hilite,InitErrors): color = 'red' trunc_ok = False def __new__(cls,s,on_fail='die'): - if type(s) == cls: return s + if type(s) == cls: + return s cls.arg_chk(on_fail) try: assert isinstance(s,str),'not a string or string subclass' @@ -676,7 +688,7 @@ class TwLabel(str,InitErrors,MMGenObject): ts = text.split(None,1) mmid = TwMMGenID(proto,ts[0],on_fail='raise') comment = TwComment(ts[1] if len(ts) == 2 else '',on_fail='raise') - me = str.__new__(cls,'{}{}'.format(mmid,' {}'.format(comment) if comment else '')) + me = str.__new__( cls, mmid + (' ' + comment if comment else '') ) me.mmid = mmid me.comment = comment me.proto = proto @@ -690,16 +702,18 @@ class HexStr(str,Hilite,InitErrors): hexcase = 'lower' trunc_ok = False def __new__(cls,s,on_fail='die',case=None): - if type(s) == cls: return s + if type(s) == cls: + return s cls.arg_chk(on_fail) - if case == None: case = cls.hexcase + if case == None: + case = cls.hexcase try: assert isinstance(s,str),'not a string or string subclass' - assert case in ('upper','lower'),"'{}' incorrect case specifier".format(case) - assert set(s) <= set(getattr(hexdigits,case)()),'not {}case hexadecimal symbols'.format(case) + assert case in ('upper','lower'), f'{case!r} incorrect case specifier' + assert set(s) <= set(getattr(hexdigits,case)()), f'not {case}case hexadecimal symbols' assert not len(s) % 2,'odd-length string' if cls.width: - assert len(s) == cls.width,'Value is not {} characters wide'.format(cls.width) + assert len(s) == cls.width, f'Value is not {cls.width} characters wide' return str.__new__(cls,s) except Exception as e: return cls.init_fail(e,s) @@ -755,7 +769,8 @@ class PrivKey(str,Hilite,InitErrors,MMGenObject): # initialize with (priv_bin,compressed), WIF or self def __new__(cls,proto,s=None,compressed=None,wif=None,pubkey_type=None,on_fail='die'): - if type(s) == cls: return s + if type(s) == cls: + return s cls.arg_chk(on_fail) if wif: @@ -821,7 +836,8 @@ class MMGenLabel(str,Hilite,InitErrors): max_screen_width = 0 # if != 0, overrides max_len desc = 'label' def __new__(cls,s,on_fail='die',msg=None): - if type(s) == cls: return s + if type(s) == cls: + return s cls.arg_chk(on_fail) for k in cls.forbidden,cls.allowed: assert type(k) == list @@ -874,7 +890,8 @@ class MMGenPWIDString(MMGenLabel): class SeedSplitSpecifier(str,Hilite,InitErrors,MMGenObject): color = 'red' def __new__(cls,s,on_fail='raise'): - if type(s) == cls: return s + if type(s) == cls: + return s cls.arg_chk(on_fail) try: arr = s.split(':') diff --git a/mmgen/protocol.py b/mmgen/protocol.py index 52cb962b..e361de9d 100755 --- a/mmgen/protocol.py +++ b/mmgen/protocol.py @@ -166,7 +166,7 @@ class CoinProtocol(MMGenObject): return False def coin_addr(self,addr): - return CoinAddr(proto=self,addr=addr) + return CoinAddr( proto=self, addr=addr ) def addr_type(self,id_str,on_fail='die'): return MMGenAddrType(proto=self,id_str=id_str,on_fail=on_fail) diff --git a/mmgen/tw.py b/mmgen/tw.py index 2f35e0f0..c06a84b5 100755 --- a/mmgen/tw.py +++ b/mmgen/tw.py @@ -32,9 +32,12 @@ CUR_HOME,ERASE_ALL = '\033[H','\033[0J' def CUR_RIGHT(n): return '\033[{}C'.format(n) def get_tw_label(proto,s): - try: return TwLabel(proto,s,on_fail='raise') - except BadTwComment: raise - except: return None + try: + return TwLabel(proto,s,on_fail='raise') + except BadTwComment: + raise + except: + return None _date_formatter = { 'days': lambda rpc,secs: (rpc.cur_date - secs) // 86400, @@ -113,13 +116,6 @@ Actions: [q]uit view, [p]rint to file, pager [v]iew, [w]ide view, add [l]abel: def amt2(self,value): return self.proto.coin_amt(value) - wmsg = { - 'no_spendable_outputs': """ -No spendable outputs found! Import addresses with balances into your -watch-only wallet using '{}-addrimport' and then re-run this program. -""".strip().format(g.proj_name.lower()) - } - async def __ainit__(self,proto,minconf=1,addrs=[]): self.proto = proto self.unspent = self.MMGenTwOutputList() @@ -146,7 +142,7 @@ watch-only wallet using '{}-addrimport' and then re-run this program. @age_fmt.setter def age_fmt(self,val): if val not in self.age_fmts: - raise BadAgeFormat("'{}': invalid age format (must be one of {!r})".format(val,self.age_fmts)) + raise BadAgeFormat(f'{val!r}: invalid age format (must be one of {self.age_fmts!r})') self._age_fmt = val def get_display_precision(self): @@ -176,7 +172,10 @@ watch-only wallet using '{}-addrimport' and then re-run this program. us_raw = await self.get_unspent_rpc() if not us_raw: - die(0,self.wmsg['no_spendable_outputs']) + die(0,fmt(f""" + No spendable outputs found! Import addresses with balances into your + watch-only wallet using '{g.proj_name.lower()}-addrimport' and then re-run this program. + """).strip()) lbl_id = ('account','label')['label_api' in self.rpc.caps] @@ -214,7 +213,7 @@ watch-only wallet using '{}-addrimport' and then re-run this program. } key = key or self.sort_key if key not in sort_funcs: - die(1,"'{}': invalid sort key. Valid options: {}".format(key,' '.join(sort_funcs.keys()))) + die(1,f'{key!r}: invalid sort key. Valid options: {" ".join(sort_funcs.keys())}') self.sort_key = key assert type(reverse) == bool self.unspent.sort(key=sort_funcs[key],reverse=reverse or self.reverse) @@ -230,10 +229,11 @@ watch-only wallet using '{}-addrimport' and then re-run this program. from .term import get_terminal_size while True: self.cols = g.terminal_width or get_terminal_size().width - if self.cols >= g.min_screen_width: break - m1 = 'Screen too narrow to display the tracking wallet\n' - m2 = 'Please resize your screen to at least {} characters and hit ENTER ' - my_raw_input((m1+m2).format(g.min_screen_width)) + if self.cols >= g.min_screen_width: + break + my_raw_input( + 'Screen too narrow to display the tracking wallet\n' + + f'Please resize your screen to at least {g.min_screen_width} characters and hit ENTER ' ) def get_display_constants(self): unsp = self.unspent @@ -360,20 +360,29 @@ watch-only wallet using '{}-addrimport' and then re-run this program. max_lbl_len = max([len(i.label) for i in self.unspent if i.label] or [2]) for n,i in enumerate(self.unspent): yield fs.format( - n = str(n+1)+')', - t = '{},{}'.format('|'+'.'*63 if i.skip == 'txid' and self.group else i.txid,i.vout), + n = str(n+1) + ')', + t = '{},{}'.format( + ('|'+'.'*63 if i.skip == 'txid' and self.group else i.txid), + i.vout ), a = ( '|'+'.' * addr_w if i.skip == 'addr' and self.group else i.addr.fmt(color=color,width=addr_w) ), - m = MMGenID.fmtc(i.twmmid if i.twmmid.type=='mmgen' else - 'Non-{}'.format(g.proj_name),width = mmid_w,color=color), + m = MMGenID.fmtc( + (i.twmmid if i.twmmid.type == 'mmgen' else f'Non-{g.proj_name}'), + width = mmid_w, + color = color ), A = i.amt.fmt(color=color), A2 = ( i.amt2.fmt(color=color) if i.amt2 is not None else '' ), c = i.confs, b = self.rpc.blockcount - (i.confs - 1), D = self.age_disp(i,'date_time'), l = i.label.hl(color=color) if i.label else - TwComment.fmtc('',color = color,nullrepl='-',width=max_lbl_len) ).rstrip() + TwComment.fmtc( + s = '', + color = color, + nullrepl = '-', + width = max_lbl_len ) + ).rstrip() fs2 = '{} (block #{}, {} UTC)\n{}Sort order: {}\n{}\n\nTotal {}: {}\n' self.fmt_print = fs2.format( @@ -399,11 +408,11 @@ watch-only wallet using '{}-addrimport' and then re-run this program. def get_idx_from_user(self,action): msg('') while True: - ret = my_raw_input('Enter {} number (or RETURN to return to main menu): '.format(self.item_desc)) + ret = my_raw_input(f'Enter {self.item_desc} number (or RETURN to return to main menu): ') if ret == '': return (None,None) if action == 'a_lbl_add' else None n = AddrIdx(ret,on_fail='silent') if not n or n < 1 or n > len(self.unspent): - msg('Choice must be a single number between 1 and {}'.format(len(self.unspent))) + msg(f'Choice must be a single number between 1 and {len(self.unspent)}') else: if action == 'a_lbl_add': while True: @@ -411,17 +420,17 @@ watch-only wallet using '{}-addrimport' and then re-run this program. if s == 'q': return None,None elif s == '': - fs = "Removing label for {} #{}. Is this what you want?" - if keypress_confirm(fs.format(self.item_desc,n)): + if keypress_confirm( + f'Removing label for {self.item_desc} #{n}. Is this what you want?'): return n,s elif s: if TwComment(s,on_fail='return'): return n,s else: if action == 'a_addr_delete': - fs = "Removing {} #{} from tracking wallet. Is this what you want?" + fs = 'Removing {} #{} from tracking wallet. Is this what you want?' elif action == 'a_balance_refresh': - fs = "Refreshing tracking wallet {} #{}. Is this what you want?" + fs = 'Refreshing tracking wallet {} #{}. Is this what you want?' if keypress_confirm(fs.format(self.item_desc,n)): return n @@ -468,7 +477,7 @@ watch-only wallet using '{}-addrimport' and then re-run this program. e = self.unspent[idx-1] bal = await self.wallet.get_balance(e.addr,force_rpc=True) await self.get_unspent_data() - oneshot_msg = yellow('{} balance for account #{} refreshed\n\n'.format(self.proto.dcoin,idx)) + oneshot_msg = yellow(f'{self.proto.dcoin} balance for account #{idx} refreshed\n\n') self.display_constants = self.get_display_constants() elif action == 'a_lbl_add': idx,lbl = self.get_idx_from_user(action) @@ -476,8 +485,10 @@ watch-only wallet using '{}-addrimport' and then re-run this program. e = self.unspent[idx-1] if await self.wallet.add_label(e.twmmid,lbl,addr=e.addr): await self.get_unspent_data() - a = 'added to' if lbl else 'removed from' - oneshot_msg = yellow("Label {} {} #{}\n\n".format(a,self.item_desc,idx)) + oneshot_msg = yellow('Label {} {} #{}\n\n'.format( + ('added to' if lbl else 'removed from'), + self.item_desc, + idx )) else: oneshot_msg = red('Label could not be added\n\n') self.display_constants = self.get_display_constants() @@ -487,22 +498,29 @@ watch-only wallet using '{}-addrimport' and then re-run this program. e = self.unspent[idx-1] if await self.wallet.remove_address(e.addr): await self.get_unspent_data() - oneshot_msg = yellow("{} #{} removed\n\n".format(capfirst(self.item_desc),idx)) + oneshot_msg = yellow(f'{capfirst(self.item_desc)} #{idx} removed\n\n') else: oneshot_msg = red('Address could not be removed\n\n') self.display_constants = self.get_display_constants() elif action == 'a_print': - of = '{}-{}[{}].out'.format(self.dump_fn_pfx,self.proto.dcoin, - ','.join(self.sort_info(include_group=False)).lower()) + of = '{}-{}[{}].out'.format( + self.dump_fn_pfx, + self.proto.dcoin, + ','.join(self.sort_info(include_group=False)).lower() ) msg('') try: - write_data_to_file(of,await self.format_for_printing(),desc='{} listing'.format(self.desc)) + write_data_to_file( + of, + await self.format_for_printing(), + desc = f'{self.desc} listing' ) except UserNonConfirmation as e: - oneshot_msg = red("File '{}' not overwritten by user request\n\n".format(of)) + oneshot_msg = red(f'File {of!r} not overwritten by user request\n\n') else: - oneshot_msg = yellow("Data written to '{}'\n\n".format(of)) + oneshot_msg = yellow(f'Data written to {of!r}\n\n') elif action in ('a_view','a_view_wide'): - do_pager(self.fmt_display if action == 'a_view' else await self.format_for_printing(color=True)) + do_pager( + self.fmt_display if action == 'a_view' else + await self.format_for_printing(color=True) ) if g.platform == 'linux' and oneshot_msg == None: msg_r(CUR_RIGHT(len(prompt.split('\n')[-1])-2)) no_output = True @@ -533,7 +551,7 @@ class TwAddrList(MMGenDict,metaclass=aInitMeta): for mmid in sorted(a.mmid for a in acct_labels if a): if mmid == mmid_prev: err = True - msg('Duplicate MMGen ID ({}) discovered in tracking wallet!\n'.format(mmid)) + msg(f'Duplicate MMGen ID ({mmid}) discovered in tracking wallet!\n') mmid_prev = mmid if err: rdie(3,'Tracking wallet is corrupted!') @@ -567,14 +585,15 @@ class TwAddrList(MMGenDict,metaclass=aInitMeta): die(2,'duplicate {} address ({}) for this MMGen address! ({})'.format( proto.coin, d['address'], - self[lm]['addr']) ) + self[lm]['addr'] )) else: lm.confs = d['confirmations'] lm.txid = d['txid'] lm.date = None - self[lm] = {'amt': proto.coin_amt('0'), - 'lbl': label, - 'addr': CoinAddr(proto,d['address'])} + self[lm] = { + 'amt': proto.coin_amt('0'), + 'lbl': label, + 'addr': CoinAddr(proto,d['address']) } self[lm]['amt'] += d['amount'] self.total += d['amount'] @@ -614,7 +633,7 @@ class TwAddrList(MMGenDict,metaclass=aInitMeta): if not self.has_age: show_age = False if age_fmt not in self.age_fmts: - raise BadAgeFormat("'{}': invalid age format (must be one of {!r})".format(age_fmt,self.age_fmts)) + raise BadAgeFormat(f'{age_fmt!r}: invalid age format (must be one of {self.age_fmts!r})') fs = '{mid}' + ('',' {addr}')[showbtcaddrs] + ' {cmt} {amt}' + ('',' {age}')[show_age] mmaddrs = [k for k in self.keys() if k.type == 'mmgen'] max_mmid_len = max(len(k) for k in mmaddrs) + 2 if mmaddrs else 10 @@ -671,7 +690,9 @@ class TwAddrList(MMGenDict,metaclass=aInitMeta): age=self.age_disp(mmid,age_fmt) if show_age and hasattr(mmid,'confs') else '-' ).rstrip() - yield '\nTOTAL: {} {}'.format(self.total.hl(color=True),self.proto.dcoin) + yield '\nTOTAL: {} {}'.format( + self.total.hl(color=True), + self.proto.dcoin ) return '\n'.join(gen_output()) @@ -694,7 +715,7 @@ class TrackingWallet(MMGenObject,metaclass=aInitMeta): mode = 'w' if g.debug: - print_stack_trace('TW INIT {!r} {!r}'.format(mode,self)) + print_stack_trace(f'TW INIT {mode!r} {self!r}') self.rpc = await rpc_init(proto) # TODO: create on demand - only certain ops require RPC self.proto = proto @@ -707,8 +728,10 @@ class TrackingWallet(MMGenObject,metaclass=aInitMeta): self.init_empty() if self.data['coin'] != self.proto.coin: # TODO remove? - m = 'Tracking wallet coin ({}) does not match current coin ({})!' - raise WalletFileError(m.format(self.data['coin'],self.proto.coin)) + raise WalletFileError( + 'Tracking wallet coin ({}) does not match current coin ({})!'.format( + self.data['coin'], + self.proto.coin )) self.conv_types(self.data[self.data_key]) self.cur_balances = {} # cache balances to prevent repeated lookups per program invocation @@ -739,8 +762,7 @@ class TrackingWallet(MMGenObject,metaclass=aInitMeta): self.init_empty() self.force_write() else: - m = "File '{}' exists but does not contain valid json data" - raise WalletFileError(m.format(self.tw_fn)) + raise WalletFileError(f'File {self.tw_fn!r} exists but does not contain valid json data') else: self.upgrade_wallet_maybe() @@ -748,7 +770,7 @@ class TrackingWallet(MMGenObject,metaclass=aInitMeta): if self.mode == 'w': import atexit def del_tw(tw): - dmsg('Running exit handler del_tw() for {!r}'.format(tw)) + dmsg(f'Running exit handler del_tw() for {tw!r}') del tw atexit.register(del_tw,self) @@ -766,7 +788,7 @@ class TrackingWallet(MMGenObject,metaclass=aInitMeta): Since no exceptions are raised, errors will not be caught by the test suite. """ if g.debug: - print_stack_trace('TW DEL {!r}'.format(self)) + print_stack_trace(f'TW DEL {self!r}') if self.mode == 'w': self.write() @@ -846,17 +868,22 @@ class TrackingWallet(MMGenObject,metaclass=aInitMeta): @write_mode def write_changed(self,data): write_data_to_file( - self.tw_fn,data, - desc='{} data'.format(self.base_desc), - ask_overwrite=False,ignore_opt_outdir=True,quiet=True, - check_data=True,cmp_data=self.orig_data) + self.tw_fn, + data, + desc = f'{self.base_desc} data', + ask_overwrite = False, + ignore_opt_outdir = True, + quiet = True, + check_data = True, + cmp_data = self.orig_data ) + self.orig_data = data def write(self): # use 'check_data' to check wallet hasn't been altered by another program if not self.use_tw_file: dmsg("'use_tw_file' is False, doing nothing") return - dmsg('write(): checking if {} data has changed'.format(self.desc)) + dmsg(f'write(): checking if {self.desc} data has changed') wdata = json.dumps(self.data) if self.orig_data != wdata: @@ -903,11 +930,11 @@ class TrackingWallet(MMGenObject,metaclass=aInitMeta): try: if not is_mmgen_id(self.proto,arg1): - assert coinaddr,"Invalid coin address for this chain: {}".format(arg1) - assert coinaddr,"{pn} address '{ma}' not found in tracking wallet" - assert await self.is_in_wallet(coinaddr),"Address '{ca}' not found in tracking wallet" + assert coinaddr, f'Invalid coin address for this chain: {arg1}' + assert coinaddr, f'{g.proj_name} address {mmaddr!r} not found in tracking wallet' + assert await self.is_in_wallet(coinaddr), f'Address {coinaddr!r} not found in tracking wallet' except Exception as e: - msg(e.args[0].format(pn=g.proj_name,ma=mmaddr,ca=coinaddr)) + msg(str(e)) return False # Allow for the possibility that BTC addr of MMGen addr was entered. @@ -917,7 +944,7 @@ class TrackingWallet(MMGenObject,metaclass=aInitMeta): mmaddr = (await TwAddrData(proto=self.proto)).coinaddr2mmaddr(coinaddr) if not mmaddr: - mmaddr = '{}:{}'.format(self.proto.base_coin.lower(),coinaddr) + mmaddr = f'{self.proto.base_coin.lower()}:{coinaddr}' mmaddr = TwMMGenID(self.proto,mmaddr) @@ -929,14 +956,16 @@ class TrackingWallet(MMGenObject,metaclass=aInitMeta): if await self.set_label(coinaddr,lbl) == False: if not silent: - msg('Label could not be {}'.format(('removed','added')[bool(label)])) + msg( 'Label could not be {}'.format('added' if label else 'removed') ) return False else: - m = mmaddr.type.replace('mmg','MMG') - a = mmaddr.replace(self.proto.base_coin.lower()+':','') - s = '{} address {} in tracking wallet'.format(m,a) - if label: msg("Added label '{}' to {}".format(label,s)) - else: msg('Removed label from {}'.format(s)) + desc = '{} address {} in tracking wallet'.format( + mmaddr.type.replace('mmg','MMG'), + mmaddr.replace(self.proto.base_coin.lower()+':','') ) + if label: + msg(f'Added label {label!r} to {desc}') + else: + msg(f'Removed label from {desc}') return True @write_mode @@ -945,7 +974,7 @@ class TrackingWallet(MMGenObject,metaclass=aInitMeta): @write_mode async def remove_address(self,addr): - raise NotImplementedError('address removal not implemented for coin {}'.format(self.proto.coin)) + raise NotImplementedError(f'address removal not implemented for coin {self.proto.coin}') class TwGetBalance(MMGenObject,metaclass=aInitMeta): diff --git a/mmgen/tx.py b/mmgen/tx.py index bdc97dd6..8dce9a57 100755 --- a/mmgen/tx.py +++ b/mmgen/tx.py @@ -737,7 +737,7 @@ class MMGenTX: if selected: if selected[-1] <= len(unspent): return selected - msg('Unspent output number must be <= {}'.format(len(unspent))) + msg(f'Unspent output number must be <= {len(unspent)}') def select_unspent_cmdline(self,unspent): diff --git a/test/objtest.py b/test/objtest.py index 6c6c2015..129da1c9 100755 --- a/test/objtest.py +++ b/test/objtest.py @@ -100,6 +100,7 @@ def run_test(test,arg,input_data): raise UserWarning("Non-'None' return value {} with bad input data".format(repr(ret))) if opt.silent and input_data=='good' and ret==bad_ret: raise UserWarning("'None' returned with good input data") + if input_data=='good': if ret_idx: ret_chk = arg[list(arg.keys())[ret_idx]].encode() @@ -108,7 +109,8 @@ def run_test(test,arg,input_data): if not opt.super_silent: try: ret_disp = ret.decode() except: ret_disp = ret - msg('==> {!r}'.format(ret_disp)) + msg(f'==> {ret_disp!r}') + if opt.verbose and issubclass(cls,MMGenObject): ret.pmsg() if hasattr(ret,'pmsg') else pmsg(ret) except Exception as e: @@ -121,10 +123,10 @@ def run_test(test,arg,input_data): if input_data == 'good': raise ValueError('Error on good input data') if opt.verbose: - msg('exitval: {}'.format(e.code)) + msg(f'exitval: {e.code}') except UserWarning as e: - msg('==> {!r}'.format(ret)) - die(2,red('{}'.format(e.args[0]))) + msg(f'==> {ret!r}') + die(2,red(str(e))) def do_loop(): import importlib @@ -143,7 +145,11 @@ def do_loop(): if not opt.silent: msg(purple(capfirst(k)+' input:')) for arg in test_data[test][k]: - run_test(test,arg,input_data=k) + run_test( + test, + arg, + input_data = k, + ) from mmgen.protocol import init_proto_from_opts proto = init_proto_from_opts() diff --git a/test/objtest_py_d/ot_btc_mainnet.py b/test/objtest_py_d/ot_btc_mainnet.py index b97d58c1..0407781e 100755 --- a/test/objtest_py_d/ot_btc_mainnet.py +++ b/test/objtest_py_d/ot_btc_mainnet.py @@ -149,18 +149,6 @@ tests = { {'id_str':'F00BAA12:S:9999999', 'proto':proto}, ), }, - 'TwLabel': { - 'bad': ('x x','x я','я:я',1,'f00f00f','a:b','x:L:3','F00BAA12:0 x', - 'F00BAA12:Z:99',tw_pfx+' x',tw_pfx+'я x', - 'F00BAA12:S:1 '+ utf8_ctrl[:40], - {'s':'F00BAA12:S:1 '+ utf8_ctrl[:40],'on_fail':'raise','ExcType':'BadTwComment'}, - ), - 'good': ( - ('F00BAA12:99 a comment','F00BAA12:L:99 a comment'), - 'F00BAA12:L:99 comment (UTF-8) α', - 'F00BAA12:S:9999999 comment', - tw_pfx+'x comment') - }, 'TwLabel': { 'bad': ( {'text':'x x', 'proto':proto}, diff --git a/test/test.py b/test/test.py index ecb43c3c..6b021880 100755 --- a/test/test.py +++ b/test/test.py @@ -167,6 +167,8 @@ def add_cmdline_opts(): # add_cmdline_opts() +opts.UserOpts._reset_ok += ('skip_deps',) + # step 2: opts.init will create new data_dir in ./test (if not 'resume' or 'skip_deps'): usr_args = opts.init(opts_data)