Browse Source

issubclass -> isinstance and related cleanups

MMGen 5 years ago
parent
commit
94e02995de
12 changed files with 61 additions and 57 deletions
  1. 1 1
      mmgen/addr.py
  2. 1 1
      mmgen/altcoins/eth/tx.py
  3. 1 1
      mmgen/crypto.py
  4. 6 5
      mmgen/devtools.py
  5. 1 1
      mmgen/filename.py
  6. 10 9
      mmgen/obj.py
  7. 1 1
      mmgen/sha2.py
  8. 6 6
      mmgen/tool.py
  9. 2 2
      mmgen/tx.py
  10. 22 21
      mmgen/util.py
  11. 5 4
      test/objtest.py
  12. 5 5
      test/tooltest2.py

+ 1 - 1
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)

+ 1 - 1
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

+ 1 - 1
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

+ 6 - 5
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)

+ 1 - 1
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:

+ 10 - 9
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

+ 1 - 1
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)

+ 6 - 6
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)

+ 2 - 2
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)
 

+ 22 - 21
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):

+ 5 - 4
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')

+ 5 - 5
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: