diff --git a/mmgen/addr.py b/mmgen/addr.py index 87fdc04d..53718fb7 100755 --- a/mmgen/addr.py +++ b/mmgen/addr.py @@ -728,7 +728,7 @@ Removed {{}} duplicate WIF key{{}} from keylist (also in {pnm} key-address file self.al_id = AddrListID(SeedID(sid=sid),mmtype) data = self.parse_file_body(lines[1:-1]) - assert issubclass(type(data),list),'Invalid file body data' + assert isinstance(data,list),'Invalid file body data' except Exception as e: m = 'Invalid address list file ({})'.format(e.args[0]) if exit_on_error: die(3,m) diff --git a/mmgen/altcoins/eth/tx.py b/mmgen/altcoins/eth/tx.py index 2db0cafa..ecfbc66d 100755 --- a/mmgen/altcoins/eth/tx.py +++ b/mmgen/altcoins/eth/tx.py @@ -201,7 +201,7 @@ class EthereumMMGenTX(MMGenTX): # given rel fee in wei, return absolute fee using tx_gas (not in MMGenTX) def fee_rel2abs(self,rel_fee): - assert type(rel_fee) in (int,Int),"'{}': incorrect type for fee estimate (not an integer)".format(rel_fee) + assert isinstance(rel_fee,int),"'{}': incorrect type for fee estimate (not an integer)".format(rel_fee) return ETHAmt(rel_fee * self.tx_gas.toWei(),'wei') # given fee estimate (gas price) in wei, return absolute fee, adjusting by opt.tx_fee_adj diff --git a/mmgen/crypto.py b/mmgen/crypto.py index f7219035..63d80c59 100755 --- a/mmgen/crypto.py +++ b/mmgen/crypto.py @@ -108,7 +108,7 @@ def scrypt_hash_passphrase(passwd,salt,hash_preset,buflen=32): # Buflen arg is for brainwallets only, which use this function to generate # the seed directly. N,r,p = get_hash_params(hash_preset) - if type(passwd) == str: passwd = passwd.encode() + if isinstance(passwd,str): passwd = passwd.encode() def do_hashlib_scrypt(): from hashlib import scrypt # Python >= v3.6 diff --git a/mmgen/devtools.py b/mmgen/devtools.py index e75bce30..ca67d828 100755 --- a/mmgen/devtools.py +++ b/mmgen/devtools.py @@ -40,7 +40,7 @@ class MMGenObject(object): out.append('{s}{:<{l}}'.format(i,s=' '*(4*lvl+8),l=10,l2=8*(lvl+1)+8)) if hasattr(el,'ppformat'): out.append('{:>{l}}{}'.format('',el.ppformat(lvl=lvl+1,id_list=id_list+[id(self)]),l=(lvl+1)*8)) - elif type(el) in scalars: + elif isinstance(el,scalars): if isList(e): out.append('{:>{l}}{:16}\n'.format('',repr(el),l=lvl*8)) else: @@ -48,7 +48,8 @@ class MMGenObject(object): elif isList(el) or isDict(el): indent = 1 if is_dict else lvl*8+4 out.append('{:>{l}}{:16}'.format('','<'+type(el).__name__+'>',l=indent)) - if isList(el) and type(el[0]) in scalars: out.append('\n') + if isList(el) and isinstance(el[0],scalars): + out.append('\n') do_list(out,el,lvl=lvl+1,is_dict=isDict(el)) else: out.append('{:>{l}}{:16} {}\n'.format('','<'+type(el).__name__+'>',repr(el),l=(lvl*8)+8)) @@ -57,11 +58,11 @@ class MMGenObject(object): from collections import OrderedDict def isDict(obj): - return issubclass(type(obj),dict) or issubclass(type(obj),OrderedDict) + return isinstance(obj,dict) def isList(obj): - return issubclass(type(obj),list) and type(obj) != OrderedDict + return isinstance(obj,list) def isScalar(obj): - return any(issubclass(type(obj),t) for t in scalars) + return isinstance(obj,scalars) # print type(self) # print dir(self) diff --git a/mmgen/filename.py b/mmgen/filename.py index c256bc26..9da6b5a0 100755 --- a/mmgen/filename.py +++ b/mmgen/filename.py @@ -40,7 +40,7 @@ class Filename(MMGenObject): from mmgen.tx import MMGenTX if ftype: if type(ftype) == type: - if issubclass(ftype,SeedSource) or issubclass(ftype,MMGenTX): + if issubclass(ftype,(SeedSource,MMGenTX)): self.ftype = ftype # elif: # other MMGen file types else: diff --git a/mmgen/obj.py b/mmgen/obj.py index 3fcb7d7e..7798dc33 100755 --- a/mmgen/obj.py +++ b/mmgen/obj.py @@ -137,7 +137,7 @@ class Hilite(object): center=False,nullrepl='',append_chars='',append_color=False): if cls.dtype == bytes: s = s.decode() s_wide_count = len([1 for ch in s if unicodedata.east_asian_width(ch) in ('F','W')]) - assert type(encl) is str and len(encl) in (0,2),"'encl' must be 2-character str" + assert isinstance(encl,str) and len(encl) in (0,2),"'encl' must be 2-character str" a,b = list(encl) if encl else ('','') add_len = len(a) + len(b) + len(append_chars) if width == None: width = cls.width @@ -188,7 +188,7 @@ class MMGenImmutableAttr(object): # Descriptor def __init__(self,name,dtype,typeconv=True,no_type_check=False): self.typeconv = typeconv self.no_type_check = no_type_check - assert type(dtype) in (str,type) or dtype is None + assert isinstance(dtype,(str,type,type(None))),'{!r}: invalid dtype arg'.format(dtype) self.name = name self.dtype = dtype @@ -328,7 +328,7 @@ class MMGenRange(tuple,InitErrors,MMGenObject): if len(args) == 1: s = args[0] if type(s) == cls: return s - assert issubclass(type(s),str),'not a string or string subclass' + assert isinstance(s,str),'not a string or string subclass' ss = s.split('-',1) first = int(ss[0]) last = int(ss.pop()) @@ -384,7 +384,7 @@ class BTCAmt(Decimal,Hilite,InitErrors): if from_unit: assert from_unit in cls.units,( "'{}': unrecognized denomination for {}".format(from_unit,cls.__name__)) - assert type(num) == int,'value is not an integer or long integer' + assert type(num) == int,'value is not an integer' me = Decimal.__new__(cls,num * getattr(cls,from_unit)) elif from_decimal: assert type(num) == Decimal,( @@ -542,7 +542,7 @@ class SeedID(str,Hilite,InitErrors): try: if seed: from mmgen.seed import SeedBase - assert issubclass(type(seed),SeedBase),'not a subclass of SeedBase' + assert isinstance(seed,SeedBase),'not a subclass of SeedBase' from mmgen.util import make_chksum_8 return str.__new__(cls,make_chksum_8(seed.data)) elif sid: @@ -560,7 +560,7 @@ class SubSeedIdx(str,Hilite,InitErrors): if type(s) == cls: return s cls.arg_chk(on_fail) try: - assert issubclass(type(s),str),'not a string or string subclass' + assert isinstance(s,str),'not a string or string subclass' idx = s[:-1] if s[-1] in 'SsLl' else s from mmgen.util import is_int assert is_int(idx),"valid format: an integer, plus optional letter 'S','s','L' or 'l'" @@ -653,7 +653,7 @@ class HexStr(str,Hilite,InitErrors): cls.arg_chk(on_fail) if case == None: case = cls.hexcase try: - assert issubclass(type(s),str),'not a string or string subclass' + 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 not len(s) % 2,'odd-length string' @@ -749,8 +749,9 @@ class AddrListID(str,Hilite,InitErrors,MMGenObject): cls.arg_chk(on_fail) try: assert type(sid) == SeedID,"{!r} not a SeedID instance".format(sid) - t = MMGenAddrType,MMGenPasswordType - assert type(mmtype) in t,"{!r} not an instance of {}".format(mmtype,','.join([i.__name__ for i in t])) + if not isinstance(mmtype,(MMGenAddrType,MMGenPasswordType)): + m = '{!r}: not an instance of MMGenAddrType or MMGenPasswordType'.format(mmtype) + raise ValueError(m.format(mmtype)) me = str.__new__(cls,sid+':'+mmtype) me.sid = sid me.mmtype = mmtype diff --git a/mmgen/sha2.py b/mmgen/sha2.py index f2c912cf..1ed00f7a 100755 --- a/mmgen/sha2.py +++ b/mmgen/sha2.py @@ -67,7 +67,7 @@ class Sha2(object): def __init__(self,message,preprocess=True): 'Use preprocess=False for Sha256Compress' - assert type(message) in (bytes,bytearray,list),'message must be of type bytes, bytearray or list' + assert isinstance(message,(bytes,bytearray,list)),'message must be of type bytes, bytearray or list' if self.K == None: type(self).initConstants() self.H = list(self.H_init) diff --git a/mmgen/tool.py b/mmgen/tool.py index 1f8444fa..14f7bc9f 100755 --- a/mmgen/tool.py +++ b/mmgen/tool.py @@ -160,7 +160,7 @@ def _process_args(cmd,cmd_args): if arg_type == 'bytes' and type(arg) != bytes: die(1,"'Binary input data must be supplied via STDIN") - if have_stdin_input and arg_type == 'str' and type(arg) == bytes: + if have_stdin_input and arg_type == 'str' and isinstance(arg,bytes): arg = arg.decode() if arg[-len(NL):] == NL: # rstrip one newline arg = arg[:-len(NL)] @@ -199,13 +199,13 @@ def _process_result(ret,pager=False,print_result=False): return True elif ret in (False,None): ydie(1,"tool command returned '{}'".format(ret)) - elif issubclass(type(ret),str): + elif isinstance(ret,str): return triage_result(ret) - elif issubclass(type(ret),int): + elif isinstance(ret,int): return triage_result(str(ret)) - elif type(ret) == tuple: - return triage_result('\n'.join([r.decode() if issubclass(type(r),bytes) else r for r in ret])) - elif issubclass(type(ret),bytes): + elif isinstance(ret,tuple): + return triage_result('\n'.join([r.decode() if isinstance(r,bytes) else r for r in ret])) + elif isinstance(ret,bytes): try: o = ret.decode() return o if not print_result else do_pager(o) if pager else Msg(o) diff --git a/mmgen/tx.py b/mmgen/tx.py index 10a2dc0f..ec24a707 100755 --- a/mmgen/tx.py +++ b/mmgen/tx.py @@ -681,7 +681,7 @@ Selected non-{pnm} inputs: {{}}""".strip().format(pnm=g.proj_name,pnl=g.proj_nam return int(bytes.fromhex(self.hex[-8:])[::-1].hex(),16) def set_hex_locktime(self,val): - assert type(val) == int,'locktime value not an integer' + assert isinstance(val,int),'locktime value not an integer' self.hex = self.hex[:-8] + bytes.fromhex('{:08x}'.format(val))[::-1].hex() def get_blockcount(self): @@ -1435,7 +1435,7 @@ Selected non-{pnm} inputs: {{}}""".strip().format(pnm=g.proj_name,pnl=g.proj_nam self.send_amt = change_amt def create(self,cmd_args,locktime,do_info=False): - assert type(locktime) == int + assert isinstance(locktime,int),'locktime must be of type int' if opt.comment_file: self.add_comment(opt.comment_file) diff --git a/mmgen/util.py b/mmgen/util.py index a4ff7e90..5b3462a9 100755 --- a/mmgen/util.py +++ b/mmgen/util.py @@ -66,22 +66,22 @@ def mdie(*args): mmsg(*args); sys.exit(0) def die_wait(delay,ev=0,s=''): - assert type(delay) == int - assert type(ev) == int + assert isinstance(delay,int) + assert isinstance(ev,int) if s: msg(s) time.sleep(delay) sys.exit(ev) def die_pause(ev=0,s=''): - assert type(ev) == int + assert isinstance(ev,int) if s: msg(s) input('Press ENTER to exit') sys.exit(ev) def die(ev=0,s=''): - assert type(ev) == int + assert isinstance(ev,int) if s: msg(s) sys.exit(ev) def Die(ev=0,s=''): - assert type(ev) == int + assert isinstance(ev,int) if s: Msg(s) sys.exit(ev) @@ -177,11 +177,10 @@ def dmsg(s): def suf(arg,suf_type='s'): suf_types = { 's': '', 'es': '', 'ies': 'y' } - assert suf_type in suf_types - t = type(arg) - if t == int: + assert suf_type in suf_types,'invalid suffix type' + if isinstance(arg,int): n = arg - elif any(issubclass(t,c) for c in (list,tuple,set,dict)): + elif isinstance(arg,(list,tuple,set,dict)): n = len(arg) else: die(2,'{}: invalid parameter for suf()'.format(arg)) @@ -196,7 +195,7 @@ def remove_extension(f,e): return (f,a)[len(b)>1 and b[1:]==e] def make_chksum_N(s,nchars,sep=False): - if type(s) == str: s = s.encode() + if isinstance(s,str): s = s.encode() if nchars%4 or not (4 <= nchars <= 64): return False s = sha256(sha256(s).digest()).hexdigest().upper() sep = ('',' ')[bool(sep)] @@ -208,7 +207,7 @@ def make_chksum_8(s,sep=False): return '{} {}'.format(s[:4],s[4:]) if sep else s def make_chksum_6(s): from mmgen.obj import HexStr - if type(s) == str: s = s.encode() + if isinstance(s,str): s = s.encode() return HexStr(sha256(s).hexdigest()[:6]) def is_chksum_6(s): return len(s) == 6 and is_hex_str_lc(s) @@ -301,23 +300,25 @@ class baseconv(object): @classmethod def b58encode(cls,s,pad=None): - pad = cls.get_pad(s,pad,'en',cls.b58pad_lens,[bytes]) + pad = cls.get_pad(s,pad,'b58encode',cls.b58pad_lens,(bytes,)) return cls.fromhex(s.hex(),'b58',pad=pad,tostr=True) @classmethod def b58decode(cls,s,pad=None): - pad = cls.get_pad(s,pad,'de',cls.b58pad_lens_rev,[bytes,str]) + pad = cls.get_pad(s,pad,'b58decode',cls.b58pad_lens_rev,(bytes,str)) return bytes.fromhex(cls.tohex(s,'b58',pad=pad*2 if pad else None)) @staticmethod - def get_pad(s,pad,op,pad_map,ok_types): - m = "b58{}code() input must be one of {}, not '{}'" - assert type(s) in ok_types, m.format(op,repr([t.__name__ for t in ok_types]),type(s).__name__) + def get_pad(s,pad,op_desc,pad_map,ok_types): + if not isinstance(s,ok_types): + m = "{}() input must be one of {}, not '{}'" + raise ValueError(m.format(op_desc,repr([t.__name__ for t in ok_types]),type(s).__name__)) if pad: - assert type(pad) == bool, "'pad' must be boolean type" + assert type(pad) == bool,"'pad' must be boolean type" d = dict(pad_map) - m = 'Invalid data length for b58{}code(pad=True) (must be one of {})' - assert len(s) in d, m.format(op,repr([e[0] for e in pad_map])) + if not len(s) in d: + m = 'Invalid data length for {}(pad=True) (must be one of {})' + raise ValueError(m.format(op_desc,repr([e[0] for e in pad_map]))) return d[len(s)] else: return None @@ -347,7 +348,7 @@ class baseconv(object): @classmethod def tohex(cls,words_arg,wl_id,pad=None): - words = words_arg if type(words_arg) in (list,tuple) else tuple(words_arg.strip()) + words = words_arg if isinstance(words_arg,(list,tuple)) else tuple(words_arg.strip()) wl = cls.digits[wl_id] base = len(wl) @@ -604,7 +605,7 @@ def write_data_to_file( outfile,data,desc='data', import msvcrt msvcrt.setmode(sys.stdout.fileno(),os.O_BINARY) - sys.stdout.write(data.decode() if issubclass(type(data),bytes) else data) + sys.stdout.write(data.decode() if isinstance(data,bytes) else data) def do_file(outfile,ask_write_prompt): if opt.outdir and not ignore_opt_outdir and not os.path.isabs(outfile): diff --git a/test/objtest.py b/test/objtest.py index 1e31c927..a18ced35 100755 --- a/test/objtest.py +++ b/test/objtest.py @@ -86,8 +86,8 @@ def run_test(test,arg,input_data): ret = cls(*args,**kwargs) bad_ret = list() if issubclass(cls,list) else None - if issubclass(type(ret_chk),str): ret_chk = ret_chk.encode() - if issubclass(type(ret),str): ret = ret.encode() + if isinstance(ret_chk,str): ret_chk = ret_chk.encode() + if isinstance(ret,str): ret = ret.encode() if (opt.silent and input_data=='bad' and ret!=bad_ret) or (not opt.silent and input_data=='bad'): raise UserWarning("Non-'None' return value {} with bad input data".format(repr(ret))) @@ -102,8 +102,9 @@ def run_test(test,arg,input_data): except Exception as e: if not type(e).__name__ == exc_type: raise - msg_r(' {}'.format(yellow(exc_type+':'))) - msg(e.args[0]) + if not opt.super_silent: + msg_r(' {}'.format(yellow(exc_type+':'))) + msg(e.args[0]) except SystemExit as e: if input_data == 'good': raise ValueError('Error on good input data') diff --git a/test/tooltest2.py b/test/tooltest2.py index da696e7c..f10438a5 100755 --- a/test/tooltest2.py +++ b/test/tooltest2.py @@ -671,12 +671,12 @@ def run_test(gid,cmd_name): continue cmd_out = run_func(cmd_name,args,out,opts,exec_code) - vmsg('Output: {}\n'.format(cmd_out if issubclass(type(out),str) else repr(cmd_out))) + vmsg('Output: {}\n'.format(cmd_out if isinstance(out,str) else repr(cmd_out))) def check_output(cmd_out,out): - if issubclass(type(out),str): out = out.encode() - if issubclass(type(cmd_out),int): cmd_out = str(cmd_out).encode() - if issubclass(type(cmd_out),str): cmd_out = cmd_out.encode() + if isinstance(out,str): out = out.encode() + if isinstance(cmd_out,int): cmd_out = str(cmd_out).encode() + if isinstance(cmd_out,str): cmd_out = cmd_out.encode() if type(out).__name__ == 'function': assert out(cmd_out.decode()),"{}({}) failed!".format(out.__name__,cmd_out.decode()) @@ -694,7 +694,7 @@ def run_test(gid,cmd_name): func_out = out[0](cmd_out) assert func_out == out[1],( "{}({}) == {} failed!\nOutput: {}".format(out[0].__name__,cmd_out,out[1],func_out)) - elif type(out) in (list,tuple): + elif isinstance(out,(list,tuple)): for co,o in zip(cmd_out.split(NL) if opt.fork else cmd_out,out): check_output(co,o) else: