Browse Source

whitespace: cmdtest_d

The MMGen Project 1 year ago
parent
commit
9bc284ae24

+ 191 - 178
test/cmdtest_py_d/cfg.py

@@ -12,203 +12,217 @@
 test.cmdtest_py_d.cfg: configuration data for cmdtest.py
 test.cmdtest_py_d.cfg: configuration data for cmdtest.py
 """
 """
 
 
-from .common import pwfile,hincog_fn,incog_id_fn,randbool
+from .common import pwfile, hincog_fn, incog_id_fn, randbool
 from ..include.common import cfg
 from ..include.common import cfg
 
 
-cmd_groups_altcoin = ['ref_altcoin','autosign','ethdev','xmrwallet','xmr_autosign']
+cmd_groups_altcoin = ['ref_altcoin', 'autosign', 'ethdev', 'xmrwallet', 'xmr_autosign']
 
 
 cmd_groups_dfl = {
 cmd_groups_dfl = {
-	'misc':             ('CmdTestMisc',{}),
-	'opts':             ('CmdTestOpts',{'full_data':True}),
-	'cfgfile':          ('CmdTestCfgFile',{'full_data':True}),
-	'help':             ('CmdTestHelp',{'full_data':True}),
-	'main':             ('CmdTestMain',{'full_data':True}),
-	'conv':             ('CmdTestWalletConv',{'is3seed':True,'modname':'wallet'}),
-	'ref':              ('CmdTestRef',{}),
-	'ref3':             ('CmdTestRef3Seed',{'is3seed':True,'modname':'ref_3seed'}),
-	'ref3_addr':        ('CmdTestRef3Addr',{'is3seed':True,'modname':'ref_3seed'}),
-	'ref3_pw':          ('CmdTestRef3Passwd',{'is3seed':True,'modname':'ref_3seed'}),
-	'ref_altcoin':      ('CmdTestRefAltcoin',{}),
-	'seedsplit':        ('CmdTestSeedSplit',{}),
-	'tool':             ('CmdTestTool',{'full_data':True}),
-	'input':            ('CmdTestInput',{}),
-	'output':           ('CmdTestOutput',{'modname':'misc','full_data':True}),
-	'autosign_clean':   ('CmdTestAutosignClean', {'modname':'autosign'}),
-	'autosign':         ('CmdTestAutosign',{}),
-	'autosign_automount': ('CmdTestAutosignAutomount', {'modname':'automount'}),
-	'autosign_eth':     ('CmdTestAutosignETH', {'modname':'automount_eth'}),
-	'regtest':          ('CmdTestRegtest',{}),
-#	'chainsplit':       ('CmdTestChainsplit',{}),
-	'ethdev':           ('CmdTestEthdev',{}),
-	'xmrwallet':        ('CmdTestXMRWallet',{}),
-	'xmr_autosign':     ('CmdTestXMRAutosign',{}),
+	'misc':               ('CmdTestMisc',              {}),
+	'opts':               ('CmdTestOpts',              {'full_data': True}),
+	'cfgfile':            ('CmdTestCfgFile',           {'full_data': True}),
+	'help':               ('CmdTestHelp',              {'full_data': True}),
+	'main':               ('CmdTestMain',              {'full_data': True}),
+	'conv':               ('CmdTestWalletConv',        {'is3seed': True, 'modname': 'wallet'}),
+	'ref':                ('CmdTestRef',               {}),
+	'ref3':               ('CmdTestRef3Seed',          {'is3seed': True, 'modname': 'ref_3seed'}),
+	'ref3_addr':          ('CmdTestRef3Addr',          {'is3seed': True, 'modname': 'ref_3seed'}),
+	'ref3_pw':            ('CmdTestRef3Passwd',        {'is3seed': True, 'modname': 'ref_3seed'}),
+	'ref_altcoin':        ('CmdTestRefAltcoin',        {}),
+	'seedsplit':          ('CmdTestSeedSplit',         {}),
+	'tool':               ('CmdTestTool',              {'full_data': True}),
+	'input':              ('CmdTestInput',             {}),
+	'output':             ('CmdTestOutput',            {'modname': 'misc', 'full_data': True}),
+	'autosign_clean':     ('CmdTestAutosignClean',     {'modname': 'autosign'}),
+	'autosign':           ('CmdTestAutosign',          {}),
+	'autosign_automount': ('CmdTestAutosignAutomount', {'modname': 'automount'}),
+	'autosign_eth':       ('CmdTestAutosignETH',       {'modname': 'automount_eth'}),
+	'regtest':            ('CmdTestRegtest',           {}),
+	# 'chainsplit':         ('CmdTestChainsplit',      {}),
+	'ethdev':             ('CmdTestEthdev',            {}),
+	'xmrwallet':          ('CmdTestXMRWallet',         {}),
+	'xmr_autosign':       ('CmdTestXMRAutosign',       {}),
 }
 }
 
 
 cmd_groups_extra = {
 cmd_groups_extra = {
-	'dev':                    ('CmdTestDev',{'modname':'misc'}),
-	'regtest_legacy':         ('CmdTestRegtestBDBWallet', {'modname':'regtest'}),
-	'autosign_btc':           ('CmdTestAutosignBTC',{'modname':'autosign'}),
-	'autosign_live':          ('CmdTestAutosignLive',{'modname':'autosign'}),
-	'autosign_live_simulate': ('CmdTestAutosignLiveSimulate',{'modname':'autosign'}),
-	'create_ref_tx':          ('CmdTestRefTX',{'modname':'misc','full_data':True}),
+	'dev':                    ('CmdTestDev',                  {'modname': 'misc'}),
+	'regtest_legacy':         ('CmdTestRegtestBDBWallet',     {'modname': 'regtest'}),
+	'autosign_btc':           ('CmdTestAutosignBTC',          {'modname': 'autosign'}),
+	'autosign_live':          ('CmdTestAutosignLive',         {'modname': 'autosign'}),
+	'autosign_live_simulate': ('CmdTestAutosignLiveSimulate', {'modname': 'autosign'}),
+	'create_ref_tx':          ('CmdTestRefTX',                {'modname': 'misc', 'full_data': True}),
 }
 }
 
 
-cfgs = { # addr_idx_lists (except 31,32,33,34) must contain exactly 8 addresses
-	'1':  { 'wpasswd':       'Dorian-α',
-			'kapasswd':      'Grok the blockchain',
-			'addr_idx_list': '12,99,5-10,5,12',
-			'dep_generators':  {
-				pwfile:        'walletgen',
-				'mmdat':       'walletgen',
-				'addrs':       'addrgen',
-				'rawtx':       'txcreate',
-				'txbump':      'txbump',
-				'sigtx':       'txsign',
-				'mmwords':     'export_mnemonic',
-				'mmseed':      'export_seed',
-				'mmhex':       'export_hex',
-				'mmincog':     'export_incog',
-				'mmincox':     'export_incog_hex',
-				hincog_fn:     'export_incog_hidden',
-				incog_id_fn:   'export_incog_hidden',
-				'akeys.mmenc': 'keyaddrgen'
-			},
+cfgs = { # addr_idx_lists (except 31, 32, 33, 34) must contain exactly 8 addresses
+	'1': {
+		'wpasswd':       'Dorian-α',
+		'kapasswd':      'Grok the blockchain',
+		'addr_idx_list': '12,99,5-10,5,12',
+		'dep_generators': {
+			pwfile:        'walletgen',
+			'mmdat':       'walletgen',
+			'addrs':       'addrgen',
+			'rawtx':       'txcreate',
+			'txbump':      'txbump',
+			'sigtx':       'txsign',
+			'mmwords':     'export_mnemonic',
+			'mmseed':      'export_seed',
+			'mmhex':       'export_hex',
+			'mmincog':     'export_incog',
+			'mmincox':     'export_incog_hex',
+			hincog_fn:     'export_incog_hidden',
+			incog_id_fn:   'export_incog_hidden',
+			'akeys.mmenc': 'keyaddrgen'
+		},
 	},
 	},
-	'2':  { 'wpasswd':       'Hodling away',
-			'addr_idx_list': '37,45,3-6,22-23',
-			'seed_len':      128,
-			'dep_generators': {
-				'mmdat':   'walletgen2',
-				'addrs':   'addrgen2',
-				'rawtx':   'txcreate2',
-				'sigtx':   'txsign2',
-				'mmwords': 'export_mnemonic2',
-			},
+	'2': {
+		'wpasswd':       'Hodling away',
+		'addr_idx_list': '37,45,3-6,22-23',
+		'seed_len':      128,
+		'dep_generators': {
+			'mmdat':   'walletgen2',
+			'addrs':   'addrgen2',
+			'rawtx':   'txcreate2',
+			'sigtx':   'txsign2',
+			'mmwords': 'export_mnemonic2',
+		},
 	},
 	},
-	'3':  { 'wpasswd':       'Major miner',
-			'addr_idx_list': '73,54,1022-1023,2-5',
-			'dep_generators': {
-				'mmdat': 'walletgen3',
-				'addrs': 'addrgen3',
-				'rawtx': 'txcreate3',
-				'sigtx': 'txsign3'
-			},
+	'3': {
+		'wpasswd':       'Major miner',
+		'addr_idx_list': '73,54,1022-1023,2-5',
+		'dep_generators': {
+			'mmdat': 'walletgen3',
+			'addrs': 'addrgen3',
+			'rawtx': 'txcreate3',
+			'sigtx': 'txsign3'
+		},
 	},
 	},
-	'4':  { 'wpasswd':       'Hashrate good',
-			'addr_idx_list': '63,1004,542-544,7-9',
-			'seed_len':      192,
-			'dep_generators': {
-				'mmdat':   'walletgen4',
-				'mmbrain': 'walletgen4',
-				'addrs':   'addrgen4',
-				'rawtx':   'txcreate4',
-				'sigtx':   'txsign4',
-				'txdo':    'txdo4',
-			},
-			'bw_filename': 'brainwallet.mmbrain',
-			'bw_params':   '192,1',
+	'4': {
+		'wpasswd':       'Hashrate good',
+		'addr_idx_list': '63,1004,542-544,7-9',
+		'seed_len':      192,
+		'dep_generators': {
+			'mmdat':   'walletgen4',
+			'mmbrain': 'walletgen4',
+			'addrs':   'addrgen4',
+			'rawtx':   'txcreate4',
+			'sigtx':   'txsign4',
+			'txdo':    'txdo4',
+		},
+		'bw_filename': 'brainwallet.mmbrain',
+		'bw_params':   '192,1',
 	},
 	},
-	'5':  { 'wpasswd':     'My changed password-α',
-			'hash_preset': '2',
-			'dep_generators': {
-				'mmdat': 'passchg',
-				pwfile:  'passchg',
-			},
+	'5': {
+		'wpasswd':     'My changed password-α',
+		'hash_preset': '2',
+		'dep_generators': {
+			'mmdat': 'passchg',
+			pwfile:  'passchg',
+		},
 	},
 	},
-	'6':  { 'seed_len':       128,
-			'seed_id':        'FE3C6545',
-			'ref_bw_seed_id': '33F10310',
-			'wpasswd':        'reference password',
-			'kapasswd':      '',
-			'dep_generators':  {
-				'mmdat':       'ref_walletgen_brain_1',
-				pwfile:        'ref_walletgen_brain_1',
-				'addrs':       'refaddrgen_1',
-				'akeys.mmenc': 'refkeyaddrgen_1'
-			},
+	'6': {
+		'seed_len':       128,
+		'seed_id':        'FE3C6545',
+		'ref_bw_seed_id': '33F10310',
+		'wpasswd':        'reference password',
+		'kapasswd':      '',
+		'dep_generators': {
+			'mmdat':       'ref_walletgen_brain_1',
+			pwfile:        'ref_walletgen_brain_1',
+			'addrs':       'refaddrgen_1',
+			'akeys.mmenc': 'refkeyaddrgen_1'
+		},
 	},
 	},
-	'7':  { 'seed_len':       192,
-			'seed_id':        '1378FC64',
-			'ref_bw_seed_id': 'CE918388',
-			'wpasswd':        'reference password',
-			'kapasswd':      '',
-			'dep_generators':  {
-				'mmdat':       'ref_walletgen_brain_2',
-				pwfile:        'ref_walletgen_brain_2',
-				'addrs':       'refaddrgen_2',
-				'akeys.mmenc': 'refkeyaddrgen_2'
-			},
+	'7': {
+		'seed_len':       192,
+		'seed_id':        '1378FC64',
+		'ref_bw_seed_id': 'CE918388',
+		'wpasswd':        'reference password',
+		'kapasswd':      '',
+		'dep_generators': {
+			'mmdat':       'ref_walletgen_brain_2',
+			pwfile:        'ref_walletgen_brain_2',
+			'addrs':       'refaddrgen_2',
+			'akeys.mmenc': 'refkeyaddrgen_2'
+		},
 	},
 	},
-	'8':  { 'seed_len':       256,
-			'seed_id':        '98831F3A',
-			'ref_bw_seed_id': 'B48CD7FC',
-			'wpasswd':        'reference password',
-			'kapasswd':      '',
-			'dep_generators':  {
-				'mmdat':       'ref_walletgen_brain_3',
-				pwfile:        'ref_walletgen_brain_3',
-				'addrs':       'refaddrgen_3',
-				'akeys.mmenc': 'refkeyaddrgen_3'
-			},
+	'8': {
+		'seed_len':       256,
+		'seed_id':        '98831F3A',
+		'ref_bw_seed_id': 'B48CD7FC',
+		'wpasswd':        'reference password',
+		'kapasswd':      '',
+		'dep_generators': {
+			'mmdat':       'ref_walletgen_brain_3',
+			pwfile:        'ref_walletgen_brain_3',
+			'addrs':       'refaddrgen_3',
+			'akeys.mmenc': 'refkeyaddrgen_3'
+		},
 	},
 	},
-	'9':  { 'tool_enc_infn': 'tool_encrypt.in',
-			'dep_generators': {
-				'tool_encrypt.in':       'tool_encrypt',
-				'tool_encrypt.in.mmenc': 'tool_encrypt',
-			},
+	'9': {
+		'tool_enc_infn': 'tool_encrypt.in',
+		'dep_generators': {
+			'tool_encrypt.in':       'tool_encrypt',
+			'tool_encrypt.in.mmenc': 'tool_encrypt',
+		},
 	},
 	},
 	'11': {}, # wallet
 	'11': {}, # wallet
 	'12': {}, # wallet
 	'12': {}, # wallet
 	'13': {}, # wallet
 	'13': {}, # wallet
-	'14': { 'kapasswd':      'Maxwell',
-			'wpasswd':       'The Halving',
-			'addr_idx_list': '61,998,502-504,7-9',
-			'seed_len':      256,
-			'dep_generators': {
-				'mmdat':       'walletgen14',
-				'addrs':       'addrgen14',
-				'akeys.mmenc': 'keyaddrgen14',
-			},
+	'14': {
+		'kapasswd':      'Maxwell',
+		'wpasswd':       'The Halving',
+		'addr_idx_list': '61,998,502-504,7-9',
+		'seed_len':      256,
+		'dep_generators': {
+			'mmdat':       'walletgen14',
+			'addrs':       'addrgen14',
+			'akeys.mmenc': 'keyaddrgen14',
+		},
 	},
 	},
-	'15': { 'wpasswd':       'Dorian-α',
-			'kapasswd':      'Grok the blockchain',
-			'addr_idx_list': '12,99,5-10,5,12',
-			'dep_generators':  {
-				pwfile:       'walletgen_dfl_wallet',
-				'addrs':      'addrgen_dfl_wallet',
-				'rawtx':      'txcreate_dfl_wallet',
-				'sigtx':      'txsign_dfl_wallet',
-				'mmseed':     'export_seed_dfl_wallet',
-				'del_dw_run': 'delete_dfl_wallet',
-			},
+	'15': {
+		'wpasswd':       'Dorian-α',
+		'kapasswd':      'Grok the blockchain',
+		'addr_idx_list': '12,99,5-10,5,12',
+		'dep_generators': {
+			pwfile:       'walletgen_dfl_wallet',
+			'addrs':      'addrgen_dfl_wallet',
+			'rawtx':      'txcreate_dfl_wallet',
+			'sigtx':      'txsign_dfl_wallet',
+			'mmseed':     'export_seed_dfl_wallet',
+			'del_dw_run': 'delete_dfl_wallet',
+		},
 	},
 	},
-	'16': { 'wpasswd':     'My changed password',
-			'hash_preset': '2',
-			'dep_generators': {
-				pwfile: 'passchg_dfl_wallet',
-			},
+	'16': {
+		'wpasswd':     'My changed password',
+		'hash_preset': '2',
+		'dep_generators': {
+			pwfile: 'passchg_dfl_wallet',
+		},
 	},
 	},
 	'17': {}, # regtest
 	'17': {}, # regtest
 	'18': {}, # autosign
 	'18': {}, # autosign
-	'19': { 'wpasswd':'abc' },
-	'20': { 'wpasswd':       'Vsize it',
-			'addr_idx_list': '1-8',
-			'seed_len':      256,
-			'dep_generators': {
-				'mmdat': 'walletgen5',
-				'addrs': 'addrgen5',
-				'rawtx': 'txcreate5',
-				'sigtx': 'txsign5',
+	'19': {'wpasswd': 'abc'},
+	'20': {
+		'wpasswd':       'Vsize it',
+		'addr_idx_list': '1-8',
+		'seed_len':      256,
+		'dep_generators': {
+			'mmdat': 'walletgen5',
+			'addrs': 'addrgen5',
+			'rawtx': 'txcreate5',
+			'sigtx': 'txsign5',
 		},
 		},
 	},
 	},
-	'21': { 'wpasswd':       'Vsize it',
-			'addr_idx_list': '1-8',
-			'seed_len':      256,
-			'dep_generators': {
-				'mmdat': 'walletgen6',
-				'addrs': 'addrgen6',
-				'rawtx': 'txcreate6',
-				'sigtx': 'txsign6',
+	'21': {
+		'wpasswd':       'Vsize it',
+		'addr_idx_list': '1-8',
+		'seed_len':      256,
+		'dep_generators': {
+			'mmdat': 'walletgen6',
+			'addrs': 'addrgen6',
+			'rawtx': 'txcreate6',
+			'sigtx': 'txsign6',
 		},
 		},
 	},
 	},
 	'22': {}, # ethdev
 	'22': {}, # ethdev
@@ -236,16 +250,15 @@ def fixup_cfgs():
 	for k in cfgs:
 	for k in cfgs:
 		cfgs[k]['tmpdir'] = os.path.join('test', 'tmp', str(k))
 		cfgs[k]['tmpdir'] = os.path.join('test', 'tmp', str(k))
 
 
-	for src,target in (
-			('6','11'),
-			('7','12'),
-			('8','13'),
-			('6','26'),
-			('7','27'),
-			('8','28')
-		):
+	for src, target in (
+			('6', '11'),
+			('7', '12'),
+			('8', '13'),
+			('6', '26'),
+			('7', '27'),
+			('8', '28')):
 		cfgs[target].update(cfgs[src])
 		cfgs[target].update(cfgs[src])
-		cfgs[target]['tmpdir'] = os.path.join('test','tmp',target)
+		cfgs[target]['tmpdir'] = os.path.join('test', 'tmp', target)
 
 
 	for k in cfgs:
 	for k in cfgs:
 		cfgs[k]['segwit'] = randbool() if cfg.segwit_random else bool(cfg.segwit or cfg.bech32)
 		cfgs[k]['segwit'] = randbool() if cfg.segwit_random else bool(cfg.segwit or cfg.bech32)

+ 38 - 31
test/cmdtest_py_d/common.py

@@ -20,12 +20,12 @@
 test.cmdtest_py_d.common: Shared routines and data for the cmdtest.py test suite
 test.cmdtest_py_d.common: Shared routines and data for the cmdtest.py test suite
 """
 """
 
 
-import sys,os
+import sys, os
 
 
 from mmgen.color import green, blue, gray
 from mmgen.color import green, blue, gray
 from mmgen.util import msg
 from mmgen.util import msg
 
 
-from ..include.common import cfg,getrand,text_jp,text_zh,ascii_cyr_gr,lat_cyr_gr
+from ..include.common import cfg, getrand, text_jp, text_zh, ascii_cyr_gr, lat_cyr_gr
 
 
 rt_pw = 'abc-α'
 rt_pw = 'abc-α'
 ref_wallet_brainpass = 'abc'
 ref_wallet_brainpass = 'abc'
@@ -45,11 +45,11 @@ hincog_seedlen = 256
 incog_id_fn = 'incog_id'
 incog_id_fn = 'incog_id'
 non_mmgen_fn = 'coinkey'
 non_mmgen_fn = 'coinkey'
 
 
-ref_dir = os.path.join('test','ref')
-dfl_words_file = os.path.join(ref_dir,'98831F3A.mmwords')
-dfl_bip39_file = os.path.join(ref_dir,'98831F3A.bip39')
+ref_dir = os.path.join('test', 'ref')
+dfl_words_file = os.path.join(ref_dir, '98831F3A.mmwords')
+dfl_bip39_file = os.path.join(ref_dir, '98831F3A.bip39')
 
 
-from mmgen.obj import MMGenTxComment,TwComment
+from mmgen.obj import MMGenTxComment, TwComment
 
 
 tx_comment_jp = text_jp
 tx_comment_jp = text_jp
 tx_comment_zh = text_zh
 tx_comment_zh = text_zh
@@ -75,8 +75,8 @@ def ok_msg():
 		return
 		return
 	sys.stderr.write(green('\nOK\n') if cfg.exact_output or cfg.verbose else ' OK\n')
 	sys.stderr.write(green('\nOK\n') if cfg.exact_output or cfg.verbose else ' OK\n')
 
 
-def skip(name,reason=None):
-	msg(gray('Skipping {}{}'.format( name, f' ({reason})' if reason else '' )))
+def skip(name, reason=None):
+	msg(gray('Skipping {}{}'.format(name, f' ({reason})' if reason else '')))
 	return 'skip'
 	return 'skip'
 
 
 def confirm_continue():
 def confirm_continue():
@@ -85,7 +85,7 @@ def confirm_continue():
 			cfg,
 			cfg,
 			blue('Continue? (Y/n): '),
 			blue('Continue? (Y/n): '),
 			default_yes     = True,
 			default_yes     = True,
-			complete_prompt = True ):
+			complete_prompt = True):
 		if cfg.verbose or cfg.exact_output:
 		if cfg.verbose or cfg.exact_output:
 			sys.stderr.write('\n')
 			sys.stderr.write('\n')
 	else:
 	else:
@@ -101,18 +101,25 @@ def get_env_without_debug_vars():
 			del ret[k]
 			del ret[k]
 	return ret
 	return ret
 
 
-def get_file_with_ext(tdir,ext,delete=True,no_dot=False,return_list=False,delete_all=False,substr=False):
+def get_file_with_ext(
+		tdir,
+		ext,
+		delete      = True,
+		no_dot      = False,
+		return_list = False,
+		delete_all  = False,
+		substr      = False):
 
 
 	dot = '' if no_dot else '.'
 	dot = '' if no_dot else '.'
 
 
 	def have_match(fn):
 	def have_match(fn):
 		return (
 		return (
 			fn == ext
 			fn == ext
-			or fn.endswith( dot + ext )
-			or (substr and ext in fn) )
+			or fn.endswith(dot + ext)
+			or (substr and ext in fn))
 
 
 	# Don’t use os.scandir here - it returns broken paths under Windows/MSYS2
 	# Don’t use os.scandir here - it returns broken paths under Windows/MSYS2
-	flist = [os.path.join(tdir,name) for name in os.listdir(tdir) if have_match(name)]
+	flist = [os.path.join(tdir, name) for name in os.listdir(tdir) if have_match(name)]
 
 
 	if not flist:
 	if not flist:
 		return False
 		return False
@@ -135,26 +142,26 @@ def get_file_with_ext(tdir,ext,delete=True,no_dot=False,return_list=False,delete
 
 
 def get_comment(do_shuffle=False):
 def get_comment(do_shuffle=False):
 	labels = [
 	labels = [
-		"Automotive",
-		"Travel expenses",
-		"Healthcare",
+		'Automotive',
+		'Travel expenses',
+		'Healthcare',
 		tx_comment_jp[:40],
 		tx_comment_jp[:40],
 		tx_comment_zh[:40],
 		tx_comment_zh[:40],
-		"Alice’s allowance",
-		"Bob’s bequest",
-		"House purchase",
-		"Real estate fund",
-		"Job 1",
-		"XYZ Corp.",
-		"Eddie’s endowment",
-		"Emergency fund",
-		"Real estate fund",
-		"Ian’s inheritance",
-		"",
-		"Rainy day",
-		"Fred’s funds",
-		"Job 2",
-		"Carl’s capital",
+		'Alice’s allowance',
+		'Bob’s bequest',
+		'House purchase',
+		'Real estate fund',
+		'Job 1',
+		'XYZ Corp.',
+		'Eddie’s endowment',
+		'Emergency fund',
+		'Real estate fund',
+		'Ian’s inheritance',
+		'',
+		'Rainy day',
+		'Fred’s funds',
+		'Job 2',
+		'Carl’s capital',
 	]
 	]
 	from random import shuffle
 	from random import shuffle
 	global label_iter
 	global label_iter

+ 122 - 122
test/cmdtest_py_d/ct_autosign.py

@@ -21,7 +21,7 @@ test.cmdtest_py_d.ct_autosign: Autosign tests for the cmdtest.py test suite
 """
 """
 
 
 import sys, os, time, shutil, atexit
 import sys, os, time, shutil, atexit
-from subprocess import run,DEVNULL
+from subprocess import run, DEVNULL
 from pathlib import Path
 from pathlib import Path
 
 
 from mmgen.cfg import Config
 from mmgen.cfg import Config
@@ -45,7 +45,7 @@ from ..include.common import (
 	end_silence,
 	end_silence,
 	VirtBlockDevice,
 	VirtBlockDevice,
 )
 )
-from .common import ref_dir,dfl_words_file,dfl_bip39_file
+from .common import ref_dir, dfl_words_file, dfl_bip39_file
 
 
 from .ct_base import CmdTestBase
 from .ct_base import CmdTestBase
 from .input import stealth_mnemonic_entry
 from .input import stealth_mnemonic_entry
@@ -58,9 +58,9 @@ class CmdTestAutosignBase(CmdTestBase):
 	threaded     = False
 	threaded     = False
 	daemon_coins = []
 	daemon_coins = []
 
 
-	def __init__(self,trunner,cfgs,spawn):
+	def __init__(self, trunner, cfgs, spawn):
 
 
-		CmdTestBase.__init__(self,trunner,cfgs,spawn)
+		CmdTestBase.__init__(self, trunner, cfgs, spawn)
 
 
 		if trunner is None:
 		if trunner is None:
 			return
 			return
@@ -89,7 +89,7 @@ class CmdTestAutosignBase(CmdTestBase):
 			self.spawn_env['MMGEN_TEST_SUITE_AUTOSIGN_THREADED'] = '1'
 			self.spawn_env['MMGEN_TEST_SUITE_AUTOSIGN_THREADED'] = '1'
 
 
 	def __del__(self):
 	def __del__(self):
-		if hasattr(self,'have_dummy_control_files'):
+		if hasattr(self, 'have_dummy_control_files'):
 			db = LEDControl.boards['dummy']
 			db = LEDControl.boards['dummy']
 			for fn in (db.status, db.trigger):
 			for fn in (db.status, db.trigger):
 				run(f'sudo rm -f {fn}'.split(), check=True)
 				run(f'sudo rm -f {fn}'.split(), check=True)
@@ -102,13 +102,13 @@ class CmdTestAutosignBase(CmdTestBase):
 				for label in (self.asi.dev_label, self.asi.ramdisk.label):
 				for label in (self.asi.dev_label, self.asi.ramdisk.label):
 					self._macOS_eject_disk(label)
 					self._macOS_eject_disk(label)
 
 
-	def _create_autosign_instances(self,create_dirs):
+	def _create_autosign_instances(self, create_dirs):
 		d = {'offline': {'name':'asi'}}
 		d = {'offline': {'name':'asi'}}
 
 
 		if self.have_online:
 		if self.have_online:
 			d['online'] =  {'name':'asi_online'}
 			d['online'] =  {'name':'asi_online'}
 
 
-		for subdir,data in d.items():
+		for subdir, data in d.items():
 			asi = Autosign(
 			asi = Autosign(
 				Config({
 				Config({
 					'coins': ','.join(self.coins),
 					'coins': ','.join(self.coins),
@@ -164,17 +164,17 @@ class CmdTestAutosignBase(CmdTestBase):
 
 
 	def _macOS_eject_disk(self, label):
 	def _macOS_eject_disk(self, label):
 		try:
 		try:
-			run(['diskutil' ,'eject', label], stdout=DEVNULL, stderr=DEVNULL)
+			run(['diskutil' , 'eject', label], stdout=DEVNULL, stderr=DEVNULL)
 		except:
 		except:
 			pass
 			pass
 
 
 	def start_daemons(self):
 	def start_daemons(self):
-		self.spawn('',msg_only=True)
+		self.spawn('', msg_only=True)
 		start_test_daemons(*self.network_ids)
 		start_test_daemons(*self.network_ids)
 		return 'ok'
 		return 'ok'
 
 
 	def stop_daemons(self):
 	def stop_daemons(self):
-		self.spawn('',msg_only=True)
+		self.spawn('', msg_only=True)
 		stop_test_daemons(*self.network_ids)
 		stop_test_daemons(*self.network_ids)
 		return 'ok'
 		return 'ok'
 
 
@@ -205,16 +205,16 @@ class CmdTestAutosignBase(CmdTestBase):
 			no_passthru_opts = True)
 			no_passthru_opts = True)
 
 
 		if use_dfl_wallet:
 		if use_dfl_wallet:
-			t.expect( 'Use default wallet for autosigning? (Y/n): ', 'y' )
+			t.expect('Use default wallet for autosigning? (Y/n): ', 'y')
 			t.passphrase('MMGen wallet', passwd)
 			t.passphrase('MMGen wallet', passwd)
 		else:
 		else:
 			if use_dfl_wallet is not None: # None => no dfl wallet present
 			if use_dfl_wallet is not None: # None => no dfl wallet present
-				t.expect( 'Use default wallet for autosigning? (Y/n): ', 'n' )
-			mn_file = mn_file or { 'mmgen': dfl_words_file, 'bip39': dfl_bip39_file }[mn_type]
+				t.expect('Use default wallet for autosigning? (Y/n): ', 'n')
+			mn_file = mn_file or {'mmgen': dfl_words_file, 'bip39': dfl_bip39_file}[mn_type]
 			mn = read_from_file(mn_file).strip().split()
 			mn = read_from_file(mn_file).strip().split()
 			if not seed_len:
 			if not seed_len:
-				t.expect('words: ',{ 12:'1', 18:'2', 24:'3' }[len(mn)])
-				t.expect('OK? (Y/n): ','\n')
+				t.expect('words: ', {12:'1', 18:'2', 24:'3'}[len(mn)])
+				t.expect('OK? (Y/n): ', '\n')
 			from mmgen.mn_entry import mn_entry
 			from mmgen.mn_entry import mn_entry
 			entry_mode = 'full'
 			entry_mode = 'full'
 			mne = mn_entry(cfg, mn_type, entry_mode)
 			mne = mn_entry(cfg, mn_type, entry_mode)
@@ -225,7 +225,7 @@ class CmdTestAutosignBase(CmdTestBase):
 					'Type a number.*: ',
 					'Type a number.*: ',
 					str(mne.entry_modes.index(entry_mode) + 1),
 					str(mne.entry_modes.index(entry_mode) + 1),
 					regex = True)
 					regex = True)
-			stealth_mnemonic_entry(t,mne,mn,entry_mode)
+			stealth_mnemonic_entry(t, mne, mn, entry_mode)
 
 
 		t.written_to_file('Autosign wallet')
 		t.written_to_file('Autosign wallet')
 
 
@@ -272,7 +272,7 @@ class CmdTestAutosignBase(CmdTestBase):
 			self._macOS_eject_disk(loc.dev_label)
 			self._macOS_eject_disk(loc.dev_label)
 
 
 	def _mount_ops(self, loc, cmd, *args, **kwargs):
 	def _mount_ops(self, loc, cmd, *args, **kwargs):
-		return getattr(getattr(self,loc),cmd)(*args, silent=self.silent_mount, **kwargs)
+		return getattr(getattr(self, loc), cmd)(*args, silent=self.silent_mount, **kwargs)
 
 
 	def do_mount(self, *args, **kwargs):
 	def do_mount(self, *args, **kwargs):
 		return self._mount_ops('asi', 'do_mount', *args, **kwargs)
 		return self._mount_ops('asi', 'do_mount', *args, **kwargs)
@@ -282,7 +282,7 @@ class CmdTestAutosignBase(CmdTestBase):
 
 
 	def _gen_listing(self):
 	def _gen_listing(self):
 		for k in self.asi.dirs:
 		for k in self.asi.dirs:
-			d = getattr(self.asi,k)
+			d = getattr(self.asi, k)
 			if d.is_dir():
 			if d.is_dir():
 				yield '{:12} {}'.format(
 				yield '{:12} {}'.format(
 					str(Path(*d.parts[6:])) + ':',
 					str(Path(*d.parts[6:])) + ':',
@@ -364,7 +364,7 @@ class CmdTestAutosignClean(CmdTestAutosignBase):
 		self.asi = Autosign(Config({'_clone': self.asi.cfg, 'coins': 'xmr,btc,bch,eth'}))
 		self.asi = Autosign(Config({'_clone': self.asi.cfg, 'coins': 'xmr,btc,bch,eth'}))
 		return self._clean('xmr,btc,bch,eth')
 		return self._clean('xmr,btc,bch,eth')
 
 
-	def _clean(self,coins):
+	def _clean(self, coins):
 
 
 		self.spawn('', msg_only=True)
 		self.spawn('', msg_only=True)
 
 
@@ -377,7 +377,7 @@ class CmdTestAutosignClean(CmdTestAutosignBase):
 		self.create_fake_tx_files()
 		self.create_fake_tx_files()
 		before = '\n'.join(self._gen_listing())
 		before = '\n'.join(self._gen_listing())
 
 
-		t = self.spawn('mmgen-autosign', [f'--coins={coins}','clean'], no_msg=True)
+		t = self.spawn('mmgen-autosign', [f'--coins={coins}', 'clean'], no_msg=True)
 		out = t.read()
 		out = t.read()
 
 
 		if sys.platform == 'darwin':
 		if sys.platform == 'darwin':
@@ -447,18 +447,18 @@ class CmdTestAutosignThreaded(CmdTestAutosignBase):
 		return 'silent'
 		return 'silent'
 
 
 	def wait_loop_kill(self):
 	def wait_loop_kill(self):
-		self.spawn('',msg_only=True)
+		self.spawn('', msg_only=True)
 		pid = int(self.read_from_tmpfile('autosign_thread_pid'))
 		pid = int(self.read_from_tmpfile('autosign_thread_pid'))
 		self.delete_tmpfile('autosign_thread_pid')
 		self.delete_tmpfile('autosign_thread_pid')
 		from signal import SIGTERM
 		from signal import SIGTERM
 		imsg(purple(f'Killing autosign wait loop [PID {pid}]'))
 		imsg(purple(f'Killing autosign wait loop [PID {pid}]'))
 		try:
 		try:
-			os.kill(pid,SIGTERM)
+			os.kill(pid, SIGTERM)
 		except:
 		except:
 			imsg(yellow(f'{pid}: no such process'))
 			imsg(yellow(f'{pid}: no such process'))
 		return 'ok'
 		return 'ok'
 
 
-	def _wait_signed(self,desc):
+	def _wait_signed(self, desc):
 		oqmsg_r(gray(f'→ offline wallet{"s" if desc.endswith("s") else ""} waiting for {desc}'))
 		oqmsg_r(gray(f'→ offline wallet{"s" if desc.endswith("s") else ""} waiting for {desc}'))
 		assert not self.asi.device_inserted, f'‘{self.asi.dev_label}’ is inserted!'
 		assert not self.asi.device_inserted, f'‘{self.asi.dev_label}’ is inserted!'
 		assert not self.asi.mountpoint.is_mount(), f'‘{self.asi.mountpoint}’ is mounted!'
 		assert not self.asi.mountpoint.is_mount(), f'‘{self.asi.mountpoint}’ is mounted!'
@@ -510,69 +510,69 @@ class CmdTestAutosignThreaded(CmdTestAutosignBase):
 
 
 class CmdTestAutosign(CmdTestAutosignBase):
 class CmdTestAutosign(CmdTestAutosignBase):
 	'autosigning transactions for all supported coins'
 	'autosigning transactions for all supported coins'
-	coins           = ['btc','bch','ltc','eth']
-	daemon_coins    = ['btc','bch','ltc']
-	txfile_coins    = ['btc','bch','ltc','eth','mm1','etc']
+	coins           = ['btc', 'bch', 'ltc', 'eth']
+	daemon_coins    = ['btc', 'bch', 'ltc']
+	txfile_coins    = ['btc', 'bch', 'ltc', 'eth', 'mm1', 'etc']
 	have_online     = False
 	have_online     = False
 	live            = False
 	live            = False
 	simulate_led    = True
 	simulate_led    = True
 	no_insert_check = True
 	no_insert_check = True
 
 
 	filedir_map = (
 	filedir_map = (
-		('btc',''),
-		('bch',''),
-		('ltc','litecoin'),
-		('eth','ethereum'),
-		('mm1','ethereum'),
-		('etc','ethereum_classic'),
+		('btc', ''),
+		('bch', ''),
+		('ltc', 'litecoin'),
+		('eth', 'ethereum'),
+		('mm1', 'ethereum'),
+		('etc', 'ethereum_classic'),
 	)
 	)
 
 
 	cmd_group = (
 	cmd_group = (
-		('start_daemons',            'starting daemons'),
-		('copy_tx_files',            'copying transaction files'),
-		('gen_key',                  'generating key'),
-		('create_dfl_wallet',        'creating default MMGen wallet'),
-		('bad_opt1',                 'running ‘mmgen-autosign’ with --seed-len in invalid context'),
-		('bad_opt2',                 'running ‘mmgen-autosign’ with --mnemonic-fmt in invalid context'),
-		('bad_opt3',                 'running ‘mmgen-autosign’ with --led in invalid context'),
-		('run_setup_dfl_wallet',     'running ‘autosign setup’ (with default wallet)'),
-		('sign_quiet',               'signing transactions (--quiet)'),
-		('remove_signed_txfiles',    'removing signed transaction files'),
-		('run_setup_bip39',          'running ‘autosign setup’ (BIP39 mnemonic)'),
-		('create_bad_txfiles',       'creating bad transaction files'),
-		('sign_full_summary',        'signing transactions (--full-summary)'),
-		('remove_signed_txfiles_btc','removing transaction files (BTC only)'),
-		('remove_bad_txfiles',       'removing bad transaction files'),
-		('sign_led',                 'signing transactions (--led - BTC files only)'),
-		('remove_signed_txfiles',    'removing signed transaction files'),
-		('sign_stealth_led',         'signing transactions (--stealth-led)'),
-		('remove_signed_txfiles',    'removing signed transaction files'),
-		('copy_msgfiles',            'copying message files'),
-		('sign_quiet_msg',           'signing transactions and messages (--quiet)'),
-		('remove_signed_txfiles',    'removing signed transaction files'),
-		('create_bad_txfiles2',      'creating bad transaction files'),
-		('remove_signed_msgfiles',   'removing signed message files'),
-		('create_invalid_msgfile',   'creating invalid message file'),
-		('sign_full_summary_msg',    'signing transactions and messages (--full-summary)'),
-		('remove_invalid_msgfile',   'removing invalid message file'),
-		('remove_bad_txfiles2',      'removing bad transaction files'),
-		('sign_no_unsigned',         'signing transactions and messages (nothing to sign)'),
-		('sign_no_unsigned_xmr',     'signing transactions and messages (nothing to sign, with XMR)'),
-		('sign_no_unsigned_xmronly', 'signing transactions and messages (nothing to sign, XMR-only)'),
-		('wipe_key',                 'wiping the wallet encryption key'),
-		('stop_daemons',             'stopping daemons'),
-		('sign_bad_no_daemon',       'signing transactions (error, no daemons running)'),
+		('start_daemons',             'starting daemons'),
+		('copy_tx_files',             'copying transaction files'),
+		('gen_key',                   'generating key'),
+		('create_dfl_wallet',         'creating default MMGen wallet'),
+		('bad_opt1',                  'running ‘mmgen-autosign’ with --seed-len in invalid context'),
+		('bad_opt2',                  'running ‘mmgen-autosign’ with --mnemonic-fmt in invalid context'),
+		('bad_opt3',                  'running ‘mmgen-autosign’ with --led in invalid context'),
+		('run_setup_dfl_wallet',      'running ‘autosign setup’ (with default wallet)'),
+		('sign_quiet',                'signing transactions (--quiet)'),
+		('remove_signed_txfiles',     'removing signed transaction files'),
+		('run_setup_bip39',           'running ‘autosign setup’ (BIP39 mnemonic)'),
+		('create_bad_txfiles',        'creating bad transaction files'),
+		('sign_full_summary',         'signing transactions (--full-summary)'),
+		('remove_signed_txfiles_btc', 'removing transaction files (BTC only)'),
+		('remove_bad_txfiles',        'removing bad transaction files'),
+		('sign_led',                  'signing transactions (--led - BTC files only)'),
+		('remove_signed_txfiles',     'removing signed transaction files'),
+		('sign_stealth_led',          'signing transactions (--stealth-led)'),
+		('remove_signed_txfiles',     'removing signed transaction files'),
+		('copy_msgfiles',             'copying message files'),
+		('sign_quiet_msg',            'signing transactions and messages (--quiet)'),
+		('remove_signed_txfiles',     'removing signed transaction files'),
+		('create_bad_txfiles2',       'creating bad transaction files'),
+		('remove_signed_msgfiles',    'removing signed message files'),
+		('create_invalid_msgfile',    'creating invalid message file'),
+		('sign_full_summary_msg',     'signing transactions and messages (--full-summary)'),
+		('remove_invalid_msgfile',    'removing invalid message file'),
+		('remove_bad_txfiles2',       'removing bad transaction files'),
+		('sign_no_unsigned',          'signing transactions and messages (nothing to sign)'),
+		('sign_no_unsigned_xmr',      'signing transactions and messages (nothing to sign, with XMR)'),
+		('sign_no_unsigned_xmronly',  'signing transactions and messages (nothing to sign, XMR-only)'),
+		('wipe_key',                  'wiping the wallet encryption key'),
+		('stop_daemons',              'stopping daemons'),
+		('sign_bad_no_daemon',        'signing transactions (error, no daemons running)'),
 	)
 	)
 
 
-	def __init__(self,trunner,cfgs,spawn):
+	def __init__(self, trunner, cfgs, spawn):
 
 
-		super().__init__(trunner,cfgs,spawn)
+		super().__init__(trunner, cfgs, spawn)
 
 
 		if trunner is None:
 		if trunner is None:
 			return
 			return
 
 
 		if self.live and not cfg.exact_output:
 		if self.live and not cfg.exact_output:
-			die(1,red('autosign_live tests must be run with --exact-output enabled!'))
+			die(1, red('autosign_live tests must be run with --exact-output enabled!'))
 
 
 		if self.no_insert_check:
 		if self.no_insert_check:
 			self.opts.append('--no-insert-check')
 			self.opts.append('--no-insert-check')
@@ -585,10 +585,10 @@ class CmdTestAutosign(CmdTestAutosignBase):
 			for coin in self.coins:
 			for coin in self.coins:
 				if coin == 'xmr':
 				if coin == 'xmr':
 					continue
 					continue
-				sdir = os.path.join('test','ref',fmap[coin])
+				sdir = os.path.join('test', 'ref', fmap[coin])
 				for fn in os.listdir(sdir):
 				for fn in os.listdir(sdir):
 					if fn.endswith(f'[{coin.upper()}].rawmsg.json'):
 					if fn.endswith(f'[{coin.upper()}].rawmsg.json'):
-						yield os.path.join(sdir,fn)
+						yield os.path.join(sdir, fn)
 
 
 		self.ref_msgfiles = tuple(gen_msg_fns())
 		self.ref_msgfiles = tuple(gen_msg_fns())
 		self.good_msg_count = 0
 		self.good_msg_count = 0
@@ -606,20 +606,20 @@ class CmdTestAutosign(CmdTestAutosignBase):
 
 
 	def gen_key(self):
 	def gen_key(self):
 		self.insert_device()
 		self.insert_device()
-		t = self.spawn( 'mmgen-autosign', self.opts + ['gen_key'] )
+		t = self.spawn('mmgen-autosign', self.opts + ['gen_key'])
 		t.expect_getend('Wrote key file ')
 		t.expect_getend('Wrote key file ')
 		t.read()
 		t.read()
 		self.remove_device()
 		self.remove_device()
 		return t
 		return t
 
 
 	def create_dfl_wallet(self):
 	def create_dfl_wallet(self):
-		t = self.spawn( 'mmgen-walletconv', [
+		t = self.spawn('mmgen-walletconv', [
 				f'--outdir={cfg.data_dir}',
 				f'--outdir={cfg.data_dir}',
 				'--usr-randchars=0', '--quiet', '--hash-preset=1', '--label=foo',
 				'--usr-randchars=0', '--quiet', '--hash-preset=1', '--label=foo',
 				'test/ref/98831F3A.hex'
 				'test/ref/98831F3A.hex'
 			]
 			]
 		)
 		)
-		t.passphrase_new('new MMGen wallet','abc')
+		t.passphrase_new('new MMGen wallet', 'abc')
 		t.written_to_file('MMGen wallet')
 		t.written_to_file('MMGen wallet')
 		return t
 		return t
 
 
@@ -638,13 +638,13 @@ class CmdTestAutosign(CmdTestAutosignBase):
 		return self._bad_opt(['--led', 'gen_key'], 'makes no sense')
 		return self._bad_opt(['--led', 'gen_key'], 'makes no sense')
 
 
 	def run_setup_dfl_wallet(self):
 	def run_setup_dfl_wallet(self):
-		return self.run_setup(mn_type='default',use_dfl_wallet=True)
+		return self.run_setup(mn_type='default', use_dfl_wallet=True)
 
 
 	def run_setup_bip39(self):
 	def run_setup_bip39(self):
 		from mmgen.cfgfile import mmgen_cfg_file
 		from mmgen.cfgfile import mmgen_cfg_file
-		fn = mmgen_cfg_file(cfg,'usr').fn
-		old_data = mmgen_cfg_file(cfg,'usr').get_data(fn)
-		new_data = [d.replace('bip39:fixed','bip39:full')[2:]
+		fn = mmgen_cfg_file(cfg, 'usr').fn
+		old_data = mmgen_cfg_file(cfg, 'usr').get_data(fn)
+		new_data = [d.replace('bip39:fixed', 'bip39:full')[2:]
 			if d.startswith('# mnemonic_entry_modes') else d for d in old_data]
 			if d.startswith('# mnemonic_entry_modes') else d for d in old_data]
 		with open(fn, 'w') as fh:
 		with open(fn, 'w') as fh:
 			fh.write('\n'.join(new_data) + '\n')
 			fh.write('\n'.join(new_data) + '\n')
@@ -657,7 +657,7 @@ class CmdTestAutosign(CmdTestAutosignBase):
 		return t
 		return t
 
 
 	def copy_tx_files(self):
 	def copy_tx_files(self):
-		self.spawn('',msg_only=True)
+		self.spawn('', msg_only=True)
 		return self.tx_file_ops('copy')
 		return self.tx_file_ops('copy')
 
 
 	def remove_signed_txfiles(self):
 	def remove_signed_txfiles(self):
@@ -665,24 +665,24 @@ class CmdTestAutosign(CmdTestAutosignBase):
 		return 'skip'
 		return 'skip'
 
 
 	def remove_signed_txfiles_btc(self):
 	def remove_signed_txfiles_btc(self):
-		self.tx_file_ops('remove_signed',txfile_coins=['btc'])
+		self.tx_file_ops('remove_signed', txfile_coins=['btc'])
 		return 'skip'
 		return 'skip'
 
 
-	def tx_file_ops(self,op,txfile_coins=[]):
+	def tx_file_ops(self, op, txfile_coins=[]):
 
 
-		assert op in ('copy','set_count','remove_signed')
+		assert op in ('copy', 'set_count', 'remove_signed')
 
 
 		from .ct_ref import CmdTestRef
 		from .ct_ref import CmdTestRef
 		def gen():
 		def gen():
 			d = CmdTestRef.sources['ref_tx_file']
 			d = CmdTestRef.sources['ref_tx_file']
 			dirmap = [e for e in self.filedir_map if e[0] in (txfile_coins or self.txfile_coins)]
 			dirmap = [e for e in self.filedir_map if e[0] in (txfile_coins or self.txfile_coins)]
-			for coin,coindir in dirmap:
-				for network in (0,1):
+			for coin, coindir in dirmap:
+				for network in (0, 1):
 					fn = d[coin][network]
 					fn = d[coin][network]
 					if fn:
 					if fn:
-						yield (coindir,fn)
+						yield (coindir, fn)
 
 
-		data = list(gen()) + [('','25EFA3[2.34].testnet.rawtx')] # TX with 2 non-MMGen outputs
+		data = list(gen()) + [('', '25EFA3[2.34].testnet.rawtx')] # TX with 2 non-MMGen outputs
 
 
 		self.tx_count = len(data)
 		self.tx_count = len(data)
 		if op == 'set_count':
 		if op == 'set_count':
@@ -694,16 +694,16 @@ class CmdTestAutosign(CmdTestAutosignBase):
 		self.do_mount(verbose=cfg.verbose or cfg.exact_output)
 		self.do_mount(verbose=cfg.verbose or cfg.exact_output)
 		end_silence()
 		end_silence()
 
 
-		for coindir,fn in data:
-			src = joinpath(ref_dir,coindir,fn)
+		for coindir, fn in data:
+			src = joinpath(ref_dir, coindir, fn)
 			if cfg.debug_utf8:
 			if cfg.debug_utf8:
 				ext = '.testnet.rawtx' if fn.endswith('.testnet.rawtx') else '.rawtx'
 				ext = '.testnet.rawtx' if fn.endswith('.testnet.rawtx') else '.rawtx'
 				fn = fn[:-len(ext)] + '-α' + ext
 				fn = fn[:-len(ext)] + '-α' + ext
 			target = joinpath(self.asi.tx_dir, fn)
 			target = joinpath(self.asi.tx_dir, fn)
 			if not op == 'remove_signed':
 			if not op == 'remove_signed':
-				shutil.copyfile(src,target)
+				shutil.copyfile(src, target)
 			try:
 			try:
-				os.unlink(target.replace('.rawtx','.sigtx'))
+				os.unlink(target.replace('.rawtx', '.sigtx'))
 			except:
 			except:
 				pass
 				pass
 
 
@@ -721,15 +721,15 @@ class CmdTestAutosign(CmdTestAutosignBase):
 	create_bad_txfiles2 = create_bad_txfiles
 	create_bad_txfiles2 = create_bad_txfiles
 	remove_bad_txfiles2 = remove_bad_txfiles
 	remove_bad_txfiles2 = remove_bad_txfiles
 
 
-	def bad_txfiles(self,op):
+	def bad_txfiles(self, op):
 		self.insert_device()
 		self.insert_device()
 		self.do_mount()
 		self.do_mount()
 		# create or delete 2 bad tx files
 		# create or delete 2 bad tx files
-		self.spawn('',msg_only=True)
-		fns = [joinpath(self.asi.tx_dir, f'bad{n}.rawtx') for n in (1,2)]
+		self.spawn('', msg_only=True)
+		fns = [joinpath(self.asi.tx_dir, f'bad{n}.rawtx') for n in (1, 2)]
 		if op == 'create':
 		if op == 'create':
 			for fn in fns:
 			for fn in fns:
-				with open(fn,'w') as fp:
+				with open(fn, 'w') as fp:
 					fp.write('bad tx data\n')
 					fp.write('bad tx data\n')
 			self.bad_tx_count = 2
 			self.bad_tx_count = 2
 		elif op == 'remove':
 		elif op == 'remove':
@@ -755,16 +755,16 @@ class CmdTestAutosign(CmdTestAutosignBase):
 	def remove_invalid_msgfile(self):
 	def remove_invalid_msgfile(self):
 		return self.msgfile_ops('remove_invalid')
 		return self.msgfile_ops('remove_invalid')
 
 
-	def msgfile_ops(self,op):
-		self.spawn('',msg_only=True)
-		destdir = joinpath(self.asi.mountpoint,'msg')
+	def msgfile_ops(self, op):
+		self.spawn('', msg_only=True)
+		destdir = joinpath(self.asi.mountpoint, 'msg')
 		self.insert_device()
 		self.insert_device()
 		self.do_mount()
 		self.do_mount()
-		os.makedirs(destdir,exist_ok=True)
+		os.makedirs(destdir, exist_ok=True)
 		if op.endswith('_invalid'):
 		if op.endswith('_invalid'):
-			fn = os.path.join(destdir,'DEADBE[BTC].rawmsg.json')
+			fn = os.path.join(destdir, 'DEADBE[BTC].rawmsg.json')
 			if op == 'create_invalid':
 			if op == 'create_invalid':
-				with open(fn,'w') as fp:
+				with open(fn, 'w') as fp:
 					fp.write('bad data\n')
 					fp.write('bad data\n')
 				self.bad_msg_count += 1
 				self.bad_msg_count += 1
 			elif op == 'remove_invalid':
 			elif op == 'remove_invalid':
@@ -778,9 +778,9 @@ class CmdTestAutosign(CmdTestAutosignBase):
 					else:
 					else:
 						self.good_msg_count += 1
 						self.good_msg_count += 1
 					imsg(f'Copying: {fn} -> {destdir}')
 					imsg(f'Copying: {fn} -> {destdir}')
-					shutil.copy2(fn,destdir)
+					shutil.copy2(fn, destdir)
 				elif op == 'remove_signed':
 				elif op == 'remove_signed':
-					os.unlink(os.path.join( destdir, os.path.basename(fn).replace('rawmsg','sigmsg') ))
+					os.unlink(os.path.join(destdir, os.path.basename(fn).replace('rawmsg', 'sigmsg')))
 		self.do_umount()
 		self.do_umount()
 		self.remove_device()
 		self.remove_device()
 		return 'ok'
 		return 'ok'
@@ -858,7 +858,7 @@ class CmdTestAutosign(CmdTestAutosignBase):
 			return 'skip'
 			return 'skip'
 		return self._sign_no_unsigned(
 		return self._sign_no_unsigned(
 			coins = 'XMR,BTC',
 			coins = 'XMR,BTC',
-			present = ['xmr_signables','non_xmr_signables'])
+			present = ['xmr_signables', 'non_xmr_signables'])
 
 
 	def sign_no_unsigned_xmronly(self):
 	def sign_no_unsigned_xmronly(self):
 		if self.coins == ['btc']:
 		if self.coins == ['btc']:
@@ -868,17 +868,17 @@ class CmdTestAutosign(CmdTestAutosignBase):
 			present = ['xmr_signables'],
 			present = ['xmr_signables'],
 			absent  = ['non_xmr_signables'])
 			absent  = ['non_xmr_signables'])
 
 
-	def _sign_no_unsigned(self,coins,present=[],absent=[]):
+	def _sign_no_unsigned(self, coins, present=[], absent=[]):
 		self.insert_device()
 		self.insert_device()
 		t = self.spawn('mmgen-autosign', ['--quiet', '--no-insert-check', f'--coins={coins}'])
 		t = self.spawn('mmgen-autosign', ['--quiet', '--no-insert-check', f'--coins={coins}'])
 		res = t.read()
 		res = t.read()
 		self.remove_device()
 		self.remove_device()
 		for signable_list in present:
 		for signable_list in present:
-			for signable_clsname in getattr(Signable,signable_list):
+			for signable_clsname in getattr(Signable, signable_list):
 				desc = getattr(Signable, signable_clsname).desc
 				desc = getattr(Signable, signable_clsname).desc
 				assert f'No unsigned {desc}s' in res, f'‘No unsigned {desc}s’ missing in output'
 				assert f'No unsigned {desc}s' in res, f'‘No unsigned {desc}s’ missing in output'
 		for signable_list in absent:
 		for signable_list in absent:
-			for signable_clsname in getattr(Signable,signable_list):
+			for signable_clsname in getattr(Signable, signable_list):
 				desc = getattr(Signable, signable_clsname).desc
 				desc = getattr(Signable, signable_clsname).desc
 				assert not f'No unsigned {desc}s' in res, f'‘No unsigned {desc}s’ should be absent in output'
 				assert not f'No unsigned {desc}s' in res, f'‘No unsigned {desc}s’ should be absent in output'
 		return t
 		return t
@@ -904,33 +904,33 @@ class CmdTestAutosignLive(CmdTestAutosignBTC):
 	no_insert_check = False
 	no_insert_check = False
 
 
 	cmd_group = (
 	cmd_group = (
-		('start_daemons',        'starting daemons'),
-		('copy_tx_files',        'copying transaction files'),
-		('gen_key',              'generating key'),
-		('run_setup_mmgen',      'running ‘autosign setup’ (MMGen native mnemonic)'),
-		('sign_live',            'signing transactions'),
-		('create_bad_txfiles',   'creating bad transaction files'),
-		('sign_live_led',        'signing transactions (--led)'),
-		('remove_bad_txfiles',   'removing bad transaction files'),
-		('sign_live_stealth_led','signing transactions (--stealth-led)'),
-		('stop_daemons',         'stopping daemons'),
+		('start_daemons',         'starting daemons'),
+		('copy_tx_files',         'copying transaction files'),
+		('gen_key',               'generating key'),
+		('run_setup_mmgen',       'running ‘autosign setup’ (MMGen native mnemonic)'),
+		('sign_live',             'signing transactions'),
+		('create_bad_txfiles',    'creating bad transaction files'),
+		('sign_live_led',         'signing transactions (--led)'),
+		('remove_bad_txfiles',    'removing bad transaction files'),
+		('sign_live_stealth_led', 'signing transactions (--stealth-led)'),
+		('stop_daemons',          'stopping daemons'),
 	)
 	)
 
 
-	def __init__(self,trunner,cfgs,spawn):
+	def __init__(self, trunner, cfgs, spawn):
 
 
-		super().__init__(trunner,cfgs,spawn)
+		super().__init__(trunner, cfgs, spawn)
 
 
 		if trunner is None:
 		if trunner is None:
 			return
 			return
 
 
 		try:
 		try:
-			LEDControl(enabled=True,simulate=self.simulate_led)
+			LEDControl(enabled=True, simulate=self.simulate_led)
 		except Exception as e:
 		except Exception as e:
 			msg(str(e))
 			msg(str(e))
-			die(2,'LEDControl initialization failed')
+			die(2, 'LEDControl initialization failed')
 
 
 	def run_setup_mmgen(self):
 	def run_setup_mmgen(self):
-		return self.run_setup(mn_type='mmgen',use_dfl_wallet=None)
+		return self.run_setup(mn_type='mmgen', use_dfl_wallet=None)
 
 
 	def sign_live(self):
 	def sign_live(self):
 		return self.do_sign_live()
 		return self.do_sign_live()
@@ -941,7 +941,7 @@ class CmdTestAutosignLive(CmdTestAutosignBTC):
 	def sign_live_stealth_led(self):
 	def sign_live_stealth_led(self):
 		return self.do_sign_live(['--stealth-led'], 'You should see no LED activity now')
 		return self.do_sign_live(['--stealth-led'], 'You should see no LED activity now')
 
 
-	def do_sign_live(self,led_opts=None,led_msg=None):
+	def do_sign_live(self, led_opts=None, led_msg=None):
 
 
 		def prompt_remove():
 		def prompt_remove():
 			omsg_r(orange('\nExtract removable device and then hit ENTER '))
 			omsg_r(orange('\nExtract removable device and then hit ENTER '))

+ 18 - 18
test/cmdtest_py_d/ct_base.py

@@ -20,17 +20,17 @@
 test.cmdtest_py_d.ct_base: Base class for the cmdtest.py test suite
 test.cmdtest_py_d.ct_base: Base class for the cmdtest.py test suite
 """
 """
 
 
-import sys,os
+import sys, os
 
 
 from mmgen.util import msg
 from mmgen.util import msg
 from mmgen.color import gray
 from mmgen.color import gray
 
 
-from ..include.common import cfg,write_to_file,read_from_file
+from ..include.common import cfg, write_to_file, read_from_file
 from .common import get_file_with_ext
 from .common import get_file_with_ext
 
 
 class CmdTestBase:
 class CmdTestBase:
 	'initializer class for the cmdtest.py test suite'
 	'initializer class for the cmdtest.py test suite'
-	base_passthru_opts = ('data_dir','skip_cfg_file')
+	base_passthru_opts = ('data_dir', 'skip_cfg_file')
 	passthru_opts = ()
 	passthru_opts = ()
 	networks = ()
 	networks = ()
 	segwit_opts_ok = False
 	segwit_opts_ok = False
@@ -40,8 +40,8 @@ class CmdTestBase:
 	tmpdir_nums = []
 	tmpdir_nums = []
 	test_name = None
 	test_name = None
 
 
-	def __init__(self,trunner,cfgs,spawn):
-		if hasattr(self,'name'): # init will be called multiple times for classes with multiple inheritance
+	def __init__(self, trunner, cfgs, spawn):
+		if hasattr(self, 'name'): # init will be called multiple times for classes with multiple inheritance
 			return
 			return
 		self.name = type(self).__name__
 		self.name = type(self).__name__
 		self.proto = cfg._proto
 		self.proto = cfg._proto
@@ -49,9 +49,9 @@ class CmdTestBase:
 		self.cfgs = cfgs
 		self.cfgs = cfgs
 		self.spawn = spawn
 		self.spawn = spawn
 		self.have_dfl_wallet = False
 		self.have_dfl_wallet = False
-		self.usr_rand_chars = (5,30)[bool(cfg.usr_random)]
+		self.usr_rand_chars = (5, 30)[bool(cfg.usr_random)]
 		self.usr_rand_arg = f'-r{self.usr_rand_chars}'
 		self.usr_rand_arg = f'-r{self.usr_rand_chars}'
-		self.tn_ext = ('','.testnet')[self.proto.testnet]
+		self.tn_ext = ('', '.testnet')[self.proto.testnet]
 		self.coin = self.proto.coin.lower()
 		self.coin = self.proto.coin.lower()
 		self.fork = 'btc' if self.coin == 'bch' and not cfg.cashaddr else self.coin
 		self.fork = 'btc' if self.coin == 'bch' and not cfg.cashaddr else self.coin
 		self.altcoin_pfx = '' if self.fork == 'btc' else f'-{self.proto.coin}'
 		self.altcoin_pfx = '' if self.fork == 'btc' else f'-{self.proto.coin}'
@@ -66,19 +66,19 @@ class CmdTestBase:
 
 
 	@property
 	@property
 	def tmpdir(self):
 	def tmpdir(self):
-		return os.path.join('test','tmp','{}{}'.format(self.tmpdir_num,'-α' if cfg.debug_utf8 else ''))
+		return os.path.join('test', 'tmp', '{}{}'.format(self.tmpdir_num, '-α' if cfg.debug_utf8 else ''))
 
 
-	def get_file_with_ext(self,ext,**kwargs):
-		return get_file_with_ext(self.tmpdir,ext,**kwargs)
+	def get_file_with_ext(self, ext, **kwargs):
+		return get_file_with_ext(self.tmpdir, ext, **kwargs)
 
 
-	def read_from_tmpfile(self,fn,binary=False):
-		return read_from_file(os.path.join(self.tmpdir,fn),binary=binary)
+	def read_from_tmpfile(self, fn, binary=False):
+		return read_from_file(os.path.join(self.tmpdir, fn), binary=binary)
 
 
-	def write_to_tmpfile(self,fn,data,binary=False):
-		return write_to_file(os.path.join(self.tmpdir,fn),data,binary=binary)
+	def write_to_tmpfile(self, fn, data, binary=False):
+		return write_to_file(os.path.join(self.tmpdir, fn), data, binary=binary)
 
 
-	def delete_tmpfile(self,fn):
-		fn = os.path.join(self.tmpdir,fn)
+	def delete_tmpfile(self, fn):
+		fn = os.path.join(self.tmpdir, fn)
 		try:
 		try:
 			return os.unlink(fn)
 			return os.unlink(fn)
 		except:
 		except:
@@ -100,13 +100,13 @@ class CmdTestBase:
 	def skip_for_win(self, extra_msg=None):
 	def skip_for_win(self, extra_msg=None):
 		return self.skip_for_platform('win32', extra_msg)
 		return self.skip_for_platform('win32', extra_msg)
 
 
-	def spawn_chk(self,*args,**kwargs):
+	def spawn_chk(self, *args, **kwargs):
 		"""
 		"""
 		Drop-in replacement for spawn() + t.read() for tests that spawn more than one process.
 		Drop-in replacement for spawn() + t.read() for tests that spawn more than one process.
 		Ensures that test script execution stops when a spawned process fails.
 		Ensures that test script execution stops when a spawned process fails.
 
 
 		"""
 		"""
-		t = self.spawn(*args,**kwargs)
+		t = self.spawn(*args, **kwargs)
 		t.read()
 		t.read()
 		t.ok()
 		t.ok()
 		t.skip_ok = True
 		t.skip_ok = True

+ 63 - 63
test/cmdtest_py_d/ct_cfgfile.py

@@ -10,12 +10,12 @@
 test.cmdtest_py_d.ct_cfgfile: CfgFile tests for the MMGen cmdtest.py test suite
 test.cmdtest_py_d.ct_cfgfile: CfgFile tests for the MMGen cmdtest.py test suite
 """
 """
 
 
-import sys,os,time,shutil
+import sys, os, time, shutil
 
 
 from mmgen.color import yellow
 from mmgen.color import yellow
-from mmgen.cfgfile import CfgFileSampleSys,CfgFileSampleUsr,cfg_file_sample
+from mmgen.cfgfile import CfgFileSampleSys, CfgFileSampleUsr, cfg_file_sample
 
 
-from ..include.common import cfg,read_from_file,write_to_file,imsg
+from ..include.common import cfg, read_from_file, write_to_file, imsg
 from .ct_base import CmdTestBase
 from .ct_base import CmdTestBase
 
 
 class CmdTestCfgFile(CmdTestBase):
 class CmdTestCfgFile(CmdTestBase):
@@ -26,25 +26,25 @@ class CmdTestCfgFile(CmdTestBase):
 	color = True
 	color = True
 
 
 	cmd_group = (
 	cmd_group = (
-		('sysfile',                  (40,'init with system cfg sample file in place', [])),
-		('no_metadata_sample',       (40,'init with unversioned cfg sample file', [])),
-		('altered_sample',           (40,'init with user-modified cfg sample file', [])),
-		('old_sample',               (40,'init with old v2 cfg sample file', [])),
-		('old_sample_bad_var',       (40,'init with old v2 cfg sample file and bad variable in mmgen.cfg', [])),
-		('autoset_opts',             (40,'setting autoset opts', [])),
-		('autoset_opts_cmdline',     (40,'setting autoset opts (override on cmdline)', [])),
-		('autoset_opts_bad',         (40,'setting autoset opts (bad value in cfg file)', [])),
-		('autoset_opts_bad_cmdline', (40,'setting autoset opts (bad param on cmdline)', [])),
-		('coin_specific_vars',       (40,'setting coin-specific vars', [])),
-		('chain_names',              (40,'setting chain names', [])),
-		('mnemonic_entry_modes',     (40,'setting mnemonic entry modes', [])),
+		('sysfile',                  (40, 'init with system cfg sample file in place', [])),
+		('no_metadata_sample',       (40, 'init with unversioned cfg sample file', [])),
+		('altered_sample',           (40, 'init with user-modified cfg sample file', [])),
+		('old_sample',               (40, 'init with old v2 cfg sample file', [])),
+		('old_sample_bad_var',       (40, 'init with old v2 cfg sample file and bad variable in mmgen.cfg', [])),
+		('autoset_opts',             (40, 'setting autoset opts', [])),
+		('autoset_opts_cmdline',     (40, 'setting autoset opts (override on cmdline)', [])),
+		('autoset_opts_bad',         (40, 'setting autoset opts (bad value in cfg file)', [])),
+		('autoset_opts_bad_cmdline', (40, 'setting autoset opts (bad param on cmdline)', [])),
+		('coin_specific_vars',       (40, 'setting coin-specific vars', [])),
+		('chain_names',              (40, 'setting chain names', [])),
+		('mnemonic_entry_modes',     (40, 'setting mnemonic entry modes', [])),
 	)
 	)
 
 
-	def __init__(self,trunner,cfgs,spawn):
-		CmdTestBase.__init__(self,trunner,cfgs,spawn)
+	def __init__(self, trunner, cfgs, spawn):
+		CmdTestBase.__init__(self, trunner, cfgs, spawn)
 		self.spawn_env['MMGEN_TEST_SUITE_CFGTEST'] = '1'
 		self.spawn_env['MMGEN_TEST_SUITE_CFGTEST'] = '1'
 
 
-	def spawn_test(self,args=[],extra_desc='',pexpect_spawn=None, exit_val=None):
+	def spawn_test(self, args=[], extra_desc='', pexpect_spawn=None, exit_val=None):
 		return self.spawn(
 		return self.spawn(
 			'test/misc/cfg.py',
 			'test/misc/cfg.py',
 			[f'--data-dir={self.path("data_dir")}'] + args,
 			[f'--data-dir={self.path("data_dir")}'] + args,
@@ -53,19 +53,19 @@ class CmdTestCfgFile(CmdTestBase):
 			pexpect_spawn = pexpect_spawn,
 			pexpect_spawn = pexpect_spawn,
 			exit_val      = exit_val)
 			exit_val      = exit_val)
 
 
-	def path(self,id_str):
+	def path(self, id_str):
 		return {
 		return {
 			'ref':         'test/ref/mmgen.cfg',
 			'ref':         'test/ref/mmgen.cfg',
 			'data_dir':    '{}/data_dir'.format(self.tmpdir),
 			'data_dir':    '{}/data_dir'.format(self.tmpdir),
-			'shared_data': '{}/data_dir/{}'.format(self.tmpdir,CfgFileSampleSys.test_fn_subdir),
+			'shared_data': '{}/data_dir/{}'.format(self.tmpdir, CfgFileSampleSys.test_fn_subdir),
 			'usr':         '{}/data_dir/mmgen.cfg'.format(self.tmpdir),
 			'usr':         '{}/data_dir/mmgen.cfg'.format(self.tmpdir),
-			'sys':         '{}/data_dir/{}/mmgen.cfg'.format(self.tmpdir,CfgFileSampleSys.test_fn_subdir),
+			'sys':         '{}/data_dir/{}/mmgen.cfg'.format(self.tmpdir, CfgFileSampleSys.test_fn_subdir),
 			'sample':      '{}/data_dir/mmgen.cfg.sample'.format(os.path.abspath(self.tmpdir)),
 			'sample':      '{}/data_dir/mmgen.cfg.sample'.format(os.path.abspath(self.tmpdir)),
 		}[id_str]
 		}[id_str]
 
 
 	def copy_sys_sample(self):
 	def copy_sys_sample(self):
-		os.makedirs(self.path('shared_data'),exist_ok=True)
-		shutil.copy2(self.path('ref'),self.path('sys'))
+		os.makedirs(self.path('shared_data'), exist_ok=True)
+		shutil.copy2(self.path('ref'), self.path('sys'))
 
 
 	def sysfile(self):
 	def sysfile(self):
 		self.copy_sys_sample()
 		self.copy_sys_sample()
@@ -74,7 +74,7 @@ class CmdTestCfgFile(CmdTestBase):
 		u = read_from_file(self.path('usr'))
 		u = read_from_file(self.path('usr'))
 		S = read_from_file(self.path('sys'))
 		S = read_from_file(self.path('sys'))
 		assert u[-1] == '\n', u
 		assert u[-1] == '\n', u
-		assert u.replace('\r\n','\n') == S, 'u != S'
+		assert u.replace('\r\n', '\n') == S, 'u != S'
 		self.check_replaced_sample()
 		self.check_replaced_sample()
 		return t
 		return t
 
 
@@ -84,8 +84,8 @@ class CmdTestCfgFile(CmdTestBase):
 		assert s[-1] == '\n', s
 		assert s[-1] == '\n', s
 		assert S.splitlines() == s.splitlines()[:-1], 'sys != sample[:-1]'
 		assert S.splitlines() == s.splitlines()[:-1], 'sys != sample[:-1]'
 
 
-	def bad_sample(self,s,e):
-		write_to_file(self.path('sample'),s)
+	def bad_sample(self, s, e):
+		write_to_file(self.path('sample'), s)
 		t = self.spawn_test()
 		t = self.spawn_test()
 		t.expect(e)
 		t.expect(e)
 		t.read()
 		t.read()
@@ -96,44 +96,44 @@ class CmdTestCfgFile(CmdTestBase):
 		self.copy_sys_sample()
 		self.copy_sys_sample()
 		s = read_from_file(self.path('sys'))
 		s = read_from_file(self.path('sys'))
 		e = CfgFileSampleUsr.out_of_date_fs.format(self.path('sample'))
 		e = CfgFileSampleUsr.out_of_date_fs.format(self.path('sample'))
-		return self.bad_sample(s,e)
+		return self.bad_sample(s, e)
 
 
 	def altered_sample(self):
 	def altered_sample(self):
 		s = '\n'.join(read_from_file(self.path('sample')).splitlines()[1:]) + '\n'
 		s = '\n'.join(read_from_file(self.path('sample')).splitlines()[1:]) + '\n'
 		e = CfgFileSampleUsr.altered_by_user_fs.format(self.path('sample'))
 		e = CfgFileSampleUsr.altered_by_user_fs.format(self.path('sample'))
-		return self.bad_sample(s,e)
+		return self.bad_sample(s, e)
 
 
-	def old_sample_common(self,old_set=False,args=[],pexpect_spawn=False):
+	def old_sample_common(self, old_set=False, args=[], pexpect_spawn=False):
 		s = read_from_file(self.path('sys'))
 		s = read_from_file(self.path('sys'))
-		d = s.replace('monero_','zcash_').splitlines()
-		a1 = ['','# Uncomment to make foo true:','# foo true']
-		a2 = ['','# Uncomment to make bar false:','# bar false']
+		d = s.replace('monero_', 'zcash_').splitlines()
+		a1 = ['', '# Uncomment to make foo true:', '# foo true']
+		a2 = ['', '# Uncomment to make bar false:', '# bar false']
 		d = d + a1 + a2
 		d = d + a1 + a2
 		chk = cfg_file_sample.cls_make_metadata(d)
 		chk = cfg_file_sample.cls_make_metadata(d)
-		write_to_file(self.path('sample'),'\n'.join(d+chk) + '\n')
+		write_to_file(self.path('sample'), '\n'.join(d+chk) + '\n')
 
 
 		t = self.spawn_test(args=args, pexpect_spawn=pexpect_spawn, exit_val=1 if old_set else None)
 		t = self.spawn_test(args=args, pexpect_spawn=pexpect_spawn, exit_val=1 if old_set else None)
 
 
 		t.expect('options have changed')
 		t.expect('options have changed')
-		for s in ('have been added','monero_','have been removed','zcash_','foo','bar'):
+		for s in ('have been added', 'monero_', 'have been removed', 'zcash_', 'foo', 'bar'):
 			t.expect(s)
 			t.expect(s)
 
 
 		if old_set:
 		if old_set:
-			for s in ('must be deleted','bar','foo'):
+			for s in ('must be deleted', 'bar', 'foo'):
 				t.expect(s)
 				t.expect(s)
 
 
 		cp = CfgFileSampleUsr.details_confirm_prompt + ' (y/N): '
 		cp = CfgFileSampleUsr.details_confirm_prompt + ' (y/N): '
 
 
-		t.expect(cp,'y')
+		t.expect(cp, 'y')
 
 
-		for s in ('CHANGES','Removed','# zcash_','# foo','# bar','Added','# monero_'):
+		for s in ('CHANGES', 'Removed', '# zcash_', '# foo', '# bar', 'Added', '# monero_'):
 			t.expect(s)
 			t.expect(s)
 
 
 		if t.pexpect_spawn: # view and exit pager
 		if t.pexpect_spawn: # view and exit pager
 			time.sleep(1 if cfg.exact_output else t.send_delay)
 			time.sleep(1 if cfg.exact_output else t.send_delay)
 			t.send('q')
 			t.send('q')
 
 
-		t.expect(cp,'n')
+		t.expect(cp, 'n')
 
 
 		if old_set:
 		if old_set:
 			t.expect('unrecognized option')
 			t.expect('unrecognized option')
@@ -148,13 +148,13 @@ class CmdTestCfgFile(CmdTestBase):
 		return t
 		return t
 
 
 	def old_sample(self):
 	def old_sample(self):
-		d = ['testnet true','rpc_password passwOrd']
-		write_to_file(self.path('usr'),'\n'.join(d) + '\n')
+		d = ['testnet true', 'rpc_password passwOrd']
+		write_to_file(self.path('usr'), '\n'.join(d) + '\n')
 		return self.old_sample_common(args=['parse_test'])
 		return self.old_sample_common(args=['parse_test'])
 
 
 	def old_sample_bad_var(self):
 	def old_sample_bad_var(self):
-		d = ['foo true','bar false']
-		write_to_file(self.path('usr'),'\n'.join(d) + '\n')
+		d = ['foo true', 'bar false']
+		write_to_file(self.path('usr'), '\n'.join(d) + '\n')
 		t = self.old_sample_common(
 		t = self.old_sample_common(
 			old_set       = True,
 			old_set       = True,
 			pexpect_spawn = not sys.platform == 'win32')
 			pexpect_spawn = not sys.platform == 'win32')
@@ -162,7 +162,7 @@ class CmdTestCfgFile(CmdTestBase):
 		return t
 		return t
 
 
 	def _autoset_opts(self, args=[], text='rpc_backend aiohttp\n', exit_val=None):
 	def _autoset_opts(self, args=[], text='rpc_backend aiohttp\n', exit_val=None):
-		write_to_file( self.path('usr'), text )
+		write_to_file(self.path('usr'), text)
 		imsg(yellow(f'Wrote cfg file:\n  {text}'))
 		imsg(yellow(f'Wrote cfg file:\n  {text}'))
 		return self.spawn_test(args=args, exit_val=exit_val)
 		return self.spawn_test(args=args, exit_val=exit_val)
 
 
@@ -170,7 +170,7 @@ class CmdTestCfgFile(CmdTestBase):
 		return self._autoset_opts(args=['autoset_opts'])
 		return self._autoset_opts(args=['autoset_opts'])
 
 
 	def autoset_opts_cmdline(self):
 	def autoset_opts_cmdline(self):
-		return self._autoset_opts(args=['--rpc-backend=curl','autoset_opts_cmdline'])
+		return self._autoset_opts(args=['--rpc-backend=curl', 'autoset_opts_cmdline'])
 
 
 	def _autoset_opts_bad(self, expect, kwargs):
 	def _autoset_opts_bad(self, expect, kwargs):
 		t = self._autoset_opts(exit_val=1, **kwargs)
 		t = self._autoset_opts(exit_val=1, **kwargs)
@@ -193,15 +193,15 @@ class CmdTestCfgFile(CmdTestBase):
 			'btc_ignore_daemon_version true',
 			'btc_ignore_daemon_version true',
 			'eth_ignore_daemon_version true'
 			'eth_ignore_daemon_version true'
 		]
 		]
-		write_to_file(self.path('usr'),'\n'.join(d) + '\n')
+		write_to_file(self.path('usr'), '\n'.join(d) + '\n')
 		imsg(yellow('Wrote cfg file:\n  {}'.format('\n  '.join(d))))
 		imsg(yellow('Wrote cfg file:\n  {}'.format('\n  '.join(d))))
 
 
-		for coin,res1_chk,res2_chk,res2_chk_eq in (
-			('BTC','True', '1.2345',True),
-			('LTC','False','1.2345',False),
-			('BCH','False','1.2345',False),
-			('ETH','True', '5.4321',True),
-			('ETC','False','5.4321',False)
+		for coin, res1_chk, res2_chk, res2_chk_eq in (
+			('BTC', 'True',  '1.2345', True),
+			('LTC', 'False', '1.2345', False),
+			('BCH', 'False', '1.2345', False),
+			('ETH', 'True',  '5.4321', True),
+			('ETC', 'False', '5.4321', False)
 		):
 		):
 			if cfg.no_altcoin and coin != 'BTC':
 			if cfg.no_altcoin and coin != 'BTC':
 				continue
 				continue
@@ -212,7 +212,7 @@ class CmdTestCfgFile(CmdTestBase):
 					'ignore_daemon_version',
 					'ignore_daemon_version',
 					'max_tx_fee'
 					'max_tx_fee'
 				],
 				],
-				extra_desc=f'({coin})' )
+				extra_desc=f'({coin})')
 			res1 = t.expect_getend('ignore_daemon_version: ')
 			res1 = t.expect_getend('ignore_daemon_version: ')
 			res2 = t.expect_getend('max_tx_fee: ')
 			res2 = t.expect_getend('max_tx_fee: ')
 			assert res1 == res1_chk, f'{res1} != {res1_chk}'
 			assert res1 == res1_chk, f'{res1} != {res1_chk}'
@@ -235,7 +235,7 @@ class CmdTestCfgFile(CmdTestBase):
 			return t
 			return t
 
 
 		txt = 'mnemonic_entry_modes mmgen:full bip39:short'
 		txt = 'mnemonic_entry_modes mmgen:full bip39:short'
-		write_to_file(self.path('usr'),txt+'\n')
+		write_to_file(self.path('usr'), txt+'\n')
 		imsg(yellow(f'Wrote cfg file: {txt!r}'))
 		imsg(yellow(f'Wrote cfg file: {txt!r}'))
 		t = run("{'mmgen': 'full', 'bip39': 'short'}")
 		t = run("{'mmgen': 'full', 'bip39': 'short'}")
 		# check that set_dfl_entry_mode() set the mode correctly:
 		# check that set_dfl_entry_mode() set the mode correctly:
@@ -248,11 +248,11 @@ class CmdTestCfgFile(CmdTestBase):
 		if cfg.no_altcoin:
 		if cfg.no_altcoin:
 			return 'skip'
 			return 'skip'
 
 
-		def run(chk,testnet):
-			for coin,chain_chk in (('ETH',chk),('ETC',None)):
+		def run(chk, testnet):
+			for coin, chain_chk in (('ETH', chk), ('ETC', None)):
 				t = self.spawn_test(
 				t = self.spawn_test(
-					args = [f'--coin={coin}',f'--testnet={(0,1)[testnet]}','coin_specific_vars','chain_names'],
-					extra_desc = f'({coin} testnet={testnet!r:5} chain_names={chain_chk})' )
+					args = [f'--coin={coin}', f'--testnet={(0, 1)[testnet]}', 'coin_specific_vars', 'chain_names'],
+					extra_desc = f'({coin} testnet={testnet!r:5} chain_names={chain_chk})')
 				chain = t.expect_getend('chain_names: ')
 				chain = t.expect_getend('chain_names: ')
 				if chain_chk:
 				if chain_chk:
 					assert chain == chain_chk, f'{chain} != {chain_chk}'
 					assert chain == chain_chk, f'{chain} != {chain_chk}'
@@ -263,16 +263,16 @@ class CmdTestCfgFile(CmdTestBase):
 			return t
 			return t
 
 
 		txt = 'eth_mainnet_chain_names istanbul constantinople'
 		txt = 'eth_mainnet_chain_names istanbul constantinople'
-		write_to_file(self.path('usr'),txt+'\n')
+		write_to_file(self.path('usr'), txt+'\n')
 		imsg(yellow(f'Wrote cfg file: {txt!r}'))
 		imsg(yellow(f'Wrote cfg file: {txt!r}'))
-		t = run("['istanbul', 'constantinople']",False)
-		t = run(None,True)
+		t = run("['istanbul', 'constantinople']", False)
+		t = run(None, True)
 
 
 		txt = 'eth_testnet_chain_names rinkeby'
 		txt = 'eth_testnet_chain_names rinkeby'
-		write_to_file(self.path('usr'),txt+'\n')
+		write_to_file(self.path('usr'), txt+'\n')
 		imsg(yellow(f'Wrote cfg file: {txt!r}'))
 		imsg(yellow(f'Wrote cfg file: {txt!r}'))
-		t = run(None,False)
-		t = run("['rinkeby']",True)
+		t = run(None, False)
+		t = run("['rinkeby']", True)
 
 
 		t.skip_ok = True
 		t.skip_ok = True
 		return t
 		return t

+ 48 - 48
test/cmdtest_py_d/ct_chainsplit.py

@@ -23,51 +23,51 @@ This module is unmaintained and currently non-functional
 
 
 from mmgen.util import die
 from mmgen.util import die
 
 
-from .common import get_file_with_ext,rt_pw
+from .common import get_file_with_ext, rt_pw
 from .ct_regtest import CmdTestRegtest
 from .ct_regtest import CmdTestRegtest
 
 
 class CmdTestChainsplit(CmdTestRegtest):
 class CmdTestChainsplit(CmdTestRegtest):
 	'forking scenario tests for the cmdtest.py test suite'
 	'forking scenario tests for the cmdtest.py test suite'
 	cmd_group = (
 	cmd_group = (
-		('split_setup',        'regtest forking scenario setup'),
-		('walletgen_bob',      "generating Bob's wallet"),
-		('addrgen_bob',        "generating Bob's addresses"),
-		('addrimport_bob',     "importing Bob's addresses"),
-		('fund_bob',           "funding Bob's wallet"),
-		('split_fork',         'regtest split fork'),
-		('split_start_btc',    'start regtest daemon (BTC)'),
-		('split_start_b2x',    'start regtest daemon (B2X)'),
-		('split_gen_btc',      'mining a block (BTC)'),
-		('split_gen_b2x',      'mining 100 blocks (B2X)'),
-		('split_do_split',     'creating coin splitting transactions'),
-		('split_sign_b2x',     'signing B2X split transaction'),
-		('split_sign_btc',     'signing BTC split transaction'),
-		('split_send_b2x',     'sending B2X split transaction'),
-		('split_send_btc',     'sending BTC split transaction'),
-		('split_gen_btc',      'mining a block (BTC)'),
-		('split_gen_b2x2',     'mining a block (B2X)'),
-		('split_txdo_timelock_bad_btc', 'sending transaction with bad locktime (BTC)'),
-		('split_txdo_timelock_good_btc','sending transaction with good locktime (BTC)'),
-		('split_txdo_timelock_bad_b2x', 'sending transaction with bad locktime (B2X)'),
-		('split_txdo_timelock_good_b2x','sending transaction with good locktime (B2X)'),
+		('split_setup',                  'regtest forking scenario setup'),
+		('walletgen_bob',                'generating Bob’s wallet'),
+		('addrgen_bob',                  'generating Bob’s addresses'),
+		('addrimport_bob',               'importing Bob’s addresses'),
+		('fund_bob',                     'funding Bob’s wallet'),
+		('split_fork',                   'regtest split fork'),
+		('split_start_btc',              'start regtest daemon (BTC)'),
+		('split_start_b2x',              'start regtest daemon (B2X)'),
+		('split_gen_btc',                'mining a block (BTC)'),
+		('split_gen_b2x',                'mining 100 blocks (B2X)'),
+		('split_do_split',               'creating coin splitting transactions'),
+		('split_sign_b2x',               'signing B2X split transaction'),
+		('split_sign_btc',               'signing BTC split transaction'),
+		('split_send_b2x',               'sending B2X split transaction'),
+		('split_send_btc',               'sending BTC split transaction'),
+		('split_gen_btc',                'mining a block (BTC)'),
+		('split_gen_b2x2',               'mining a block (B2X)'),
+		('split_txdo_timelock_bad_btc',  'sending transaction with bad locktime (BTC)'),
+		('split_txdo_timelock_good_btc', 'sending transaction with good locktime (BTC)'),
+		('split_txdo_timelock_bad_b2x',  'sending transaction with bad locktime (B2X)'),
+		('split_txdo_timelock_good_b2x', 'sending transaction with good locktime (B2X)'),
 	)
 	)
 
 
 	def split_setup(self):
 	def split_setup(self):
 		if self.proto.coin != 'BTC':
 		if self.proto.coin != 'BTC':
-			die(1,'Test valid only for coin BTC')
+			die(1, 'Test valid only for coin BTC')
 		self.coin = 'BTC'
 		self.coin = 'BTC'
 		return self.setup()
 		return self.setup()
 
 
 	def split_fork(self):
 	def split_fork(self):
 		self.coin = 'B2X'
 		self.coin = 'B2X'
-		t = self.spawn('mmgen-regtest',['fork','btc'])
+		t = self.spawn('mmgen-regtest', ['fork', 'btc'])
 		t.expect('Creating fork from coin')
 		t.expect('Creating fork from coin')
 		t.expect('successfully created')
 		t.expect('successfully created')
 		t.ok()
 		t.ok()
 
 
-	def split_start(self,coin):
+	def split_start(self, coin):
 		self.coin = coin
 		self.coin = coin
-		t = self.spawn('mmgen-regtest',['bob'])
+		t = self.spawn('mmgen-regtest', ['bob'])
 		t.expect('Starting')
 		t.expect('Starting')
 		t.expect('done')
 		t.expect('done')
 		t.ok()
 		t.ok()
@@ -82,7 +82,7 @@ class CmdTestChainsplit(CmdTestRegtest):
 		self.regtest_generate(coin='BTC')
 		self.regtest_generate(coin='BTC')
 
 
 	def split_gen_b2x(self):
 	def split_gen_b2x(self):
-		self.regtest_generate(coin='B2X',num_blocks=100)
+		self.regtest_generate(coin='B2X', num_blocks=100)
 
 
 	def split_gen_b2x2(self):
 	def split_gen_b2x2(self):
 		self.regtest_generate(coin='B2X')
 		self.regtest_generate(coin='B2X')
@@ -90,17 +90,17 @@ class CmdTestChainsplit(CmdTestRegtest):
 	def split_do_split(self):
 	def split_do_split(self):
 		self.coin = 'B2X'
 		self.coin = 'B2X'
 		sid = self.regtest_user_sid('bob')
 		sid = self.regtest_user_sid('bob')
-		t = self.spawn('mmgen-split',[
+		t = self.spawn('mmgen-split', [
 			'--bob',
 			'--bob',
 			'--outdir='+self.tmpdir,
 			'--outdir='+self.tmpdir,
 			'--tx-fees=0.0001,0.0003',
 			'--tx-fees=0.0001,0.0003',
-			sid+':S:1',sid+':S:2'])
-		t.expect(r'\[q\]uit menu, .*?:.','q', regex=True)
-		t.expect('outputs to spend: ','1\n')
+			sid+':S:1', sid+':S:2'])
+		t.expect(r'\[q\]uit menu, .*?:.', 'q', regex=True)
+		t.expect('outputs to spend: ', '1\n')
 
 
 		for _ in ('timelocked', 'split'):
 		for _ in ('timelocked', 'split'):
 			for _ in ('fee', 'change'):
 			for _ in ('fee', 'change'):
-				t.expect('OK? (Y/n): ','y')
+				t.expect('OK? (Y/n): ', 'y')
 			t.do_comment(False)
 			t.do_comment(False)
 			t.view_tx('t')
 			t.view_tx('t')
 
 
@@ -108,30 +108,30 @@ class CmdTestChainsplit(CmdTestRegtest):
 		t.written_to_file('Short chain transaction')
 		t.written_to_file('Short chain transaction')
 		t.ok()
 		t.ok()
 
 
-	def split_sign(self,coin,ext):
-		wf = get_file_with_ext(self.regtest_user_dir('bob',coin=coin.lower()),'mmdat')
-		txfile = self.get_file_with_ext(ext,no_dot=True)
+	def split_sign(self, coin, ext):
+		wf = get_file_with_ext(self.regtest_user_dir('bob', coin=coin.lower()), 'mmdat')
+		txfile = self.get_file_with_ext(ext, no_dot=True)
 		self.coin = coin
 		self.coin = coin
-		self.txsign(txfile,wf,extra_opts=['--bob'])
+		self.txsign(txfile, wf, extra_opts=['--bob'])
 
 
 	def split_sign_b2x(self):
 	def split_sign_b2x(self):
-		return self.regtest_sign(coin='B2X',ext='533].rawtx')
+		return self.regtest_sign(coin='B2X', ext='533].rawtx')
 
 
 	def split_sign_btc(self):
 	def split_sign_btc(self):
-		return self.regtest_sign(coin='BTC',ext='9997].rawtx')
+		return self.regtest_sign(coin='BTC', ext='9997].rawtx')
 
 
-	def split_send(self,coin,ext):
+	def split_send(self, coin, ext):
 		self.coin = coin
 		self.coin = coin
-		txfile = self.get_file_with_ext(ext,no_dot=True)
-		self.txsend(txfile,bogus_send=False,extra_opts=['--bob'])
+		txfile = self.get_file_with_ext(ext, no_dot=True)
+		self.txsend(txfile, bogus_send=False, extra_opts=['--bob'])
 
 
 	def split_send_b2x(self):
 	def split_send_b2x(self):
-		return self.regtest_send(coin='B2X',ext='533].sigtx')
+		return self.regtest_send(coin='B2X', ext='533].sigtx')
 
 
 	def split_send_btc(self):
 	def split_send_btc(self):
-		return self.regtest_send(coin='BTC',ext='9997].sigtx')
+		return self.regtest_send(coin='BTC', ext='9997].sigtx')
 
 
-	def split_txdo_timelock(self,coin,locktime,bad_locktime):
+	def split_txdo_timelock(self, coin, locktime, bad_locktime):
 		self.coin = coin
 		self.coin = coin
 		sid = self.regtest_user_sid('bob')
 		sid = self.regtest_user_sid('bob')
 		self.regtest_user_txdo(
 		self.regtest_user_txdo(
@@ -144,10 +144,10 @@ class CmdTestChainsplit(CmdTestRegtest):
 			bad_locktime = bad_locktime)
 			bad_locktime = bad_locktime)
 
 
 	def split_txdo_timelock_bad_btc(self):
 	def split_txdo_timelock_bad_btc(self):
-		self.regtest_txdo_timelock('BTC',locktime=8888,bad_locktime=True)
+		self.regtest_txdo_timelock('BTC', locktime=8888, bad_locktime=True)
 	def split_txdo_timelock_good_btc(self):
 	def split_txdo_timelock_good_btc(self):
-		self.regtest_txdo_timelock('BTC',locktime=1321009871,bad_locktime=False)
+		self.regtest_txdo_timelock('BTC', locktime=1321009871, bad_locktime=False)
 	def split_txdo_timelock_bad_b2x(self):
 	def split_txdo_timelock_bad_b2x(self):
-		self.regtest_txdo_timelock('B2X',locktime=8888,bad_locktime=True)
+		self.regtest_txdo_timelock('B2X', locktime=8888, bad_locktime=True)
 	def split_txdo_timelock_good_b2x(self):
 	def split_txdo_timelock_good_b2x(self):
-		self.regtest_txdo_timelock('B2X',locktime=1321009871,bad_locktime=False)
+		self.regtest_txdo_timelock('B2X', locktime=1321009871, bad_locktime=False)

File diff suppressed because it is too large
+ 262 - 262
test/cmdtest_py_d/ct_ethdev.py


+ 32 - 32
test/cmdtest_py_d/ct_help.py

@@ -23,19 +23,19 @@ from .ct_base import CmdTestBase
 class CmdTestHelp(CmdTestBase):
 class CmdTestHelp(CmdTestBase):
 	'help, info and usage screens'
 	'help, info and usage screens'
 	networks = ('btc', 'ltc', 'bch', 'eth', 'xmr', 'doge')
 	networks = ('btc', 'ltc', 'bch', 'eth', 'xmr', 'doge')
-	passthru_opts = ('daemon_data_dir','rpc_port','coin','testnet')
+	passthru_opts = ('daemon_data_dir', 'rpc_port', 'coin', 'testnet')
 	cmd_group = (
 	cmd_group = (
-		('usage1',                (1,'usage message (via --usage)',[])),
-		('usage2',                (1,'usage message (via bad invocation)',[])),
-		('version',               (1,'version message',[])),
-		('license',               (1,'license message',[])),
-		('helpscreens',           (1,'help screens',             [])),
-		('longhelpscreens',       (1,'help screens (--longhelp)',[])),
-		('show_hash_presets',     (1,'info screen (--show-hash-presets)',[])),
-		('tool_help',             (1,"'mmgen-tool' usage screen",[])),
-		('tool_cmd_usage',        (1,"'mmgen-tool' usage screen",[])),
-		('test_help',             (1,"'cmdtest.py' help screens",[])),
-		('tooltest_help',         (1,"'tooltest.py' help screens",[])),
+		('usage1',            (1, 'usage message (via --usage)', [])),
+		('usage2',            (1, 'usage message (via bad invocation)', [])),
+		('version',           (1, 'version message', [])),
+		('license',           (1, 'license message', [])),
+		('helpscreens',       (1, 'help screens',             [])),
+		('longhelpscreens',   (1, 'help screens (--longhelp)', [])),
+		('show_hash_presets', (1, 'info screen (--show-hash-presets)', [])),
+		('tool_help',         (1, '‘mmgen-tool’ usage screen', [])),
+		('tool_cmd_usage',    (1, '‘mmgen-tool’ usage screen', [])),
+		('test_help',         (1, '‘cmdtest.py’ help screens', [])),
+		('tooltest_help',     (1, '‘tooltest.py’ help screens', [])),
 	)
 	)
 
 
 	def usage1(self):
 	def usage1(self):
@@ -67,13 +67,13 @@ class CmdTestHelp(CmdTestBase):
 		if cfg.pexpect_spawn:
 		if cfg.pexpect_spawn:
 			t.send('q')
 			t.send('q')
 		t.expect('to continue: ', 'c')
 		t.expect('to continue: ', 'c')
-		t.expect('data: ','beadcafe'*4 + '\n')
+		t.expect('data: ', 'beadcafe'*4 + '\n')
 		t.expect('to confirm: ', 'YES\n')
 		t.expect('to confirm: ', 'YES\n')
 		return t
 		return t
 
 
-	def spawn_chk_expect(self,*args,**kwargs):
+	def spawn_chk_expect(self, *args, **kwargs):
 		expect = kwargs.pop('expect')
 		expect = kwargs.pop('expect')
-		t = self.spawn(*args,**kwargs)
+		t = self.spawn(*args, **kwargs)
 		t.expect(expect)
 		t.expect(expect)
 		if t.pexpect_spawn:
 		if t.pexpect_spawn:
 			time.sleep(0.4)
 			time.sleep(0.4)
@@ -106,7 +106,7 @@ class CmdTestHelp(CmdTestBase):
 				[arg],
 				[arg],
 				extra_desc       = f'(mmgen-{cmdname})',
 				extra_desc       = f'(mmgen-{cmdname})',
 				no_passthru_opts = not gc.cmd_caps_data[cmdname].proto)
 				no_passthru_opts = not gc.cmd_caps_data[cmdname].proto)
-			t.expect(expect,regex=True)
+			t.expect(expect, regex=True)
 			if pager and t.pexpect_spawn:
 			if pager and t.pexpect_spawn:
 				time.sleep(0.2)
 				time.sleep(0.2)
 				t.send('q')
 				t.send('q')
@@ -117,17 +117,17 @@ class CmdTestHelp(CmdTestBase):
 		return t
 		return t
 
 
 	def longhelpscreens(self):
 	def longhelpscreens(self):
-		return self.helpscreens(arg='--longhelp',expect='USAGE:.*GLOBAL OPTIONS:')
+		return self.helpscreens(arg='--longhelp', expect='USAGE:.*GLOBAL OPTIONS:')
 
 
 	def show_hash_presets(self):
 	def show_hash_presets(self):
 		return self.helpscreens(
 		return self.helpscreens(
 			arg = '--show-hash-presets',
 			arg = '--show-hash-presets',
 			scripts = (
 			scripts = (
-					'walletgen','walletconv','walletchk','passchg','subwalletgen',
-					'addrgen','keygen','passgen',
-					'txsign','txdo','txbump'),
+				'walletgen', 'walletconv', 'walletchk', 'passchg', 'subwalletgen',
+				'addrgen', 'keygen', 'passgen',
+				'txsign', 'txdo', 'txbump'),
 			expect = 'Available parameters.*Preset',
 			expect = 'Available parameters.*Preset',
-			pager  = False )
+			pager  = False)
 
 
 	def tool_help(self):
 	def tool_help(self):
 
 
@@ -143,7 +143,7 @@ class CmdTestHelp(CmdTestBase):
 				'mmgen-tool',
 				'mmgen-tool',
 				[arg],
 				[arg],
 				extra_desc = f'(mmgen-tool {arg})',
 				extra_desc = f'(mmgen-tool {arg})',
-				expect = 'GENERAL USAGE' )
+				expect = 'GENERAL USAGE')
 		return t
 		return t
 
 
 	def tool_cmd_usage(self):
 	def tool_cmd_usage(self):
@@ -156,32 +156,32 @@ class CmdTestHelp(CmdTestBase):
 
 
 		for cmdlist in mods.values():
 		for cmdlist in mods.values():
 			for cmd in cmdlist:
 			for cmd in cmdlist:
-				t = self.spawn_chk( 'mmgen-tool', ['help',cmd], extra_desc=f'({cmd})' )
+				t = self.spawn_chk('mmgen-tool', ['help', cmd], extra_desc=f'({cmd})')
 		return t
 		return t
 
 
 	def test_help(self):
 	def test_help(self):
-		for arg,expect in (
-			('--help','USAGE'),
-			('--list-cmds','AVAILABLE COMMANDS'),
-			('--list-cmd-groups','AVAILABLE COMMAND GROUPS')
+		for arg, expect in (
+			('--help', 'USAGE'),
+			('--list-cmds', 'AVAILABLE COMMANDS'),
+			('--list-cmd-groups', 'AVAILABLE COMMAND GROUPS')
 		):
 		):
 			t = self.spawn_chk_expect(
 			t = self.spawn_chk_expect(
 				'cmdtest.py',
 				'cmdtest.py',
 				[arg],
 				[arg],
 				cmd_dir = 'test',
 				cmd_dir = 'test',
 				extra_desc = f'(cmdtest.py {arg})',
 				extra_desc = f'(cmdtest.py {arg})',
-				expect = expect )
+				expect = expect)
 		return t
 		return t
 
 
 	def tooltest_help(self):
 	def tooltest_help(self):
-		for arg,expect in (
-			('--list-cmds','Available commands'),
-			('--testing-status','Testing status')
+		for arg, expect in (
+			('--list-cmds', 'Available commands'),
+			('--testing-status', 'Testing status')
 		):
 		):
 			t = self.spawn_chk_expect(
 			t = self.spawn_chk_expect(
 				'tooltest.py',
 				'tooltest.py',
 				[arg],
 				[arg],
 				cmd_dir = 'test',
 				cmd_dir = 'test',
 				extra_desc = f'(tooltest.py {arg})',
 				extra_desc = f'(tooltest.py {arg})',
-				expect = expect )
+				expect = expect)
 		return t
 		return t

+ 105 - 105
test/cmdtest_py_d/ct_input.py

@@ -10,10 +10,10 @@
 test.cmdtest_py_d.ct_input: user input tests for the MMGen cmdtest.py test suite
 test.cmdtest_py_d.ct_input: user input tests for the MMGen cmdtest.py test suite
 """
 """
 
 
-import sys,os
+import sys, os
 
 
 from mmgen.cfg import gc
 from mmgen.cfg import gc
-from mmgen.util import fmt,capfirst,remove_whitespace
+from mmgen.util import fmt, capfirst, remove_whitespace
 from mmgen.wallet import get_wallet_cls
 from mmgen.wallet import get_wallet_cls
 
 
 from ..include.common import (
 from ..include.common import (
@@ -25,9 +25,9 @@ from ..include.common import (
 	read_from_file,
 	read_from_file,
 	strip_ansi_escapes
 	strip_ansi_escapes
 )
 )
-from .common import Ctrl_U,ref_dir
+from .common import Ctrl_U, ref_dir
 from .ct_base import CmdTestBase
 from .ct_base import CmdTestBase
-from .input import stealth_mnemonic_entry,user_dieroll_entry
+from .input import stealth_mnemonic_entry, user_dieroll_entry
 
 
 hold_protect_delay = 2 if sys.platform == 'darwin' else None
 hold_protect_delay = 2 if sys.platform == 'darwin' else None
 
 
@@ -88,17 +88,17 @@ class CmdTestInput(CmdTestBase):
 	),
 	),
 	'mnemonic': (
 	'mnemonic': (
 		'mnemonic entry',
 		'mnemonic entry',
-		('mnemonic_entry_mmgen',          'stealth mnemonic entry (mmgen)'),
-		('mnemonic_entry_mmgen_minimal',  'stealth mnemonic entry (mmgen - minimal entry mode)'),
-		('mnemonic_entry_bip39',          'stealth mnemonic entry (bip39)'),
-		('mnemonic_entry_bip39_short',    'stealth mnemonic entry (bip39 - short entry mode)'),
-		('mn2hex_interactive_mmgen',      'mn2hex_interactive (mmgen)'),
-		('mn2hex_interactive_mmgen_fixed','mn2hex_interactive (mmgen - fixed (10-letter) entry mode)'),
-		('mn2hex_interactive_bip39',      'mn2hex_interactive (bip39)'),
-		('mn2hex_interactive_bip39_short','mn2hex_interactive (bip39 - short entry mode (+pad entry))'),
-		('mn2hex_interactive_bip39_fixed','mn2hex_interactive (bip39 - fixed (4-letter) entry mode)'),
-		('mn2hex_interactive_xmr',        'mn2hex_interactive (xmrseed)'),
-		('mn2hex_interactive_xmr_short',  'mn2hex_interactive (xmrseed - short entry mode)'),
+		('mnemonic_entry_mmgen',           'stealth mnemonic entry (mmgen)'),
+		('mnemonic_entry_mmgen_minimal',   'stealth mnemonic entry (mmgen - minimal entry mode)'),
+		('mnemonic_entry_bip39',           'stealth mnemonic entry (bip39)'),
+		('mnemonic_entry_bip39_short',     'stealth mnemonic entry (bip39 - short entry mode)'),
+		('mn2hex_interactive_mmgen',       'mn2hex_interactive (mmgen)'),
+		('mn2hex_interactive_mmgen_fixed', 'mn2hex_interactive (mmgen - fixed (10-letter) entry mode)'),
+		('mn2hex_interactive_bip39',       'mn2hex_interactive (bip39)'),
+		('mn2hex_interactive_bip39_short', 'mn2hex_interactive (bip39 - short entry mode (+pad entry))'),
+		('mn2hex_interactive_bip39_fixed', 'mn2hex_interactive (bip39 - fixed (4-letter) entry mode)'),
+		('mn2hex_interactive_xmr',         'mn2hex_interactive (xmrseed)'),
+		('mn2hex_interactive_xmr_short',   'mn2hex_interactive (xmrseed - short entry mode)'),
 	),
 	),
 	'dieroll': (
 	'dieroll': (
 		'dieroll entry',
 		'dieroll entry',
@@ -108,79 +108,79 @@ class CmdTestInput(CmdTestBase):
 	}
 	}
 
 
 	def get_seed_from_stdin(self):
 	def get_seed_from_stdin(self):
-		self.spawn('',msg_only=True)
-		from subprocess import run,PIPE
-		cmd = ['python3','cmds/mmgen-walletconv','--in-fmt=words','--out-fmt=words','--outdir=test/trash']
+		self.spawn('', msg_only=True)
+		from subprocess import run, PIPE
+		cmd = ['python3', 'cmds/mmgen-walletconv', '--in-fmt=words', '--out-fmt=words', '--outdir=test/trash']
 		mn = sample_mn['mmgen']['mn']
 		mn = sample_mn['mmgen']['mn']
 		run_env = dict(os.environ)
 		run_env = dict(os.environ)
 		run_env['MMGEN_TEST_SUITE'] = ''
 		run_env['MMGEN_TEST_SUITE'] = ''
 
 
 		# the test can fail the first time if cfg file has changed, so run it twice if necessary:
 		# the test can fail the first time if cfg file has changed, so run it twice if necessary:
 		for _ in range(2):
 		for _ in range(2):
-			cp = run( cmd, input=mn.encode(), stdout=PIPE, stderr=PIPE, env=run_env )
+			cp = run(cmd, input=mn.encode(), stdout=PIPE, stderr=PIPE, env=run_env)
 			if b'written to file' in cp.stderr:
 			if b'written to file' in cp.stderr:
 				break
 				break
 
 
 		from mmgen.color import set_vt100
 		from mmgen.color import set_vt100
 		set_vt100()
 		set_vt100()
 		imsg(cp.stderr.decode().strip())
 		imsg(cp.stderr.decode().strip())
-		res = get_data_from_file(cfg,'test/trash/A773B05C[128].mmwords',silent=True).strip()
+		res = get_data_from_file(cfg, 'test/trash/A773B05C[128].mmwords', silent=True).strip()
 		assert res == mn, f'{res} != {mn}'
 		assert res == mn, f'{res} != {mn}'
 		return 'ok' if b'written to file' in cp.stderr else 'error'
 		return 'ok' if b'written to file' in cp.stderr else 'error'
 
 
 	def get_passphrase_ui(self):
 	def get_passphrase_ui(self):
-		t = self.spawn('test/misc/get_passphrase.py',['--usr-randchars=0','seed'],cmd_dir='.')
+		t = self.spawn('test/misc/get_passphrase.py', ['--usr-randchars=0', 'seed'], cmd_dir='.')
 
 
-		# 1 - new wallet, default hp,label;empty pw
-		t.expect('accept the default.*: ','\n',regex=True)
+		# 1 - new wallet, default hp, label;empty pw
+		t.expect('accept the default.*: ', '\n', regex=True)
 
 
 		# bad repeat
 		# bad repeat
-		t.expect('new MMGen wallet: ','pass1\n')
-		t.expect('peat passphrase: ','pass2\n')
+		t.expect('new MMGen wallet: ', 'pass1\n')
+		t.expect('peat passphrase: ', 'pass2\n')
 
 
 		# good repeat
 		# good repeat
-		t.expect('new MMGen wallet: ','\n')
-		t.expect('peat passphrase: ','\n')
+		t.expect('new MMGen wallet: ', '\n')
+		t.expect('peat passphrase: ', '\n')
 		t.expect('mpty pass')
 		t.expect('mpty pass')
 
 
-		t.expect('no label: ','\n')
+		t.expect('no label: ', '\n')
 
 
 		t.expect('[][3][No Label]')
 		t.expect('[][3][No Label]')
 
 
-		# 2 - new wallet, user-selected hp,pw,label
+		# 2 - new wallet, user-selected hp, pw, label
 		t.expect('accept the default.*: ', '1\n', regex=True)
 		t.expect('accept the default.*: ', '1\n', regex=True)
 
 
-		t.expect('new MMGen wallet: ','pass1\n')
-		t.expect('peat passphrase: ','pass1\n')
+		t.expect('new MMGen wallet: ', 'pass1\n')
+		t.expect('peat passphrase: ', 'pass1\n')
 
 
-		t.expect('no label: ','lbl1\n')
+		t.expect('no label: ', 'lbl1\n')
 
 
 		t.expect('[pass1][1][lbl1]')
 		t.expect('[pass1][1][lbl1]')
 
 
 		# 3 - passchg, nothing changes
 		# 3 - passchg, nothing changes
 		t.expect('new hash preset')
 		t.expect('new hash preset')
-		t.expect('reuse the old value.*: ','\n',regex=True)
+		t.expect('reuse the old value.*: ', '\n', regex=True)
 		t.expect('unchanged')
 		t.expect('unchanged')
 
 
-		t.expect('new passphrase.*: ','pass1\n',regex=True)
-		t.expect('peat new passphrase: ','pass1\n')
+		t.expect('new passphrase.*: ', 'pass1\n', regex=True)
+		t.expect('peat new passphrase: ', 'pass1\n')
 		t.expect('unchanged')
 		t.expect('unchanged')
 
 
-		t.expect('reuse the label .*: ','\n',regex=True)
+		t.expect('reuse the label .*: ', '\n', regex=True)
 		t.expect('unchanged')
 		t.expect('unchanged')
 
 
 		t.expect('[pass1][1][lbl1]')
 		t.expect('[pass1][1][lbl1]')
 
 
 		# 4 - passchg, everything changes
 		# 4 - passchg, everything changes
 		t.expect('new hash preset')
 		t.expect('new hash preset')
-		t.expect('reuse the old value.*: ','2\n',regex=True)
+		t.expect('reuse the old value.*: ', '2\n', regex=True)
 		t.expect(' changed to')
 		t.expect(' changed to')
 
 
-		t.expect('new passphrase.*: ','pass2\n',regex=True)
-		t.expect('peat new passphrase: ','pass2\n')
+		t.expect('new passphrase.*: ', 'pass2\n', regex=True)
+		t.expect('peat new passphrase: ', 'pass2\n')
 		t.expect(' changed')
 		t.expect(' changed')
 
 
-		t.expect('reuse the label .*: ','lbl2\n',regex=True)
+		t.expect('reuse the label .*: ', 'lbl2\n', regex=True)
 		t.expect(' changed to')
 		t.expect(' changed to')
 		t.expect('[pass2][2][lbl2]')
 		t.expect('[pass2][2][lbl2]')
 
 
@@ -188,32 +188,32 @@ class CmdTestInput(CmdTestBase):
 		t.expect('from file')
 		t.expect('from file')
 
 
 		# bad passphrase
 		# bad passphrase
-		t.expect('passphrase for MMGen wallet: ','bad\n')
+		t.expect('passphrase for MMGen wallet: ', 'bad\n')
 		t.expect('Trying again')
 		t.expect('Trying again')
 
 
 		# good passphrase
 		# good passphrase
-		t.expect('passphrase for MMGen wallet: ','reference password\n')
+		t.expect('passphrase for MMGen wallet: ', 'reference password\n')
 		t.expect('[reference password][1][No Label]')
 		t.expect('[reference password][1][No Label]')
 
 
 		return t
 		return t
 
 
 	def get_passphrase_cmdline(self):
 	def get_passphrase_cmdline(self):
-		with open('test/trash/pwfile','w') as fp:
+		with open('test/trash/pwfile', 'w') as fp:
 			fp.write('reference password\n')
 			fp.write('reference password\n')
 		t = self.spawn('test/misc/get_passphrase.py', [
 		t = self.spawn('test/misc/get_passphrase.py', [
 			'--usr-randchars=0',
 			'--usr-randchars=0',
 			'--label=MyLabel',
 			'--label=MyLabel',
 			'--passwd-file=test/trash/pwfile',
 			'--passwd-file=test/trash/pwfile',
 			'--hash-preset=1',
 			'--hash-preset=1',
-			'seed' ],
-			cmd_dir = '.' )
+			'seed'],
+			cmd_dir = '.')
 		for _ in range(4):
 		for _ in range(4):
 			t.expect('[reference password][1][MyLabel]')
 			t.expect('[reference password][1][MyLabel]')
 
 
 		return t
 		return t
 
 
 	def get_passphrase_crypto(self):
 	def get_passphrase_crypto(self):
-		t = self.spawn('test/misc/get_passphrase.py',['--usr-randchars=0','crypto'],cmd_dir='.')
+		t = self.spawn('test/misc/get_passphrase.py', ['--usr-randchars=0', 'crypto'], cmd_dir='.')
 
 
 		# new passwd
 		# new passwd
 		t.expect('passphrase for .*: ', 'x\n', regex=True)
 		t.expect('passphrase for .*: ', 'x\n', regex=True)
@@ -242,20 +242,20 @@ class CmdTestInput(CmdTestBase):
 
 
 	def _input_func(self, func_name, arg_dfls, func_args, text, expect, term, delay=None):
 	def _input_func(self, func_name, arg_dfls, func_args, text, expect, term, delay=None):
 		if term and sys.platform == 'win32':
 		if term and sys.platform == 'win32':
-			return ('skip_warn','pexpect_spawn not supported on Windows platform')
-		func_args = dict(zip(arg_dfls.keys(),func_args))
+			return ('skip_warn', 'pexpect_spawn not supported on Windows platform')
+		func_args = dict(zip(arg_dfls.keys(), func_args))
 		t = self.spawn(
 		t = self.spawn(
 			'test/misc/input_func.py',
 			'test/misc/input_func.py',
-			[func_name,repr(func_args)],
+			[func_name, repr(func_args)],
 			cmd_dir='.',
 			cmd_dir='.',
-			pexpect_spawn=term )
+			pexpect_spawn=term)
 		imsg('Parameters:')
 		imsg('Parameters:')
 		imsg(f'  pexpect_spawn: {term}')
 		imsg(f'  pexpect_spawn: {term}')
 		imsg(f'  sending:       {text!r}')
 		imsg(f'  sending:       {text!r}')
 		imsg(f'  expecting:     {expect!r}')
 		imsg(f'  expecting:     {expect!r}')
 		imsg('\nFunction args:')
 		imsg('\nFunction args:')
-		for k,v in func_args.items():
-			imsg('  {:14} {!r}'.format(k+':',v))
+		for k, v in func_args.items():
+			imsg('  {:14} {!r}'.format(k+':', v))
 		imsg_r('\nScript output: ')
 		imsg_r('\nScript output: ')
 		prompt_add = (func_args['insert_txt'] if term else '') if func_name == 'line_input' else ''
 		prompt_add = (func_args['insert_txt'] if term else '') if func_name == 'line_input' else ''
 		prompt = func_args['prompt'] + prompt_add
 		prompt = func_args['prompt'] + prompt_add
@@ -268,14 +268,14 @@ class CmdTestInput(CmdTestBase):
 		assert ret == repr(expect), f'Text mismatch! {ret} != {repr(expect)}'
 		assert ret == repr(expect), f'Text mismatch! {ret} != {repr(expect)}'
 		return t
 		return t
 
 
-	def _get_char(self,func_args,text,expect,term):
+	def _get_char(self, func_args, text, expect, term):
 		arg_dfls = {
 		arg_dfls = {
 			'prompt': '',
 			'prompt': '',
 			'immed_chars': '',
 			'immed_chars': '',
 			'prehold_protect': True,
 			'prehold_protect': True,
 			'num_bytes': 5,
 			'num_bytes': 5,
 		}
 		}
-		return self._input_func('get_char',arg_dfls,func_args,text,expect,term)
+		return self._input_func('get_char', arg_dfls, func_args, text, expect, term)
 
 
 	def _line_input(self, func_args, text, expect, term, delay=None):
 	def _line_input(self, func_args, text, expect, term, delay=None):
 		arg_dfls = {
 		arg_dfls = {
@@ -287,29 +287,29 @@ class CmdTestInput(CmdTestBase):
 		return self._input_func('line_input', arg_dfls, func_args, text+'\n', expect, term, delay=delay)
 		return self._input_func('line_input', arg_dfls, func_args, text+'\n', expect, term, delay=delay)
 
 
 	def get_char1(self):
 	def get_char1(self):
-		return self._get_char(['prompt> ','',True,5],'x','x',False)
+		return self._get_char(['prompt> ', '', True, 5], 'x', 'x', False)
 
 
 	def get_char2(self):
 	def get_char2(self):
 		expect = 'x' if sys.platform == 'win32' else 'xxxxx'
 		expect = 'x' if sys.platform == 'win32' else 'xxxxx'
-		return self._get_char(['prompt> ','',True,5],'xxxxx',expect,False)
+		return self._get_char(['prompt> ', '', True, 5], 'xxxxx', expect, False)
 
 
 	def get_char3(self):
 	def get_char3(self):
-		return self._get_char(['','',True,5],'x','x',False)
+		return self._get_char(['', '', True, 5], 'x', 'x', False)
 
 
 	def get_char4(self):
 	def get_char4(self):
-		return self._get_char(['prompt> ','',True,2],'α','α',False) # UTF-8, must get 2 bytes
+		return self._get_char(['prompt> ', '', True, 2], 'α', 'α', False) # UTF-8, must get 2 bytes
 
 
 	def get_char_term1(self):
 	def get_char_term1(self):
-		return self._get_char(['prompt> ','',True,2],'β','β',True)  # UTF-8, must get 2 bytes
+		return self._get_char(['prompt> ', '', True, 2], 'β', 'β', True)  # UTF-8, must get 2 bytes
 
 
 	def get_char_term2(self):
 	def get_char_term2(self):
-		return self._get_char(['prompt> ','',True,5],'xxxxx','xxxxx',True)
+		return self._get_char(['prompt> ', '', True, 5], 'xxxxx', 'xxxxx', True)
 
 
 	def get_char_term3(self):
 	def get_char_term3(self):
-		return self._get_char(['','',False,5],'x','x',True)
+		return self._get_char(['', '', False, 5], 'x', 'x', True)
 
 
 	def get_char_term4(self):
 	def get_char_term4(self):
-		return self._get_char(['prompt> ','xyz',False,5],'x','x',True)
+		return self._get_char(['prompt> ', 'xyz', False, 5], 'x', 'x', True)
 
 
 	def line_input(self):
 	def line_input(self):
 		return self._line_input(
 		return self._line_input(
@@ -387,13 +387,13 @@ class CmdTestInput(CmdTestBase):
 			True,
 			True,
 			hold_protect_delay)
 			hold_protect_delay)
 
 
-	def _password_entry(self,prompt,opts=[],term=False):
+	def _password_entry(self, prompt, opts=[], term=False):
 		if term and sys.platform == 'win32':
 		if term and sys.platform == 'win32':
-			return ('skip_warn','pexpect_spawn not supported on Windows platform')
-		t = self.spawn( 'test/misc/input_func.py', opts + ['passphrase'], cmd_dir='.', pexpect_spawn=term )
+			return ('skip_warn', 'pexpect_spawn not supported on Windows platform')
+		t = self.spawn('test/misc/input_func.py', opts + ['passphrase'], cmd_dir='.', pexpect_spawn=term)
 		imsg(f'Terminal: {term}')
 		imsg(f'Terminal: {term}')
 		pw = 'abc-α'
 		pw = 'abc-α'
-		t.expect(prompt,pw+'\n')
+		t.expect(prompt, pw+'\n')
 		ret = t.expect_getend('Entered: ')
 		ret = t.expect_getend('Entered: ')
 		assert ret == pw, f'Password mismatch! {ret} != {pw}'
 		assert ret == pw, f'Password mismatch! {ret} != {pw}'
 		return t
 		return t
@@ -406,35 +406,35 @@ class CmdTestInput(CmdTestBase):
 		  test/misc/input_func.py{} passphrase
 		  test/misc/input_func.py{} passphrase
 	"""
 	"""
 
 
-	def password_entry_noecho(self,term=False):
-		return self._password_entry('Enter passphrase: ',term=term)
+	def password_entry_noecho(self, term=False):
+		return self._password_entry('Enter passphrase: ', term=term)
 
 
 	def password_entry_noecho_term(self):
 	def password_entry_noecho_term(self):
 		if self.skip_for_win('no pexpect_spawn'):
 		if self.skip_for_win('no pexpect_spawn'):
-			return ('skip_warn','\n' + fmt(self.winskip_msg.format(''),strip_char='\t'))
+			return ('skip_warn', '\n' + fmt(self.winskip_msg.format(''), strip_char='\t'))
 		return self.password_entry_noecho(term=True)
 		return self.password_entry_noecho(term=True)
 
 
-	def password_entry_echo(self,term=False):
-		return self._password_entry('Enter passphrase (echoed): ',['--echo-passphrase'],term=term)
+	def password_entry_echo(self, term=False):
+		return self._password_entry('Enter passphrase (echoed): ', ['--echo-passphrase'], term=term)
 
 
 	def password_entry_echo_term(self):
 	def password_entry_echo_term(self):
 		if self.skip_for_win('no pexpect_spawn'):
 		if self.skip_for_win('no pexpect_spawn'):
-			return ('skip_warn','\n' + fmt(self.winskip_msg.format(' --echo-passphrase'),strip_char='\t'))
+			return ('skip_warn', '\n' + fmt(self.winskip_msg.format(' --echo-passphrase'), strip_char='\t'))
 		return self.password_entry_echo(term=True)
 		return self.password_entry_echo(term=True)
 
 
-	def _mn2hex(self,fmt,entry_mode='full',mn=None,pad_entry=False,enter_for_dfl=False):
+	def _mn2hex(self, fmt, entry_mode='full', mn=None, pad_entry=False, enter_for_dfl=False):
 		mn = mn or sample_mn[fmt]['mn'].split()
 		mn = mn or sample_mn[fmt]['mn'].split()
-		t = self.spawn('mmgen-tool',['mn2hex_interactive','fmt='+fmt,'mn_len=12','print_mn=1'])
+		t = self.spawn('mmgen-tool', ['mn2hex_interactive', 'fmt='+fmt, 'mn_len=12', 'print_mn=1'])
 		from mmgen.mn_entry import mn_entry
 		from mmgen.mn_entry import mn_entry
-		mne = mn_entry( cfg, fmt, entry_mode )
+		mne = mn_entry(cfg, fmt, entry_mode)
 		t.expect(
 		t.expect(
 			'Type a number.*: ',
 			'Type a number.*: ',
 			('\n' if enter_for_dfl else str(mne.entry_modes.index(entry_mode)+1)),
 			('\n' if enter_for_dfl else str(mne.entry_modes.index(entry_mode)+1)),
-			regex = True )
+			regex = True)
 		t.expect(r'Using entry mode (\S+)', regex=True)
 		t.expect(r'Using entry mode (\S+)', regex=True)
 		mode = strip_ansi_escapes(t.p.match.group(1)).lower()
 		mode = strip_ansi_escapes(t.p.match.group(1)).lower()
 		assert mode == mne.em.name.lower(), f'{mode} != {mne.em.name.lower()}'
 		assert mode == mne.em.name.lower(), f'{mode} != {mne.em.name.lower()}'
-		stealth_mnemonic_entry(t,mne,mn,entry_mode=entry_mode,pad_entry=pad_entry)
+		stealth_mnemonic_entry(t, mne, mn, entry_mode=entry_mode, pad_entry=pad_entry)
 		t.expect(sample_mn[fmt]['hex'])
 		t.expect(sample_mn[fmt]['hex'])
 		return t
 		return t
 
 
@@ -448,52 +448,52 @@ class CmdTestInput(CmdTestBase):
 			seedlen_opt = False):
 			seedlen_opt = False):
 
 
 		wcls = get_wallet_cls(fmt_code=fmt)
 		wcls = get_wallet_cls(fmt_code=fmt)
-		wf = os.path.join(ref_dir,f'FE3C6545.{wcls.ext}')
+		wf = os.path.join(ref_dir, f'FE3C6545.{wcls.ext}')
 		if wcls.base_type == 'mnemonic':
 		if wcls.base_type == 'mnemonic':
 			mn = mn or read_from_file(wf).strip().split()
 			mn = mn or read_from_file(wf).strip().split()
 		elif wcls.type == 'dieroll':
 		elif wcls.type == 'dieroll':
 			mn = mn or list(remove_whitespace(read_from_file(wf)))
 			mn = mn or list(remove_whitespace(read_from_file(wf)))
-			for idx,val in ((5,'x'),(18,'0'),(30,'7'),(44,'9')):
-				mn.insert(idx,val)
+			for idx, val in ((5, 'x'), (18, '0'), (30, '7'), (44, '9')):
+				mn.insert(idx, val)
 		t = self.spawn(
 		t = self.spawn(
 			'mmgen-walletconv',
 			'mmgen-walletconv',
 			['--usr-randchars=10', '--stdout']
 			['--usr-randchars=10', '--stdout']
 			+ (['--seed-len=128'] if seedlen_opt else [])
 			+ (['--seed-len=128'] if seedlen_opt else [])
 			+ [f'--in-fmt={fmt}', f'--out-fmt={out_fmt or fmt}']
 			+ [f'--in-fmt={fmt}', f'--out-fmt={out_fmt or fmt}']
 		)
 		)
-		t.expect(f'{capfirst(wcls.base_type or wcls.type)} type:.*{wcls.mn_type}',regex=True)
+		t.expect(f'{capfirst(wcls.base_type or wcls.type)} type:.*{wcls.mn_type}', regex=True)
 		if not seedlen_opt:
 		if not seedlen_opt:
-			t.expect(wcls.choose_seedlen_prompt,'1')
-			t.expect('(Y/n): ','y')
+			t.expect(wcls.choose_seedlen_prompt, '1')
+			t.expect('(Y/n): ', 'y')
 		if wcls.base_type == 'mnemonic':
 		if wcls.base_type == 'mnemonic':
-			t.expect('Type a number.*: ','6',regex=True)
+			t.expect('Type a number.*: ', '6', regex=True)
 			t.expect('invalid')
 			t.expect('invalid')
 			from mmgen.mn_entry import mn_entry
 			from mmgen.mn_entry import mn_entry
-			mne = mn_entry( cfg, fmt, entry_mode )
-			t.expect('Type a number.*: ',str(mne.entry_modes.index(entry_mode)+1),regex=True)
-			t.expect(r'Using entry mode (\S+)',regex=True)
+			mne = mn_entry(cfg, fmt, entry_mode)
+			t.expect('Type a number.*: ', str(mne.entry_modes.index(entry_mode)+1), regex=True)
+			t.expect(r'Using entry mode (\S+)', regex=True)
 			mode = strip_ansi_escapes(t.p.match.group(1)).lower()
 			mode = strip_ansi_escapes(t.p.match.group(1)).lower()
 			assert mode == mne.em.name.lower(), f'{mode} != {mne.em.name.lower()}'
 			assert mode == mne.em.name.lower(), f'{mode} != {mne.em.name.lower()}'
-			stealth_mnemonic_entry(t,mne,mn,entry_mode=entry_mode)
+			stealth_mnemonic_entry(t, mne, mn, entry_mode=entry_mode)
 		elif wcls.type == 'dieroll':
 		elif wcls.type == 'dieroll':
-			user_dieroll_entry(t,mn)
+			user_dieroll_entry(t, mn)
 			if usr_rand:
 			if usr_rand:
-				t.expect(wcls.user_entropy_prompt,'y')
+				t.expect(wcls.user_entropy_prompt, 'y')
 				t.usr_rand(10)
 				t.usr_rand(10)
 			else:
 			else:
-				t.expect(wcls.user_entropy_prompt,'n')
+				t.expect(wcls.user_entropy_prompt, 'n')
 		if not usr_rand:
 		if not usr_rand:
 			sid_chk = 'FE3C6545'
 			sid_chk = 'FE3C6545'
 			sid = t.expect_getend(f'Valid {wcls.desc} for Seed ID')
 			sid = t.expect_getend(f'Valid {wcls.desc} for Seed ID')
 			sid = strip_ansi_escapes(sid.split(',')[0])
 			sid = strip_ansi_escapes(sid.split(',')[0])
 			assert sid_chk in sid, f'Seed ID mismatch! {sid_chk} not found in {sid}'
 			assert sid_chk in sid, f'Seed ID mismatch! {sid_chk} not found in {sid}'
-		t.expect('to confirm: ','YES\n')
+		t.expect('to confirm: ', 'YES\n')
 		return t
 		return t
 
 
 	def mnemonic_entry_mmgen_minimal(self):
 	def mnemonic_entry_mmgen_minimal(self):
 		from mmgen.mn_entry import mn_entry
 		from mmgen.mn_entry import mn_entry
 		# erase_chars: '\b\x7f'
 		# erase_chars: '\b\x7f'
-		m = mn_entry( cfg, 'mmgen', 'minimal' )
+		m = mn_entry(cfg, 'mmgen', 'minimal')
 		np = 2
 		np = 2
 		mn = (
 		mn = (
 			'z',
 			'z',
@@ -511,30 +511,30 @@ class CmdTestInput(CmdTestBase):
 			'app\bpl',
 			'app\bpl',
 			'wd',
 			'wd',
 			'busy')
 			'busy')
-		return self._user_seed_entry('words',entry_mode='minimal',mn=mn)
+		return self._user_seed_entry('words', entry_mode='minimal', mn=mn)
 	def mnemonic_entry_mmgen(self):
 	def mnemonic_entry_mmgen(self):
-		return self._user_seed_entry('words',entry_mode='full')
+		return self._user_seed_entry('words', entry_mode='full')
 	def mnemonic_entry_bip39(self):
 	def mnemonic_entry_bip39(self):
-		return self._user_seed_entry('bip39',entry_mode='full')
+		return self._user_seed_entry('bip39', entry_mode='full')
 	def mnemonic_entry_bip39_short(self):
 	def mnemonic_entry_bip39_short(self):
-		return self._user_seed_entry('bip39',entry_mode='short')
+		return self._user_seed_entry('bip39', entry_mode='short')
 
 
 	def mn2hex_interactive_mmgen(self):
 	def mn2hex_interactive_mmgen(self):
-		return self._mn2hex('mmgen',entry_mode='full')
+		return self._mn2hex('mmgen', entry_mode='full')
 	def mn2hex_interactive_mmgen_fixed(self):
 	def mn2hex_interactive_mmgen_fixed(self):
-		return self._mn2hex('mmgen',entry_mode='fixed')
+		return self._mn2hex('mmgen', entry_mode='fixed')
 	def mn2hex_interactive_bip39(self):
 	def mn2hex_interactive_bip39(self):
-		return self._mn2hex('bip39',entry_mode='full')
+		return self._mn2hex('bip39', entry_mode='full')
 	def mn2hex_interactive_bip39_short(self):
 	def mn2hex_interactive_bip39_short(self):
-		return self._mn2hex('bip39',entry_mode='short',pad_entry=True)
+		return self._mn2hex('bip39', entry_mode='short', pad_entry=True)
 	def mn2hex_interactive_bip39_fixed(self):
 	def mn2hex_interactive_bip39_fixed(self):
-		return self._mn2hex('bip39',entry_mode='fixed',enter_for_dfl=True)
+		return self._mn2hex('bip39', entry_mode='fixed', enter_for_dfl=True)
 	def mn2hex_interactive_xmr(self):
 	def mn2hex_interactive_xmr(self):
-		return self._mn2hex('xmrseed',entry_mode='full')
+		return self._mn2hex('xmrseed', entry_mode='full')
 	def mn2hex_interactive_xmr_short(self):
 	def mn2hex_interactive_xmr_short(self):
-		return self._mn2hex('xmrseed',entry_mode='short')
+		return self._mn2hex('xmrseed', entry_mode='short')
 
 
 	def dieroll_entry(self):
 	def dieroll_entry(self):
 		return self._user_seed_entry('dieroll', seedlen_opt=True)
 		return self._user_seed_entry('dieroll', seedlen_opt=True)
 	def dieroll_entry_usrrand(self):
 	def dieroll_entry_usrrand(self):
-		return self._user_seed_entry('dieroll',usr_rand=True,out_fmt='bip39')
+		return self._user_seed_entry('dieroll', usr_rand=True, out_fmt='bip39')

File diff suppressed because it is too large
+ 411 - 317
test/cmdtest_py_d/ct_main.py


+ 63 - 58
test/cmdtest_py_d/ct_misc.py

@@ -39,8 +39,8 @@ class CmdTestDev(CmdTestBase):
 	tmpdir_nums = [99]
 	tmpdir_nums = [99]
 	color = True
 	color = True
 
 
-	def _spawn(self,script,args):
-		return self.spawn(script,args,cmd_dir='.',no_exec_wrapper=True)
+	def _spawn(self, script, args):
+		return self.spawn(script, args, cmd_dir='.', no_exec_wrapper=True)
 
 
 	def compute_file_chksum(self):
 	def compute_file_chksum(self):
 		t = self._spawn('scripts/compute-file-chksum.py', ['test/ref/25EFA3[2.34].testnet.rawtx'])
 		t = self._spawn('scripts/compute-file-chksum.py', ['test/ref/25EFA3[2.34].testnet.rawtx'])
@@ -50,28 +50,29 @@ class CmdTestDev(CmdTestBase):
 	def create_bip_hd_chain_params(self):
 	def create_bip_hd_chain_params(self):
 		t = self._spawn('scripts/create-bip-hd-chain-params.py', ['test/ref/altcoin/slip44-mini.json'])
 		t = self._spawn('scripts/create-bip-hd-chain-params.py', ['test/ref/altcoin/slip44-mini.json'])
 		t.expect('[defaults]')
 		t.expect('[defaults]')
-		t.expect(r"secp.*0488ade4.*0488b21e.*0'\/0\/0",regex=True)
+		t.expect(r"secp.*0488ade4.*0488b21e.*0'\/0\/0", regex=True)
 		t.expect('[bip-44]')
 		t.expect('[bip-44]')
 		t.expect('[bip-49]')
 		t.expect('[bip-49]')
-		t.match_expect_list(['0','BTC','x','m','P2SH','049d7878','049d7cb2','80','05','x','Bitcoin','1'])
+		t.match_expect_list(
+			['0', 'BTC', 'x', 'm', 'P2SH', '049d7878', '049d7cb2', '80', '05', 'x', 'Bitcoin', '1'])
 		return t
 		return t
 
 
 class CmdTestMisc(CmdTestBase):
 class CmdTestMisc(CmdTestBase):
 	'miscellaneous tests (RPC backends, xmrwallet_txview, term)'
 	'miscellaneous tests (RPC backends, xmrwallet_txview, term)'
 	networks = ('btc',)
 	networks = ('btc',)
 	tmpdir_nums = [99]
 	tmpdir_nums = [99]
-	passthru_opts = ('daemon_data_dir','rpc_port')
+	passthru_opts = ('daemon_data_dir', 'rpc_port')
 	cmd_group = (
 	cmd_group = (
 		('rpc_backends',         'RPC backends'),
 		('rpc_backends',         'RPC backends'),
-		('bch_txview_legacy1',   "'mmgen-tool --coin=bch --cashaddr=0 txview terse=0'"),
-		('bch_txview_legacy2',   "'mmgen-tool --coin=bch --cashaddr=0 txview terse=1'"),
-		('bch_txview_cashaddr1', "'mmgen-tool --coin=bch --cashaddr=1 txview terse=0'"),
-		('bch_txview_cashaddr2', "'mmgen-tool --coin=bch --cashaddr=1 txview terse=1'"),
-		('xmrwallet_txview',     "'mmgen-xmrwallet' txview"),
-		('xmrwallet_txlist',     "'mmgen-xmrwallet' txlist"),
-		('coin_daemon_info',     "'examples/coin-daemon-info.py'"),
-		('examples_bip_hd',      "'examples/bip_hd.py'"),
-		('term_echo',            "term.set('echo')"),
+		('bch_txview_legacy1',   'mmgen-tool --coin=bch --cashaddr=0 txview terse=0'),
+		('bch_txview_legacy2',   'mmgen-tool --coin=bch --cashaddr=0 txview terse=1'),
+		('bch_txview_cashaddr1', 'mmgen-tool --coin=bch --cashaddr=1 txview terse=0'),
+		('bch_txview_cashaddr2', 'mmgen-tool --coin=bch --cashaddr=1 txview terse=1'),
+		('xmrwallet_txview',     '‘mmgen-xmrwallet txview’'),
+		('xmrwallet_txlist',     '‘mmgen-xmrwallet txlist’'),
+		('coin_daemon_info',     'examples/coin-daemon-info.py'),
+		('examples_bip_hd',      'examples/bip_hd.py'),
+		('term_echo',            'term.set("echo")'),
 		('term_cleanup',         'term.register_cleanup()'),
 		('term_cleanup',         'term.register_cleanup()'),
 	)
 	)
 	need_daemon = True
 	need_daemon = True
@@ -80,7 +81,7 @@ class CmdTestMisc(CmdTestBase):
 	def rpc_backends(self):
 	def rpc_backends(self):
 		backends = cfg._autoset_opts['rpc_backend'][1]
 		backends = cfg._autoset_opts['rpc_backend'][1]
 		for b in backends:
 		for b in backends:
-			t = self.spawn_chk('mmgen-tool',[f'--rpc-backend={b}','daemon_version'],extra_desc=f'({b})')
+			t = self.spawn_chk('mmgen-tool', [f'--rpc-backend={b}', 'daemon_version'], extra_desc=f'({b})')
 		return t
 		return t
 
 
 	def _bch_txview(self, view_pref, terse, expect):
 	def _bch_txview(self, view_pref, terse, expect):
@@ -104,11 +105,11 @@ class CmdTestMisc(CmdTestBase):
 	def bch_txview_cashaddr2(self):
 	def bch_txview_cashaddr2(self):
 		return self._bch_txview(1, 1, '[1HpynST7vkLn8yNtdrqPfeghexZk4sdB3W]')
 		return self._bch_txview(1, 1, '[1HpynST7vkLn8yNtdrqPfeghexZk4sdB3W]')
 
 
-	def xmrwallet_txview(self,op='txview'):
+	def xmrwallet_txview(self, op='txview'):
 		if cfg.no_altcoin:
 		if cfg.no_altcoin:
 			return 'skip'
 			return 'skip'
-		files = get_file_with_ext('test/ref/monero','tx',no_dot=True,delete=False,return_list=True)
-		t = self.spawn( 'mmgen-xmrwallet', [op] + files )
+		files = get_file_with_ext('test/ref/monero', 'tx', no_dot=True, delete=False, return_list=True)
+		t = self.spawn('mmgen-xmrwallet', [op] + files)
 		res = t.read(strip_color=True)
 		res = t.read(strip_color=True)
 		if op == 'txview':
 		if op == 'txview':
 			for s in (
 			for s in (
@@ -117,7 +118,7 @@ class CmdTestMisc(CmdTestBase):
 			):
 			):
 				assert s in res, f'{s} not in {res}'
 				assert s in res, f'{s} not in {res}'
 		elif op == 'txlist':
 		elif op == 'txlist':
-			assert re.search( '3EBD06-.*D94583-.*8BFA29-', res, re.DOTALL )
+			assert re.search('3EBD06-.*D94583-.*8BFA29-', res, re.DOTALL)
 		return t
 		return t
 
 
 	def xmrwallet_txlist(self):
 	def xmrwallet_txlist(self):
@@ -126,31 +127,31 @@ class CmdTestMisc(CmdTestBase):
 	def examples_bip_hd(self):
 	def examples_bip_hd(self):
 		if cfg.no_altcoin:
 		if cfg.no_altcoin:
 			return 'skip'
 			return 'skip'
-		return self.spawn('examples/bip_hd.py',cmd_dir='.')
+		return self.spawn('examples/bip_hd.py', cmd_dir='.')
 
 
 	def coin_daemon_info(self):
 	def coin_daemon_info(self):
 		if cfg.no_altcoin:
 		if cfg.no_altcoin:
 			coins = ['btc']
 			coins = ['btc']
 		else:
 		else:
-			coins = ['btc','ltc','eth']
-			start_test_daemons('ltc','eth')
-		t = self.spawn('examples/coin-daemon-info.py',coins,cmd_dir='.')
+			coins = ['btc', 'ltc', 'eth']
+			start_test_daemons('ltc', 'eth')
+		t = self.spawn('examples/coin-daemon-info.py', coins, cmd_dir='.')
 		for coin in coins:
 		for coin in coins:
-			t.expect(coin.upper() + r'\s+mainnet\s+Up',regex=True)
+			t.expect(coin.upper() + r'\s+mainnet\s+Up', regex=True)
 		if cfg.pexpect_spawn:
 		if cfg.pexpect_spawn:
 			t.send('q')
 			t.send('q')
 		if not cfg.no_altcoin:
 		if not cfg.no_altcoin:
-			stop_test_daemons('ltc','eth')
+			stop_test_daemons('ltc', 'eth')
 		return t
 		return t
 
 
 	def term_echo(self):
 	def term_echo(self):
 
 
 		def test_echo():
 		def test_echo():
-			t.expect('echo> ','foo\n')
+			t.expect('echo> ', 'foo\n')
 			t.expect('foo')
 			t.expect('foo')
 
 
 		def test_noecho():
 		def test_noecho():
-			t.expect('noecho> ','foo\n')
+			t.expect('noecho> ', 'foo\n')
 			import pexpect
 			import pexpect
 			try:
 			try:
 				t.expect('foo')
 				t.expect('foo')
@@ -163,7 +164,7 @@ class CmdTestMisc(CmdTestBase):
 		if self.skip_for_win('no termios support') or self.skip_for_mac('termios.ECHO issues'):
 		if self.skip_for_win('no termios support') or self.skip_for_mac('termios.ECHO issues'):
 			return 'skip'
 			return 'skip'
 
 
-		t = self.spawn('test/misc/term_ni.py',['echo'],cmd_dir='.',pexpect_spawn=True,timeout=1)
+		t = self.spawn('test/misc/term_ni.py', ['echo'], cmd_dir='.', pexpect_spawn=True, timeout=1)
 		t.p.logfile = None
 		t.p.logfile = None
 		t.p.logfile_read = sys.stdout if cfg.verbose or cfg.exact_output else None
 		t.p.logfile_read = sys.stdout if cfg.verbose or cfg.exact_output else None
 		t.p.logfile_send = None
 		t.p.logfile_send = None
@@ -177,23 +178,23 @@ class CmdTestMisc(CmdTestBase):
 	def term_cleanup(self):
 	def term_cleanup(self):
 		if self.skip_for_win('no termios support'):
 		if self.skip_for_win('no termios support'):
 			return 'skip'
 			return 'skip'
-		return self.spawn('test/misc/term_ni.py',['cleanup'],cmd_dir='.',pexpect_spawn=True)
+		return self.spawn('test/misc/term_ni.py', ['cleanup'], cmd_dir='.', pexpect_spawn=True)
 
 
 class CmdTestOutput(CmdTestBase):
 class CmdTestOutput(CmdTestBase):
 	'screen output'
 	'screen output'
 	networks = ('btc',)
 	networks = ('btc',)
 	cmd_group = (
 	cmd_group = (
-		('output_gr', (1,"Greek text", [])),
-		('output_ru', (1,"Russian text", [])),
-		('output_zh', (1,"Chinese text", [])),
-		('output_jp', (1,"Japanese text", [])),
-		('oneshot_warning', (1,"Oneshot warnings", [])),
-		('oneshot_warning_term', (1,"Oneshot warnings (pexpect_spawn)", []))
+		('output_gr',            (1, 'Greek text', [])),
+		('output_ru',            (1, 'Russian text', [])),
+		('output_zh',            (1, 'Chinese text', [])),
+		('output_jp',            (1, 'Japanese text', [])),
+		('oneshot_warning',      (1, 'Oneshot warnings', [])),
+		('oneshot_warning_term', (1, 'Oneshot warnings (pexpect_spawn)', []))
 	)
 	)
 	color = True
 	color = True
 
 
-	def screen_output(self,lang):
-		return self.spawn('test/misc/utf8_output.py',[lang],cmd_dir='.')
+	def screen_output(self, lang):
+		return self.spawn('test/misc/utf8_output.py', [lang], cmd_dir='.')
 
 
 	def output_gr(self):
 	def output_gr(self):
 		return self.screen_output('gr')
 		return self.screen_output('gr')
@@ -204,8 +205,8 @@ class CmdTestOutput(CmdTestBase):
 	def output_jp(self):
 	def output_jp(self):
 		return self.screen_output('jp')
 		return self.screen_output('jp')
 
 
-	def oneshot_warning(self,pexpect_spawn=None):
-		t = self.spawn('test/misc/oneshot_warning.py',cmd_dir='.',pexpect_spawn=pexpect_spawn)
+	def oneshot_warning(self, pexpect_spawn=None):
+		t = self.spawn('test/misc/oneshot_warning.py', cmd_dir='.', pexpect_spawn=pexpect_spawn)
 		nl = '\r\n' if sys.platform == 'win32' or t.pexpect_spawn else '\n'
 		nl = '\r\n' if sys.platform == 'win32' or t.pexpect_spawn else '\n'
 		for s in (
 		for s in (
 			f'pw{nl}wg1',
 			f'pw{nl}wg1',
@@ -234,33 +235,37 @@ class CmdTestOutput(CmdTestBase):
 			return 'skip'
 			return 'skip'
 		return self.oneshot_warning(pexpect_spawn=True)
 		return self.oneshot_warning(pexpect_spawn=True)
 
 
-class CmdTestRefTX(CmdTestMain,CmdTestBase):
+class CmdTestRefTX(CmdTestMain, CmdTestBase):
 	'create a reference transaction file (administrative command)'
 	'create a reference transaction file (administrative command)'
 	segwit_opts_ok = False
 	segwit_opts_ok = False
-	passthru_opts = ('daemon_data_dir','rpc_port','coin','testnet')
-	tmpdir_nums = [31,32,33,34]
+	passthru_opts = ('daemon_data_dir', 'rpc_port', 'coin', 'testnet')
+	tmpdir_nums = [31, 32, 33, 34]
 	need_daemon = True
 	need_daemon = True
 	cmd_group = (
 	cmd_group = (
-		('ref_tx_addrgen1', (31,'address generation (legacy)', [[[],1]])),
-		('ref_tx_addrgen2', (32,'address generation (compressed)', [[[],1]])),
-		('ref_tx_addrgen3', (33,'address generation (segwit)', [[[],1]])),
-		('ref_tx_addrgen4', (34,'address generation (bech32)', [[[],1]])),
-		('ref_tx_txcreate', (31,'transaction creation',
-								([['addrs'],31],[['addrs'],32],[['addrs'],33],[['addrs'],34]))),
+		('ref_tx_addrgen1', (31, 'address generation (legacy)',     [[[], 1]])),
+		('ref_tx_addrgen2', (32, 'address generation (compressed)', [[[], 1]])),
+		('ref_tx_addrgen3', (33, 'address generation (segwit)',     [[[], 1]])),
+		('ref_tx_addrgen4', (34, 'address generation (bech32)',     [[[], 1]])),
+		('ref_tx_txcreate',
+			(31, 'transaction creation',
+			([['addrs'], 31], [['addrs'], 32], [['addrs'], 33], [['addrs'], 34]))
+		),
 	)
 	)
 
 
-	def __init__(self,trunner,cfgs,spawn):
+	def __init__(self, trunner, cfgs, spawn):
 		if cfgs:
 		if cfgs:
 			for n in self.tmpdir_nums:
 			for n in self.tmpdir_nums:
-				cfgs[str(n)].update({   'addr_idx_list': '1-2',
-										'segwit': n in (33,34),
-										'dep_generators': { 'addrs':'ref_tx_addrgen'+str(n)[-1] }})
-		CmdTestMain.__init__(self,trunner,cfgs,spawn)
-
-	def ref_tx_addrgen(self,atype):
+				cfgs[str(n)].update({
+					'addr_idx_list': '1-2',
+					'segwit': n in (33, 34),
+					'dep_generators': {'addrs':'ref_tx_addrgen'+str(n)[-1]}
+				})
+		CmdTestMain.__init__(self, trunner, cfgs, spawn)
+
+	def ref_tx_addrgen(self, atype):
 		if atype not in self.proto.mmtypes:
 		if atype not in self.proto.mmtypes:
 			return
 			return
-		return self.spawn('mmgen-addrgen',['--outdir='+self.tmpdir,'--type='+atype,dfl_words_file,'1-2'])
+		return self.spawn('mmgen-addrgen', ['--outdir='+self.tmpdir, '--type='+atype, dfl_words_file, '1-2'])
 
 
 	def ref_tx_addrgen1(self):
 	def ref_tx_addrgen1(self):
 		return self.ref_tx_addrgen(atype='L')
 		return self.ref_tx_addrgen(atype='L')
@@ -271,8 +276,8 @@ class CmdTestRefTX(CmdTestMain,CmdTestBase):
 	def ref_tx_addrgen4(self):
 	def ref_tx_addrgen4(self):
 		return self.ref_tx_addrgen(atype='B')
 		return self.ref_tx_addrgen(atype='B')
 
 
-	def ref_tx_txcreate(self,f1,f2,f3,f4):
-		sources = ['31','32']
+	def ref_tx_txcreate(self, f1, f2, f3, f4):
+		sources = ['31', '32']
 		if 'S' in self.proto.mmtypes:
 		if 'S' in self.proto.mmtypes:
 			sources += ['33']
 			sources += ['33']
 		if 'B' in self.proto.mmtypes:
 		if 'B' in self.proto.mmtypes:

+ 87 - 87
test/cmdtest_py_d/ct_opts.py

@@ -10,7 +10,7 @@
 test.cmdtest_py_d.ct_opts: options processing tests for the MMGen cmdtest.py test suite
 test.cmdtest_py_d.ct_opts: options processing tests for the MMGen cmdtest.py test suite
 """
 """
 
 
-import os,time
+import os, time
 
 
 from ..include.common import cfg
 from ..include.common import cfg
 from .ct_base import CmdTestBase
 from .ct_base import CmdTestBase
@@ -46,41 +46,41 @@ class CmdTestOpts(CmdTestBase):
 		('opt_bad_outdir',       (41, 'bad outdir parameter', [])),
 		('opt_bad_outdir',       (41, 'bad outdir parameter', [])),
 		('opt_bad_incompatible', (41, 'incompatible opts', [])),
 		('opt_bad_incompatible', (41, 'incompatible opts', [])),
 		('opt_bad_autoset',      (41, 'invalid autoset value', [])),
 		('opt_bad_autoset',      (41, 'invalid autoset value', [])),
-		('opt_invalid_1',     (41, 'invalid cmdline opt ‘--x’', [])),
-		('opt_invalid_2',     (41, 'invalid cmdline opt ‘---’', [])),
-		('opt_invalid_5',     (41, 'invalid cmdline opt (missing parameter)', [])),
-		('opt_invalid_6',     (41, 'invalid cmdline opt (missing parameter)', [])),
-		('opt_invalid_7',     (41, 'invalid cmdline opt (parameter not required)', [])),
-		('opt_invalid_8',     (41, 'invalid cmdline opt (non-existent option)', [])),
-		('opt_invalid_9',     (41, 'invalid cmdline opt (non-existent option)', [])),
-		('opt_invalid_10',    (41, 'invalid cmdline opt (missing parameter)', [])),
-		('opt_invalid_11',    (41, 'invalid cmdline opt (missing parameter)', [])),
-		('opt_invalid_12',    (41, 'invalid cmdline opt (non-existent option)', [])),
-		('opt_invalid_13',    (41, 'invalid cmdline opt (ambiguous long opt substring)', [])),
-		('opt_invalid_14',    (41, 'invalid cmdline opt (long opt substring too short)', [])),
-		('opt_invalid_15',    (41, 'invalid cmdline (too many args)', [])),
-		('opt_invalid_16',    (41, 'invalid cmdline (overlong arg)', [])),
+		('opt_invalid_1',        (41, 'invalid cmdline opt ‘--x’', [])),
+		('opt_invalid_2',        (41, 'invalid cmdline opt ‘---’', [])),
+		('opt_invalid_5',        (41, 'invalid cmdline opt (missing parameter)', [])),
+		('opt_invalid_6',        (41, 'invalid cmdline opt (missing parameter)', [])),
+		('opt_invalid_7',        (41, 'invalid cmdline opt (parameter not required)', [])),
+		('opt_invalid_8',        (41, 'invalid cmdline opt (non-existent option)', [])),
+		('opt_invalid_9',        (41, 'invalid cmdline opt (non-existent option)', [])),
+		('opt_invalid_10',       (41, 'invalid cmdline opt (missing parameter)', [])),
+		('opt_invalid_11',       (41, 'invalid cmdline opt (missing parameter)', [])),
+		('opt_invalid_12',       (41, 'invalid cmdline opt (non-existent option)', [])),
+		('opt_invalid_13',       (41, 'invalid cmdline opt (ambiguous long opt substring)', [])),
+		('opt_invalid_14',       (41, 'invalid cmdline opt (long opt substring too short)', [])),
+		('opt_invalid_15',       (41, 'invalid cmdline (too many args)', [])),
+		('opt_invalid_16',       (41, 'invalid cmdline (overlong arg)', [])),
 	)
 	)
 
 
 	def spawn_prog(self, args, exit_val=None):
 	def spawn_prog(self, args, exit_val=None):
 		return self.spawn('test/misc/opts.py', args, cmd_dir='.', exit_val=exit_val)
 		return self.spawn('test/misc/opts.py', args, cmd_dir='.', exit_val=exit_val)
 
 
-	def check_vals(self,args,vals):
+	def check_vals(self, args, vals):
 		t = self.spawn_prog(args)
 		t = self.spawn_prog(args)
-		for k,v in vals:
-			t.expect(rf'{k}:\s+{v}',regex=True)
+		for k, v in vals:
+			t.expect(rf'{k}:\s+{v}', regex=True)
 		return t
 		return t
 
 
-	def do_run(self,args,expect,exit_val,regex=False):
+	def do_run(self, args, expect, exit_val, regex=False):
 		t = self.spawn_prog(args, exit_val=exit_val or None)
 		t = self.spawn_prog(args, exit_val=exit_val or None)
-		t.expect(expect,regex=regex)
+		t.expect(expect, regex=regex)
 		return t
 		return t
 
 
 	def opt_helpscreen(self):
 	def opt_helpscreen(self):
 		expect = r'OPTS.PY: Opts test.*USAGE:\s+opts.py'
 		expect = r'OPTS.PY: Opts test.*USAGE:\s+opts.py'
 		if not cfg.pexpect_spawn:
 		if not cfg.pexpect_spawn:
 			expect += r'.*--minconf.*NOTES FOR THIS.*a note'
 			expect += r'.*--minconf.*NOTES FOR THIS.*a note'
-		t = self.do_run( ['--help'], expect, 0, regex=True )
+		t = self.do_run(['--help'], expect, 0, regex=True)
 		if t.pexpect_spawn:
 		if t.pexpect_spawn:
 			time.sleep(0.4)
 			time.sleep(0.4)
 			t.send('q')
 			t.send('q')
@@ -88,74 +88,74 @@ class CmdTestOpts(CmdTestBase):
 
 
 	def opt_noargs(self):
 	def opt_noargs(self):
 		return self.check_vals(
 		return self.check_vals(
-				[],
-				(
-					('cfg.foo',                 'None'),         # added opt
-					('cfg.print_checksum',      'None'),         # sets 'quiet'
-					('cfg.quiet',               'False'),        # _incompatible_opts
-					('cfg.verbose',             'False'),        # _incompatible_opts
-					('cfg.passwd_file',         ''),             # _infile_opts - check_infile()
-					('cfg.outdir',              ''),             # check_outdir()
-					('cfg.cached_balances',     'False'),
-					('cfg.minconf',             '1'),
-					('cfg.coin',                'BTC'),
-					('cfg.pager',               'False'),
-					('cfg.fee_estimate_mode',   'conservative'), # _autoset_opts
-				))
+			[],
+			(
+				('cfg.foo',                 'None'),         # added opt
+				('cfg.print_checksum',      'None'),         # sets 'quiet'
+				('cfg.quiet',               'False'),        # _incompatible_opts
+				('cfg.verbose',             'False'),        # _incompatible_opts
+				('cfg.passwd_file',         ''),             # _infile_opts - check_infile()
+				('cfg.outdir',              ''),             # check_outdir()
+				('cfg.cached_balances',     'False'),
+				('cfg.minconf',             '1'),
+				('cfg.coin',                'BTC'),
+				('cfg.pager',               'False'),
+				('cfg.fee_estimate_mode',   'conservative'), # _autoset_opts
+			))
 
 
 	def opt_good1(self):
 	def opt_good1(self):
 		pf_base = 'testfile'
 		pf_base = 'testfile'
-		pf = os.path.join(self.tmpdir,pf_base)
-		self.write_to_tmpfile(pf_base,'')
+		pf = os.path.join(self.tmpdir, pf_base)
+		self.write_to_tmpfile(pf_base, '')
 		return self.check_vals(
 		return self.check_vals(
-				[
-					'--print-checksum',
-					'--fee-estimate-mode=E',
-					'--passwd-file='+pf,
-					'--outdir='+self.tmpdir,
-					'--cached-balances',
-					f'--hidden-incog-input-params={pf},123',
-				], (
-					('cfg.print_checksum',           'True'),
-					('cfg.quiet',                    'True'), # set by print_checksum
-					('cfg.passwd_file',              pf),
-					('cfg.outdir',                   self.tmpdir),
-					('cfg.cached_balances',          'True'),
-					('cfg.hidden_incog_input_params', pf+',123'),
-					('cfg.fee_estimate_mode',         'economical'),
-				))
+			[
+				'--print-checksum',
+				'--fee-estimate-mode=E',
+				'--passwd-file='+pf,
+				'--outdir='+self.tmpdir,
+				'--cached-balances',
+				f'--hidden-incog-input-params={pf},123',
+			], (
+				('cfg.print_checksum',           'True'),
+				('cfg.quiet',                    'True'), # set by print_checksum
+				('cfg.passwd_file',              pf),
+				('cfg.outdir',                   self.tmpdir),
+				('cfg.cached_balances',          'True'),
+				('cfg.hidden_incog_input_params', pf+',123'),
+				('cfg.fee_estimate_mode',         'economical'),
+			))
 
 
 	def opt_good2(self):
 	def opt_good2(self):
 		return self.check_vals(
 		return self.check_vals(
-				[
-					'--print-checksum',
-					'-qX',
-					f'--outdir={self.tmpdir}',
-					'-p5',
-					'-m', '0',
-					'--seed-len=256',
-					'-L--my-label',
-					'--seed-len', '128',
-					'--min-temp=-30',
-					'-T-10',
-					'--',
-					'x', 'y', '12345'
-				], (
-					('cfg.print_checksum',  'True'),
-					('cfg.quiet',           'True'),
-					('cfg.outdir',          self.tmpdir),
-					('cfg.cached_balances', 'True'),
-					('cfg.minconf',         '0'),
-					('cfg.keep_label',      'None'),
-					('cfg.seed_len',        '128'),
-					('cfg.hash_preset',     '5'),
-					('cfg.label',           '--my-label'),
-					('cfg.min_temp',     '-30'),
-					('cfg.max_temp',     '-10'),
-					('arg1',           'x'),
-					('arg2',           'y'),
-					('arg3',           '12345'),
-				))
+			[
+				'--print-checksum',
+				'-qX',
+				f'--outdir={self.tmpdir}',
+				'-p5',
+				'-m', '0',
+				'--seed-len=256',
+				'-L--my-label',
+				'--seed-len', '128',
+				'--min-temp=-30',
+				'-T-10',
+				'--',
+				'x', 'y', '12345'
+			], (
+				('cfg.print_checksum',  'True'),
+				('cfg.quiet',           'True'),
+				('cfg.outdir',          self.tmpdir),
+				('cfg.cached_balances', 'True'),
+				('cfg.minconf',         '0'),
+				('cfg.keep_label',      'None'),
+				('cfg.seed_len',        '128'),
+				('cfg.hash_preset',     '5'),
+				('cfg.label',           '--my-label'),
+				('cfg.min_temp',        '-30'),
+				('cfg.max_temp',        '-10'),
+				('arg1',                'x'),
+				('arg2',                'y'),
+				('arg3',                '12345'),
+			))
 
 
 	def opt_good3(self):
 	def opt_good3(self):
 		return self.check_vals(['m'] * 256, (('arg256', 'm'),))
 		return self.check_vals(['m'] * 256, (('arg256', 'm'),))
@@ -212,18 +212,18 @@ class CmdTestOpts(CmdTestBase):
 		return self.do_run(['--pager=1'], 'no parameter', 1)
 		return self.do_run(['--pager=1'], 'no parameter', 1)
 
 
 	def opt_bad_infile(self):
 	def opt_bad_infile(self):
-		pf = os.path.join(self.tmpdir,'fubar')
-		return self.do_run(['--passwd-file='+pf],'not found',1)
+		pf = os.path.join(self.tmpdir, 'fubar')
+		return self.do_run(['--passwd-file='+pf], 'not found', 1)
 
 
 	def opt_bad_outdir(self):
 	def opt_bad_outdir(self):
 		bo = self.tmpdir+'_fubar'
 		bo = self.tmpdir+'_fubar'
-		return self.do_run(['--outdir='+bo],'not found',1)
+		return self.do_run(['--outdir='+bo], 'not found', 1)
 
 
 	def opt_bad_incompatible(self):
 	def opt_bad_incompatible(self):
-		return self.do_run(['--label=Label','--keep-label'],'Conflicting options',1)
+		return self.do_run(['--label=Label', '--keep-label'], 'Conflicting options', 1)
 
 
 	def opt_bad_autoset(self):
 	def opt_bad_autoset(self):
-		return self.do_run(['--fee-estimate-mode=Fubar'],'not unique substring',1)
+		return self.do_run(['--fee-estimate-mode=Fubar'], 'not unique substring', 1)
 
 
 	def opt_invalid(self, args, expect, exit_val):
 	def opt_invalid(self, args, expect, exit_val):
 		t = self.spawn_prog(args, exit_val=exit_val)
 		t = self.spawn_prog(args, exit_val=exit_val)

+ 134 - 119
test/cmdtest_py_d/ct_ref.py

@@ -51,11 +51,11 @@ from .ct_shared import CmdTestShared
 
 
 wpasswd = 'reference password'
 wpasswd = 'reference password'
 
 
-class CmdTestRef(CmdTestBase,CmdTestShared):
+class CmdTestRef(CmdTestBase, CmdTestShared):
 	'saved reference address, password and transaction files'
 	'saved reference address, password and transaction files'
 	tmpdir_nums = [8]
 	tmpdir_nums = [8]
-	networks = ('btc','btc_tn','ltc','ltc_tn')
-	passthru_opts = ('daemon_data_dir','rpc_port','coin','testnet')
+	networks = ('btc', 'btc_tn', 'ltc', 'ltc_tn')
+	passthru_opts = ('daemon_data_dir', 'rpc_port', 'coin', 'testnet')
 	need_daemon = True
 	need_daemon = True
 	sources = {
 	sources = {
 		'ref_addrfile':    '98831F3A{}[1,31-33,500-501,1010-1011]{}.addrs',
 		'ref_addrfile':    '98831F3A{}[1,31-33,500-501,1010-1011]{}.addrs',
@@ -77,17 +77,30 @@ class CmdTestRef(CmdTestBase,CmdTestShared):
 		'ref_passwdfile_xmrseed_25': '98831F3A-фубар@crypto.org-xmrseed-25[1,4,1100].pws',
 		'ref_passwdfile_xmrseed_25': '98831F3A-фубар@crypto.org-xmrseed-25[1,4,1100].pws',
 		'ref_passwdfile_hex2bip39_12': '98831F3A-фубар@crypto.org-hex2bip39-12[1,4,1100].pws',
 		'ref_passwdfile_hex2bip39_12': '98831F3A-фубар@crypto.org-hex2bip39-12[1,4,1100].pws',
 		'ref_tx_file': { # data shared with ref_altcoin, autosign
 		'ref_tx_file': { # data shared with ref_altcoin, autosign
-			'btc': ('0B8D5A[15.31789,14,tl=1320969600].rawtx',
-					'0C7115[15.86255,14,tl=1320969600].testnet.rawtx'),
-			'ltc': ('AF3CDF-LTC[620.76194,1453,tl=1320969600].rawtx',
-					'A5A1E0-LTC[1454.64322,1453,tl=1320969600].testnet.rawtx'),
-			'bch': ('460D4D-BCH[10.19764,tl=1320969600].rawtx',
-					'359FD5-BCH[6.68868,tl=1320969600].testnet.rawtx'),
-			'eth': ('88FEFD-ETH[23.45495,40000].rawtx',
-					'B472BD-ETH[23.45495,40000].testnet.rawtx'),
-			'mm1': ('5881D2-MM1[1.23456,50000].rawtx',
-					'6BDB25-MM1[1.23456,50000].testnet.rawtx'),
-			'etc': ('ED3848-ETC[1.2345,40000].rawtx','')
+			'btc': (
+				'0B8D5A[15.31789,14,tl=1320969600].rawtx',
+				'0C7115[15.86255,14,tl=1320969600].testnet.rawtx'
+			),
+			'ltc': (
+				'AF3CDF-LTC[620.76194,1453,tl=1320969600].rawtx',
+				'A5A1E0-LTC[1454.64322,1453,tl=1320969600].testnet.rawtx'
+			),
+			'bch': (
+				'460D4D-BCH[10.19764,tl=1320969600].rawtx',
+				'359FD5-BCH[6.68868,tl=1320969600].testnet.rawtx'
+			),
+			'eth': (
+				'88FEFD-ETH[23.45495,40000].rawtx',
+				'B472BD-ETH[23.45495,40000].testnet.rawtx'
+			),
+			'mm1': (
+				'5881D2-MM1[1.23456,50000].rawtx',
+				'6BDB25-MM1[1.23456,50000].testnet.rawtx'
+			),
+			'etc': (
+				'ED3848-ETC[1.2345,40000].rawtx',
+				''
+			)
 		},
 		},
 	}
 	}
 	chk_data = {
 	chk_data = {
@@ -96,82 +109,84 @@ class CmdTestRef(CmdTestBase,CmdTestShared):
 			'98831F3A:1S':'20D95B09',
 			'98831F3A:1S':'20D95B09',
 		},
 		},
 		'ref_addrfile_chksum': {
 		'ref_addrfile_chksum': {
-			'btc': ('6FEF 6FB9 7B13 5D91','424E 4326 CFFE 5F51'),
-			'ltc': ('AD52 C3FE 8924 AAF0','4EBE 2E85 E969 1B30'),
+			'btc': ('6FEF 6FB9 7B13 5D91', '424E 4326 CFFE 5F51'),
+			'ltc': ('AD52 C3FE 8924 AAF0', '4EBE 2E85 E969 1B30'),
 		},
 		},
 		'ref_segwitaddrfile_chksum': {
 		'ref_segwitaddrfile_chksum': {
-			'btc': ('06C1 9C87 F25C 4EE6','072C 8B07 2730 CB7A'),
-			'ltc': ('63DF E42A 0827 21C3','5DD1 D186 DBE1 59F2'),
+			'btc': ('06C1 9C87 F25C 4EE6', '072C 8B07 2730 CB7A'),
+			'ltc': ('63DF E42A 0827 21C3', '5DD1 D186 DBE1 59F2'),
 		},
 		},
 		'ref_bech32addrfile_chksum': {
 		'ref_bech32addrfile_chksum': {
-			'btc': ('9D2A D4B6 5117 F02E','0527 9C39 6C1B E39A'),
-			'ltc': ('FF1C 7939 5967 AB82','ED3D 8AA4 BED4 0B40'),
+			'btc': ('9D2A D4B6 5117 F02E', '0527 9C39 6C1B E39A'),
+			'ltc': ('FF1C 7939 5967 AB82', 'ED3D 8AA4 BED4 0B40'),
 		},
 		},
 		'ref_keyaddrfile_chksum': {
 		'ref_keyaddrfile_chksum': {
-			'btc': ('9F2D D781 1812 8BAD','88CC 5120 9A91 22C2'),
-			'ltc': ('B804 978A 8796 3ED4','98B5 AC35 F334 0398'),
+			'btc': ('9F2D D781 1812 8BAD', '88CC 5120 9A91 22C2'),
+			'ltc': ('B804 978A 8796 3ED4', '98B5 AC35 F334 0398'),
 		},
 		},
-		'ref_passwdfile_b32_12_chksum': '7252 CD8D EF0D 3DB1',
-		'ref_passwdfile_b32_24_chksum': '8D56 3845 A072 A5B9',
-		'ref_passwdfile_b58_10_chksum': '534F CC1A 6701 9FED',
-		'ref_passwdfile_b58_20_chksum': 'DDD9 44B0 CA28 183F',
-		'ref_passwdfile_hex_32_chksum': '05C7 3678 E25E BC32',
-		'ref_passwdfile_hex_48_chksum': '7DBB FFD0 633E DE6F',
-		'ref_passwdfile_hex_64_chksum': 'F11D CB0A 8AE3 4D21',
-		'ref_passwdfile_bip39_12_chksum': 'BF57 02A3 5229 CF18',
-		'ref_passwdfile_bip39_18_chksum': '31D3 1656 B7DC 27CF',
-		'ref_passwdfile_bip39_24_chksum': 'E565 3A59 7D91 4671',
-		'ref_passwdfile_xmrseed_25_chksum': 'B488 21D3 4539 968D',
+		'ref_passwdfile_b32_12_chksum':       '7252 CD8D EF0D 3DB1',
+		'ref_passwdfile_b32_24_chksum':       '8D56 3845 A072 A5B9',
+		'ref_passwdfile_b58_10_chksum':       '534F CC1A 6701 9FED',
+		'ref_passwdfile_b58_20_chksum':       'DDD9 44B0 CA28 183F',
+		'ref_passwdfile_hex_32_chksum':       '05C7 3678 E25E BC32',
+		'ref_passwdfile_hex_48_chksum':       '7DBB FFD0 633E DE6F',
+		'ref_passwdfile_hex_64_chksum':       'F11D CB0A 8AE3 4D21',
+		'ref_passwdfile_bip39_12_chksum':     'BF57 02A3 5229 CF18',
+		'ref_passwdfile_bip39_18_chksum':     '31D3 1656 B7DC 27CF',
+		'ref_passwdfile_bip39_24_chksum':     'E565 3A59 7D91 4671',
+		'ref_passwdfile_xmrseed_25_chksum':   'B488 21D3 4539 968D',
 		'ref_passwdfile_hex2bip39_12_chksum': '93AD 4AE2 03D1 8A0A',
 		'ref_passwdfile_hex2bip39_12_chksum': '93AD 4AE2 03D1 8A0A',
 	}
 	}
 	cmd_group = ( # TODO: move to tooltest2
 	cmd_group = ( # TODO: move to tooltest2
-		('ref_words_to_subwallet_chk1','subwallet generation from reference words file (long subseed)'),
-		('ref_words_to_subwallet_chk2','subwallet generation from reference words file (short subseed)'),
-		('ref_subwallet_addrgen1','subwallet address file generation (long subseed)'),
-		('ref_subwallet_addrgen2','subwallet address file generation (short subseed)'),
-		('ref_subwallet_keygen1','subwallet key-address file generation (long subseed)'),
-		('ref_subwallet_keygen2','subwallet key-address file generation (short subseed)'),
-		('ref_addrfile_chk',   'saved reference address file'),
-		('ref_segwitaddrfile_chk','saved reference address file (segwit)'),
-		('ref_bech32addrfile_chk','saved reference address file (bech32)'),
-		('ref_keyaddrfile_chk','saved reference key-address file'),
-
-		('ref_passwdfile_chk_b58_20','saved reference password file (base58, 20 chars)'),
-		('ref_passwdfile_chk_b58_10','saved reference password file (base58, 10 chars)'),
-		('ref_passwdfile_chk_b32_24','saved reference password file (base32, 24 chars)'),
-		('ref_passwdfile_chk_b32_12','saved reference password file (base32, 12 chars)'),
-		('ref_passwdfile_chk_hex_32','saved reference password file (hexadecimal, 32 chars)'),
-		('ref_passwdfile_chk_hex_48','saved reference password file (hexadecimal, 48 chars)'),
-		('ref_passwdfile_chk_hex_64','saved reference password file (hexadecimal, 64 chars)'),
-		('ref_passwdfile_chk_bip39_12','saved reference password file (BIP39, 12 words)'),
-		('ref_passwdfile_chk_bip39_18','saved reference password file (BIP39, 18 words)'),
-		('ref_passwdfile_chk_bip39_24','saved reference password file (BIP39, 24 words)'),
-		('ref_passwdfile_chk_xmrseed_25','saved reference password file (Monero new-style mnemonic, 25 words)'),
-		('ref_passwdfile_chk_hex2bip39_12','saved reference password file (hex-to-BIP39, 12 words)'),
+		('ref_words_to_subwallet_chk1',     'subwallet generation from reference words file (long subseed)'),
+		('ref_words_to_subwallet_chk2',     'subwallet generation from reference words file (short subseed)'),
+		('ref_subwallet_addrgen1',          'subwallet address file generation (long subseed)'),
+		('ref_subwallet_addrgen2',          'subwallet address file generation (short subseed)'),
+		('ref_subwallet_keygen1',           'subwallet key-address file generation (long subseed)'),
+		('ref_subwallet_keygen2',           'subwallet key-address file generation (short subseed)'),
+		('ref_addrfile_chk',                'saved reference address file'),
+		('ref_segwitaddrfile_chk',          'saved reference address file (segwit)'),
+		('ref_bech32addrfile_chk',          'saved reference address file (bech32)'),
+		('ref_keyaddrfile_chk',             'saved reference key-address file'),
+
+		('ref_passwdfile_chk_b58_20',       'saved reference password file (base58, 20 chars)'),
+		('ref_passwdfile_chk_b58_10',       'saved reference password file (base58, 10 chars)'),
+		('ref_passwdfile_chk_b32_24',       'saved reference password file (base32, 24 chars)'),
+		('ref_passwdfile_chk_b32_12',       'saved reference password file (base32, 12 chars)'),
+		('ref_passwdfile_chk_hex_32',       'saved reference password file (hexadecimal, 32 chars)'),
+		('ref_passwdfile_chk_hex_48',       'saved reference password file (hexadecimal, 48 chars)'),
+		('ref_passwdfile_chk_hex_64',       'saved reference password file (hexadecimal, 64 chars)'),
+		('ref_passwdfile_chk_bip39_12',     'saved reference password file (BIP39, 12 words)'),
+		('ref_passwdfile_chk_bip39_18',     'saved reference password file (BIP39, 18 words)'),
+		('ref_passwdfile_chk_bip39_24',     'saved reference password file (BIP39, 24 words)'),
+		('ref_passwdfile_chk_xmrseed_25',   'saved reference password file (Monero new-style mnemonic, 25 words)'),
+		('ref_passwdfile_chk_hex2bip39_12', 'saved reference password file (hex-to-BIP39, 12 words)'),
 
 
 #	Create the fake inputs:
 #	Create the fake inputs:
 #	('txcreate8',          'transaction creation (8)'),
 #	('txcreate8',          'transaction creation (8)'),
-		('ref_tx_chk',         'signing saved reference tx file'),
-		('ref_brain_chk_spc3', 'saved brainwallet (non-standard spacing)'),
-		('ref_dieroll_chk_seedtruncate','saved dieroll wallet with extra entropy bits'),
-		('ref_tool_decrypt',   'decryption of saved MMGen-encrypted file'),
+		('ref_tx_chk',                   'signing saved reference tx file'),
+		('ref_brain_chk_spc3',           'saved brainwallet (non-standard spacing)'),
+		('ref_dieroll_chk_seedtruncate', 'saved dieroll wallet with extra entropy bits'),
+		('ref_tool_decrypt',             'decryption of saved MMGen-encrypted file'),
 	)
 	)
 
 
 	@property
 	@property
 	def nw_desc(self):
 	def nw_desc(self):
 		return '{} {}'.format(
 		return '{} {}'.format(
 			self.proto.coin,
 			self.proto.coin,
-			('Mainnet','Testnet')[self.proto.testnet] )
+			('Mainnet','Testnet')[self.proto.testnet])
 
 
 	def _get_ref_subdir_by_coin(self,coin):
 	def _get_ref_subdir_by_coin(self,coin):
-		return {'btc': '',
-				'bch': '',
-				'ltc': 'litecoin',
-				'eth': 'ethereum',
-				'etc': 'ethereum_classic',
-				'xmr': 'monero',
-				'zec': 'zcash',
-				'dash': 'dash' }[coin.lower()]
+		return {
+			'btc':  '',
+			'bch':  '',
+			'ltc':  'litecoin',
+			'eth':  'ethereum',
+			'etc':  'ethereum_classic',
+			'xmr':  'monero',
+			'zec':  'zcash',
+			'dash': 'dash'
+		}[coin.lower()]
 
 
 	@property
 	@property
 	def ref_subdir(self):
 	def ref_subdir(self):
@@ -183,10 +198,10 @@ class CmdTestRef(CmdTestBase,CmdTestShared):
 	def ref_words_to_subwallet_chk2(self):
 	def ref_words_to_subwallet_chk2(self):
 		return self.ref_words_to_subwallet_chk('1S')
 		return self.ref_words_to_subwallet_chk('1S')
 
 
-	def ref_words_to_subwallet_chk(self,ss_idx):
+	def ref_words_to_subwallet_chk(self, ss_idx):
 		wf = dfl_words_file
 		wf = dfl_words_file
 		ocls = get_wallet_cls('words')
 		ocls = get_wallet_cls('words')
-		args = ['-d',self.tr.trash_dir,'-o',ocls.fmt_codes[-1],wf,ss_idx]
+		args = ['-d', self.tr.trash_dir, '-o', ocls.fmt_codes[-1], wf, ss_idx]
 
 
 		t = self.spawn(
 		t = self.spawn(
 			'mmgen-subwalletgen',
 			'mmgen-subwalletgen',
@@ -196,7 +211,7 @@ class CmdTestRef(CmdTestBase,CmdTestShared):
 		t.expect(f'Generating subseed {ss_idx}')
 		t.expect(f'Generating subseed {ss_idx}')
 		chk_sid = self.chk_data['ref_subwallet_sid'][f'98831F3A:{ss_idx}']
 		chk_sid = self.chk_data['ref_subwallet_sid'][f'98831F3A:{ss_idx}']
 		fn = t.written_to_file(capfirst(ocls.desc))
 		fn = t.written_to_file(capfirst(ocls.desc))
-		assert chk_sid in fn,f'incorrect filename: {fn} (does not contain {chk_sid})'
+		assert chk_sid in fn, f'incorrect filename: {fn} (does not contain {chk_sid})'
 		ok()
 		ok()
 
 
 		t = self.spawn(
 		t = self.spawn(
@@ -204,22 +219,22 @@ class CmdTestRef(CmdTestBase,CmdTestShared):
 			self.testnet_opt + [fn],
 			self.testnet_opt + [fn],
 			extra_desc       = '(check subwallet)',
 			extra_desc       = '(check subwallet)',
 			no_passthru_opts = True)
 			no_passthru_opts = True)
-		t.expect(r'Valid MMGen native mnemonic data for Seed ID ([0-9A-F]*)\b',regex=True)
+		t.expect(r'Valid MMGen native mnemonic data for Seed ID ([0-9A-F]*)\b', regex=True)
 		sid = t.p.match.group(1)
 		sid = t.p.match.group(1)
-		assert sid == chk_sid,f'subseed ID {sid} does not match expected value {chk_sid}'
+		assert sid == chk_sid, f'subseed ID {sid} does not match expected value {chk_sid}'
 		return t
 		return t
 
 
-	def ref_subwallet_addrgen(self,ss_idx,target='addr'):
+	def ref_subwallet_addrgen(self, ss_idx, target='addr'):
 		wf = dfl_words_file
 		wf = dfl_words_file
-		args = ['-d',self.tr.trash_dir,'--subwallet='+ss_idx,wf,'1-10']
-		t = self.spawn(f'mmgen-{target}gen',args)
+		args = ['-d', self.tr.trash_dir, '--subwallet='+ss_idx, wf, '1-10']
+		t = self.spawn(f'mmgen-{target}gen', args)
 		t.expect(f'Generating subseed {ss_idx}')
 		t.expect(f'Generating subseed {ss_idx}')
 		chk_sid = self.chk_data['ref_subwallet_sid'][f'98831F3A:{ss_idx}']
 		chk_sid = self.chk_data['ref_subwallet_sid'][f'98831F3A:{ss_idx}']
-		assert chk_sid == t.expect_getend('Checksum for .* data ',regex=True)[:8]
+		assert chk_sid == t.expect_getend('Checksum for .* data ', regex=True)[:8]
 		if target == 'key':
 		if target == 'key':
-			t.expect('Encrypt key list? (y/N): ','n')
-		fn = t.written_to_file(('Addresses','Secret keys')[target=='key'])
-		assert chk_sid in fn,f'incorrect filename: {fn} (does not contain {chk_sid})'
+			t.expect('Encrypt key list? (y/N): ', 'n')
+		fn = t.written_to_file(('Addresses', 'Secret keys')[target=='key'])
+		assert chk_sid in fn, f'incorrect filename: {fn} (does not contain {chk_sid})'
 		return t
 		return t
 
 
 	def ref_subwallet_addrgen1(self):
 	def ref_subwallet_addrgen1(self):
@@ -229,10 +244,10 @@ class CmdTestRef(CmdTestBase,CmdTestShared):
 		return self.ref_subwallet_addrgen('1S')
 		return self.ref_subwallet_addrgen('1S')
 
 
 	def ref_subwallet_keygen1(self):
 	def ref_subwallet_keygen1(self):
-		return self.ref_subwallet_addrgen('32L',target='key')
+		return self.ref_subwallet_addrgen('32L', target='key')
 
 
 	def ref_subwallet_keygen2(self):
 	def ref_subwallet_keygen2(self):
-		return self.ref_subwallet_addrgen('1S',target='key')
+		return self.ref_subwallet_addrgen('1S', target='key')
 
 
 	def ref_addrfile_chk(
 	def ref_addrfile_chk(
 			self,
 			self,
@@ -246,90 +261,90 @@ class CmdTestRef(CmdTestBase,CmdTestShared):
 
 
 		pat = pat or f'{self.nw_desc}.*Legacy'
 		pat = pat or f'{self.nw_desc}.*Legacy'
 		af_key = f'ref_{ftype}file' + ('_' + id_key if id_key else '')
 		af_key = f'ref_{ftype}file' + ('_' + id_key if id_key else '')
-		af_fn = CmdTestRef.sources[af_key].format(pfx or self.altcoin_pfx,'' if coin else self.tn_ext)
-		af = joinpath(ref_dir,(subdir or self.ref_subdir,'')[ftype=='passwd'],af_fn)
+		af_fn = CmdTestRef.sources[af_key].format(pfx or self.altcoin_pfx, '' if coin else self.tn_ext)
+		af = joinpath(ref_dir, (subdir or self.ref_subdir, '')[ftype=='passwd'], af_fn)
 		coin_arg = [] if coin is None else ['--coin='+coin]
 		coin_arg = [] if coin is None else ['--coin='+coin]
-		tool_cmd = ftype.replace('segwit','').replace('bech32','')+'file_chksum'
-		t = self.spawn( 'mmgen-tool', coin_arg + ['--verbose','-p1',tool_cmd,af] )
+		tool_cmd = ftype.replace('segwit', '').replace('bech32', '')+'file_chksum'
+		t = self.spawn('mmgen-tool', coin_arg + ['--verbose', '-p1', tool_cmd, af])
 		if ftype == 'keyaddr':
 		if ftype == 'keyaddr':
-			t.do_decrypt_ka_data(pw=ref_kafile_pass,have_yes_opt=True)
-		chksum_key = '_'.join([af_key,'chksum'] + ([coin.lower()] if coin else []) + ([mmtype] if mmtype else []))
+			t.do_decrypt_ka_data(pw=ref_kafile_pass, have_yes_opt=True)
+		chksum_key = '_'.join([af_key, 'chksum'] + ([coin.lower()] if coin else []) + ([mmtype] if mmtype else []))
 		rc = self.chk_data[chksum_key]
 		rc = self.chk_data[chksum_key]
 		ref_chksum = rc if (ftype == 'passwd' or coin) else rc[self.proto.base_coin.lower()][self.proto.testnet]
 		ref_chksum = rc if (ftype == 'passwd' or coin) else rc[self.proto.base_coin.lower()][self.proto.testnet]
 		if pat:
 		if pat:
-			t.expect(pat,regex=True)
-		t.expect(chksum_pat,regex=True)
+			t.expect(pat, regex=True)
+		t.expect(chksum_pat, regex=True)
 		m = t.p.match.group(0)
 		m = t.p.match.group(0)
-		cmp_or_die(ref_chksum,m)
+		cmp_or_die(ref_chksum, m)
 		return t
 		return t
 
 
 	def ref_segwitaddrfile_chk(self):
 	def ref_segwitaddrfile_chk(self):
 		if not 'S' in self.proto.mmtypes:
 		if not 'S' in self.proto.mmtypes:
 			return skip(f'not supported by {self.proto.cls_name} protocol')
 			return skip(f'not supported by {self.proto.cls_name} protocol')
-		return self.ref_addrfile_chk(ftype='segwitaddr',pat=f'{self.nw_desc}.*Segwit')
+		return self.ref_addrfile_chk(ftype='segwitaddr', pat=f'{self.nw_desc}.*Segwit')
 
 
 	def ref_bech32addrfile_chk(self):
 	def ref_bech32addrfile_chk(self):
 		if not 'B' in self.proto.mmtypes:
 		if not 'B' in self.proto.mmtypes:
 			return skip(f'not supported by {self.proto.cls_name} protocol')
 			return skip(f'not supported by {self.proto.cls_name} protocol')
-		return self.ref_addrfile_chk(ftype='bech32addr',pat=f'{self.nw_desc}.*Bech32')
+		return self.ref_addrfile_chk(ftype='bech32addr', pat=f'{self.nw_desc}.*Bech32')
 
 
 	def ref_keyaddrfile_chk(self):
 	def ref_keyaddrfile_chk(self):
 		return self.ref_addrfile_chk(ftype='keyaddr')
 		return self.ref_addrfile_chk(ftype='keyaddr')
 
 
-	def ref_passwdfile_chk(self,key,pat):
-		return self.ref_addrfile_chk(ftype='passwd',id_key=key,pat=pat)
+	def ref_passwdfile_chk(self, key, pat):
+		return self.ref_addrfile_chk(ftype='passwd', id_key=key, pat=pat)
 
 
 	def ref_passwdfile_chk_b58_20(self):
 	def ref_passwdfile_chk_b58_20(self):
-		return self.ref_passwdfile_chk(key='b58_20',pat=r'Base58.*len.* 20\b')
+		return self.ref_passwdfile_chk(key='b58_20', pat=r'Base58.*len.* 20\b')
 	def ref_passwdfile_chk_b58_10(self):
 	def ref_passwdfile_chk_b58_10(self):
-		return self.ref_passwdfile_chk(key='b58_10',pat=r'Base58.*len.* 10\b')
+		return self.ref_passwdfile_chk(key='b58_10', pat=r'Base58.*len.* 10\b')
 	def ref_passwdfile_chk_b32_24(self):
 	def ref_passwdfile_chk_b32_24(self):
-		return self.ref_passwdfile_chk(key='b32_24',pat=r'Base32.*len.* 24\b')
+		return self.ref_passwdfile_chk(key='b32_24', pat=r'Base32.*len.* 24\b')
 	def ref_passwdfile_chk_b32_12(self):
 	def ref_passwdfile_chk_b32_12(self):
-		return self.ref_passwdfile_chk(key='b32_12',pat=r'Base32.*len.* 12\b')
+		return self.ref_passwdfile_chk(key='b32_12', pat=r'Base32.*len.* 12\b')
 	def ref_passwdfile_chk_hex_32(self):
 	def ref_passwdfile_chk_hex_32(self):
-		return self.ref_passwdfile_chk(key='hex_32',pat=r'Hexadec.*len.* 32\b')
+		return self.ref_passwdfile_chk(key='hex_32', pat=r'Hexadec.*len.* 32\b')
 	def ref_passwdfile_chk_hex_48(self):
 	def ref_passwdfile_chk_hex_48(self):
-		return self.ref_passwdfile_chk(key='hex_48',pat=r'Hexadec.*len.* 48\b')
+		return self.ref_passwdfile_chk(key='hex_48', pat=r'Hexadec.*len.* 48\b')
 	def ref_passwdfile_chk_hex_64(self):
 	def ref_passwdfile_chk_hex_64(self):
-		return self.ref_passwdfile_chk(key='hex_64',pat=r'Hexadec.*len.* 64\b')
+		return self.ref_passwdfile_chk(key='hex_64', pat=r'Hexadec.*len.* 64\b')
 	def ref_passwdfile_chk_bip39_12(self):
 	def ref_passwdfile_chk_bip39_12(self):
-		return self.ref_passwdfile_chk(key='bip39_12',pat=r'BIP39.*len.* 12\b')
+		return self.ref_passwdfile_chk(key='bip39_12', pat=r'BIP39.*len.* 12\b')
 	def ref_passwdfile_chk_bip39_18(self):
 	def ref_passwdfile_chk_bip39_18(self):
-		return self.ref_passwdfile_chk(key='bip39_18',pat=r'BIP39.*len.* 18\b')
+		return self.ref_passwdfile_chk(key='bip39_18', pat=r'BIP39.*len.* 18\b')
 	def ref_passwdfile_chk_bip39_24(self):
 	def ref_passwdfile_chk_bip39_24(self):
-		return self.ref_passwdfile_chk(key='bip39_24',pat=r'BIP39.*len.* 24\b')
+		return self.ref_passwdfile_chk(key='bip39_24', pat=r'BIP39.*len.* 24\b')
 	def ref_passwdfile_chk_xmrseed_25(self):
 	def ref_passwdfile_chk_xmrseed_25(self):
-		return self.ref_passwdfile_chk(key='xmrseed_25',pat=r'Mon.*len.* 25\b')
+		return self.ref_passwdfile_chk(key='xmrseed_25', pat=r'Mon.*len.* 25\b')
 	def ref_passwdfile_chk_hex2bip39_12(self):
 	def ref_passwdfile_chk_hex2bip39_12(self):
-		return self.ref_passwdfile_chk(key='hex2bip39_12',pat=r'BIP39.*len.* 12\b')
+		return self.ref_passwdfile_chk(key='hex2bip39_12', pat=r'BIP39.*len.* 12\b')
 
 
 	def ref_tx_chk(self):
 	def ref_tx_chk(self):
 		fn = self.sources['ref_tx_file'][self.coin][bool(self.tn_ext)]
 		fn = self.sources['ref_tx_file'][self.coin][bool(self.tn_ext)]
 		if not fn:
 		if not fn:
 			return
 			return
-		tf = joinpath(ref_dir,self.ref_subdir,fn)
+		tf = joinpath(ref_dir, self.ref_subdir, fn)
 		wf = dfl_words_file
 		wf = dfl_words_file
-		self.write_to_tmpfile(pwfile,wpasswd)
-		return self.txsign(wf,tf,save=False,has_label=True,view='y')
+		self.write_to_tmpfile(pwfile, wpasswd)
+		return self.txsign(wf, tf, save=False, has_label=True, view='y')
 
 
 	def ref_brain_chk_spc3(self):
 	def ref_brain_chk_spc3(self):
 		return self.ref_brain_chk(bw_file=ref_bw_file_spc)
 		return self.ref_brain_chk(bw_file=ref_bw_file_spc)
 
 
 	def ref_dieroll_chk_seedtruncate(self):
 	def ref_dieroll_chk_seedtruncate(self):
-		wf = joinpath(ref_dir,'overflow128.b6d')
-		return self.walletchk(wf,sid='8EC6D4A2')
+		wf = joinpath(ref_dir, 'overflow128.b6d')
+		return self.walletchk(wf, sid='8EC6D4A2')
 
 
 	def ref_tool_decrypt(self):
 	def ref_tool_decrypt(self):
-		f = joinpath(ref_dir,ref_enc_fn)
-		dec_file = joinpath(self.tmpdir,'famous.txt')
+		f = joinpath(ref_dir, ref_enc_fn)
+		dec_file = joinpath(self.tmpdir, 'famous.txt')
 		t = self.spawn(
 		t = self.spawn(
 			'mmgen-tool',
 			'mmgen-tool',
-			['-q','decrypt',f,'outfile='+dec_file,'hash_preset=1'],
-			env = os.environ if cfg.debug_utf8 else get_env_without_debug_vars() )
-		t.passphrase('data',tool_enc_passwd)
+			['-q', 'decrypt', f, 'outfile='+dec_file, 'hash_preset=1'],
+			env = os.environ if cfg.debug_utf8 else get_env_without_debug_vars())
+		t.passphrase('data', tool_enc_passwd)
 		t.written_to_file('Decrypted data')
 		t.written_to_file('Decrypted data')
 		dec_txt = read_from_file(dec_file)
 		dec_txt = read_from_file(dec_file)
 		imsg_r(dec_txt)
 		imsg_r(dec_txt)
-		cmp_or_die(sample_text+'\n',dec_txt) # file adds a newline to sample_text
+		cmp_or_die(sample_text+'\n', dec_txt) # file adds a newline to sample_text
 		return t
 		return t

+ 119 - 119
test/cmdtest_py_d/ct_ref_3seed.py

@@ -23,10 +23,10 @@ test.cmdtest_py_d.ct_ref_3seed: Saved and generated reference file tests for 128
 
 
 import os
 import os
 
 
-from mmgen.util import msg,capfirst
+from mmgen.util import msg, capfirst
 from mmgen.wallet import get_wallet_cls
 from mmgen.wallet import get_wallet_cls
 
 
-from ..include.common import cfg,cmp_or_die,joinpath
+from ..include.common import cfg, cmp_or_die, joinpath
 from .common import (
 from .common import (
 	pwfile,
 	pwfile,
 	ref_wallet_hash_preset,
 	ref_wallet_hash_preset,
@@ -39,66 +39,66 @@ from .ct_base import CmdTestBase
 from .ct_shared import CmdTestShared
 from .ct_shared import CmdTestShared
 from .ct_wallet import CmdTestWalletConv
 from .ct_wallet import CmdTestWalletConv
 
 
-class CmdTestRef3Seed(CmdTestBase,CmdTestShared):
+class CmdTestRef3Seed(CmdTestBase, CmdTestShared):
 	'saved wallet files for 128-, 192- and 256-bit seeds + generated filename checks'
 	'saved wallet files for 128-, 192- and 256-bit seeds + generated filename checks'
 	networks = ('btc',)
 	networks = ('btc',)
 	mmtypes = (None,)
 	mmtypes = (None,)
-	tmpdir_nums = [6,7,8]
+	tmpdir_nums = [6, 7, 8]
 	addr_idx_list_in = '1010,500-501,31-33,1,33,500,1011'
 	addr_idx_list_in = '1010,500-501,31-33,1,33,500,1011'
 	pass_idx_list_in = '1,4,9-11,1100'
 	pass_idx_list_in = '1,4,9-11,1100'
 	chk_data = {
 	chk_data = {
 		'lens': (128, 192, 256),
 		'lens': (128, 192, 256),
 		'sids': ('FE3C6545', '1378FC64', '98831F3A'),
 		'sids': ('FE3C6545', '1378FC64', '98831F3A'),
 	}
 	}
-	shared_deps = ['mmdat',pwfile]
+	shared_deps = ['mmdat', pwfile]
 	skip_cmds = (
 	skip_cmds = (
 		'ref_xmrseed_25_passwdgen_1',
 		'ref_xmrseed_25_passwdgen_1',
 		'ref_xmrseed_25_passwdgen_2',
 		'ref_xmrseed_25_passwdgen_2',
 	)
 	)
 	cmd_group = (
 	cmd_group = (
 		# reading saved reference wallets
 		# reading saved reference wallets
-		('ref_wallet_chk',  ([],'saved reference wallet')),
-		('ref_seed_chk',    ([],'saved seed file')),
-		('ref_hex_chk',     ([],'saved mmhex file')),
-		('ref_plainhex_chk',([],'saved hex file')),
-		('ref_dieroll_chk', ([],'saved dieroll (b6d) file')),
-		('ref_mn_chk',      ([],'saved native MMGen mnemonic file')),
-		('ref_bip39_chk',   ([],'saved BIP39 mnemonic file')),
-		('ref_hincog_chk',  ([],'saved hidden incog reference wallet')),
-		('ref_brain_chk',   ([],'saved brainwallet')), # in ct_shared
+		('ref_wallet_chk',   ([], 'saved reference wallet')),
+		('ref_seed_chk',     ([], 'saved seed file')),
+		('ref_hex_chk',      ([], 'saved mmhex file')),
+		('ref_plainhex_chk', ([], 'saved hex file')),
+		('ref_dieroll_chk',  ([], 'saved dieroll (b6d) file')),
+		('ref_mn_chk',       ([], 'saved native MMGen mnemonic file')),
+		('ref_bip39_chk',    ([], 'saved BIP39 mnemonic file')),
+		('ref_hincog_chk',   ([], 'saved hidden incog reference wallet')),
+		('ref_brain_chk',    ([], 'saved brainwallet')),                    # in ct_shared
 
 
 		# generating new reference ('abc' brainwallet) wallets for filename checks:
 		# generating new reference ('abc' brainwallet) wallets for filename checks:
-		('ref_walletgen_brain',        ([],'generating new reference wallet + filename check (brain)')),
-		('ref_walletconv_words',       ([],'wallet filename (native mnemonic)')),
-		('ref_walletconv_bip39',       ([],'wallet filename (bip39)')),
-		('ref_walletconv_seed',        ([],'wallet filename (seed)')),
-		('ref_walletconv_hexseed',     ([],'wallet filename (hex seed)')),
-		('ref_walletconv_plainhexseed',([],'wallet filename (plain hex seed)')),
-		('ref_walletconv_dieroll',     ([],'wallet filename (dieroll (b6d) seed)')),
-		('ref_walletconv_incog',       ([],'wallet filename (incog)')),
-		('ref_walletconv_hexincog',    ([],'wallet filename (hex incog)')),
+		('ref_walletgen_brain',         ([], 'generating new reference wallet + filename check (brain)')),
+		('ref_walletconv_words',        ([], 'wallet filename (native mnemonic)')),
+		('ref_walletconv_bip39',        ([], 'wallet filename (bip39)')),
+		('ref_walletconv_seed',         ([], 'wallet filename (seed)')),
+		('ref_walletconv_hexseed',      ([], 'wallet filename (hex seed)')),
+		('ref_walletconv_plainhexseed', ([], 'wallet filename (plain hex seed)')),
+		('ref_walletconv_dieroll',      ([], 'wallet filename (dieroll (b6d) seed)')),
+		('ref_walletconv_incog',        ([], 'wallet filename (incog)')),
+		('ref_walletconv_hexincog',     ([], 'wallet filename (hex incog)')),
 	)
 	)
 
 
-	def __init__(self,trunner,cfgs,spawn):
-		for k,_ in self.cmd_group:
-			for n in (1,2,3): # 128,192,256 bits
-				setattr(self,f'{k}_{n}',getattr(self,k))
+	def __init__(self, trunner, cfgs, spawn):
+		for k, _ in self.cmd_group:
+			for n in (1, 2, 3): # 128, 192, 256 bits
+				setattr(self, f'{k}_{n}', getattr(self, k))
 		if cfgs:
 		if cfgs:
 			for n in self.tmpdir_nums:
 			for n in self.tmpdir_nums:
 				cfgs[str(n)]['addr_idx_list'] = self.addr_idx_list_in
 				cfgs[str(n)]['addr_idx_list'] = self.addr_idx_list_in
 				cfgs[str(n)]['pass_idx_list'] = self.pass_idx_list_in
 				cfgs[str(n)]['pass_idx_list'] = self.pass_idx_list_in
-		CmdTestBase.__init__(self,trunner,cfgs,spawn)
+		CmdTestBase.__init__(self, trunner, cfgs, spawn)
 
 
 	def ref_wallet_chk(self):
 	def ref_wallet_chk(self):
-		wf = joinpath(ref_dir,CmdTestWalletConv.sources[str(self.seed_len)]['ref_wallet'])
-		return self.walletchk(wf,sid=self.seed_id)
+		wf = joinpath(ref_dir, CmdTestWalletConv.sources[str(self.seed_len)]['ref_wallet'])
+		return self.walletchk(wf, sid=self.seed_id)
 
 
-	def ref_ss_chk(self,ss_type):
+	def ref_ss_chk(self, ss_type):
 		ss = get_wallet_cls(ss_type)
 		ss = get_wallet_cls(ss_type)
 		return self.walletchk(
 		return self.walletchk(
-			wf   = joinpath(ref_dir,f'{self.seed_id}.{ss.ext}'),
+			wf   = joinpath(ref_dir, f'{self.seed_id}.{ss.ext}'),
 			wcls = ss,
 			wcls = ss,
-			sid  = self.seed_id )
+			sid  = self.seed_id)
 
 
 	def ref_seed_chk(self):
 	def ref_seed_chk(self):
 		return self.ref_ss_chk('seed')
 		return self.ref_ss_chk('seed')
@@ -118,14 +118,14 @@ class CmdTestRef3Seed(CmdTestBase,CmdTestShared):
 	def ref_bip39_chk(self):
 	def ref_bip39_chk(self):
 		return self.ref_ss_chk('bip39')
 		return self.ref_ss_chk('bip39')
 
 
-	def ref_hincog_chk(self,desc='hidden incognito data'):
+	def ref_hincog_chk(self, desc='hidden incognito data'):
 		source = CmdTestWalletConv.sources[str(self.seed_len)]
 		source = CmdTestWalletConv.sources[str(self.seed_len)]
-		for wtype,edesc,of_arg in (
-				('hic_wallet',    '',            []),
-				('hic_wallet_old','(old format)',['-O']) ):
+		for wtype, edesc, of_arg in (
+				('hic_wallet',     '',             []),
+				('hic_wallet_old', '(old format)', ['-O'])):
 			ic_arg = ['-H{},{}'.format(
 			ic_arg = ['-H{},{}'.format(
-				joinpath(ref_dir,source[wtype]),
-				ref_wallet_incog_offset )
+				joinpath(ref_dir, source[wtype]),
+				ref_wallet_incog_offset)
 			]
 			]
 			slarg = [f'-l{self.seed_len} ']
 			slarg = [f'-l{self.seed_len} ']
 			hparg = ['-p1']
 			hparg = ['-p1']
@@ -134,11 +134,11 @@ class CmdTestRef3Seed(CmdTestBase,CmdTestShared):
 			t = self.spawn('mmgen-walletchk',
 			t = self.spawn('mmgen-walletchk',
 				slarg + hparg + of_arg + ic_arg,
 				slarg + hparg + of_arg + ic_arg,
 				extra_desc=edesc)
 				extra_desc=edesc)
-			t.passphrase(desc,self.wpasswd+'\n')
+			t.passphrase(desc, self.wpasswd+'\n')
 			if wtype == 'hic_wallet_old':
 			if wtype == 'hic_wallet_old':
-				t.expect('Is the Seed ID correct? (Y/n): ','\n')
+				t.expect('Is the Seed ID correct? (Y/n): ', '\n')
 			chk = t.expect_getend('Seed ID: ')
 			chk = t.expect_getend('Seed ID: ')
-			cmp_or_die(self.seed_id,chk)
+			cmp_or_die(self.seed_id, chk)
 			ok_msg()
 			ok_msg()
 		t.skip_ok = True
 		t.skip_ok = True
 		return t
 		return t
@@ -148,14 +148,14 @@ class CmdTestRef3Seed(CmdTestBase,CmdTestShared):
 		hp_arg = f'-p{ref_wallet_hash_preset}'
 		hp_arg = f'-p{ref_wallet_hash_preset}'
 		label = f'ref. wallet (pw {ref_wallet_brainpass!r}, seed len {self.seed_len}) α'
 		label = f'ref. wallet (pw {ref_wallet_brainpass!r}, seed len {self.seed_len}) α'
 		bf = 'ref.mmbrain'
 		bf = 'ref.mmbrain'
-		args = ['-d',self.tmpdir,hp_arg,sl_arg,'-ibw','-L',label]
-		self.write_to_tmpfile(bf,ref_wallet_brainpass)
-		self.write_to_tmpfile(pwfile,self.wpasswd)
+		args = ['-d', self.tmpdir, hp_arg, sl_arg, '-ibw', '-L', label]
+		self.write_to_tmpfile(bf, ref_wallet_brainpass)
+		self.write_to_tmpfile(pwfile, self.wpasswd)
 		t = self.spawn('mmgen-walletconv', self.testnet_opt + args + [self.usr_rand_arg], no_passthru_opts=True)
 		t = self.spawn('mmgen-walletconv', self.testnet_opt + args + [self.usr_rand_arg], no_passthru_opts=True)
 		t.license()
 		t.license()
 		t.expect('Enter brainwallet: ', ref_wallet_brainpass+'\n')
 		t.expect('Enter brainwallet: ', ref_wallet_brainpass+'\n')
 		ocls = get_wallet_cls('mmgen')
 		ocls = get_wallet_cls('mmgen')
-		t.passphrase_new('new '+ocls.desc,self.wpasswd)
+		t.passphrase_new('new '+ocls.desc, self.wpasswd)
 		t.usr_rand(self.usr_rand_chars)
 		t.usr_rand(self.usr_rand_chars)
 		fn = os.path.split(t.written_to_file(capfirst(ocls.desc)))[-1]
 		fn = os.path.split(t.written_to_file(capfirst(ocls.desc)))[-1]
 		import re
 		import re
@@ -164,15 +164,15 @@ class CmdTestRef3Seed(CmdTestBase,CmdTestShared):
 			self.chk_data['sids'][idx],
 			self.chk_data['sids'][idx],
 			self.chk_data['lens'][idx],
 			self.chk_data['lens'][idx],
 			'-α' if cfg.debug_utf8 else '')
 			'-α' if cfg.debug_utf8 else '')
-		assert re.match(pat,fn), f'{pat} != {fn}'
+		assert re.match(pat, fn), f'{pat} != {fn}'
 		sid = os.path.basename(fn.split('-')[0])
 		sid = os.path.basename(fn.split('-')[0])
-		cmp_or_die(sid,self.seed_id,desc='Seed ID')
+		cmp_or_die(sid, self.seed_id, desc='Seed ID')
 		return t
 		return t
 
 
-	def ref_walletconv(self,ofmt,extra_args=[],re_pat=None):
+	def ref_walletconv(self, ofmt, extra_args=[], re_pat=None):
 		wf = self.get_file_with_ext('mmdat')
 		wf = self.get_file_with_ext('mmdat')
-		pf = joinpath(self.tmpdir,pwfile)
-		t = self.spawn('mmgen-walletconv',extra_args+['-d','test/trash','-o',ofmt,'-P'+pf,wf])
+		pf = joinpath(self.tmpdir, pwfile)
+		t = self.spawn('mmgen-walletconv', extra_args+['-d', 'test/trash', '-o', ofmt, '-P'+pf, wf])
 		wcls = get_wallet_cls(fmt_code=ofmt)
 		wcls = get_wallet_cls(fmt_code=ofmt)
 		fn = os.path.split(t.written_to_file(capfirst(wcls.desc)))[-1]
 		fn = os.path.split(t.written_to_file(capfirst(wcls.desc)))[-1]
 		idx = int(self.test_name[-1]) - 1
 		idx = int(self.test_name[-1]) - 1
@@ -180,15 +180,15 @@ class CmdTestRef3Seed(CmdTestBase,CmdTestShared):
 		slen = self.chk_data['lens'][idx]
 		slen = self.chk_data['lens'][idx]
 		if re_pat:
 		if re_pat:
 			import re
 			import re
-			pat = re_pat.format(sid,slen)
-			assert re.match(pat,fn), f'{pat} != {fn}'
+			pat = re_pat.format(sid, slen)
+			assert re.match(pat, fn), f'{pat} != {fn}'
 		else:
 		else:
 			cmp_or_die('{}[{}]{}.{}'.format(
 			cmp_or_die('{}[{}]{}.{}'.format(
 				sid,
 				sid,
 				slen,
 				slen,
 				'-α' if cfg.debug_utf8 else '',
 				'-α' if cfg.debug_utf8 else '',
 				wcls.ext),
 				wcls.ext),
-				fn )
+				fn)
 		return t
 		return t
 
 
 	def ref_walletconv_words(self):
 	def ref_walletconv_words(self):
@@ -204,13 +204,13 @@ class CmdTestRef3Seed(CmdTestBase,CmdTestShared):
 	def ref_walletconv_dieroll(self):
 	def ref_walletconv_dieroll(self):
 		return self.ref_walletconv(ofmt='dieroll')
 		return self.ref_walletconv(ofmt='dieroll')
 
 
-	def ref_walletconv_incog(self,ofmt='incog',ext='mmincog'):
-		args = ['-r0','-p1']
+	def ref_walletconv_incog(self, ofmt='incog', ext='mmincog'):
+		args = ['-r0', '-p1']
 		pat = r'{}-[0-9A-F]{{8}}-[0-9A-F]{{8}}\[{},1\]' + ('-α' if cfg.debug_utf8 else '') + '.' + ext
 		pat = r'{}-[0-9A-F]{{8}}-[0-9A-F]{{8}}\[{},1\]' + ('-α' if cfg.debug_utf8 else '') + '.' + ext
-		return self.ref_walletconv(ofmt=ofmt,extra_args=args,re_pat=pat)
+		return self.ref_walletconv(ofmt=ofmt, extra_args=args, re_pat=pat)
 
 
 	def ref_walletconv_hexincog(self):
 	def ref_walletconv_hexincog(self):
-		return self.ref_walletconv_incog(ofmt='incog_hex',ext='mmincox')
+		return self.ref_walletconv_incog(ofmt='incog_hex', ext='mmincox')
 
 
 class CmdTestRef3Addr(CmdTestRef3Seed):
 class CmdTestRef3Addr(CmdTestRef3Seed):
 	'generated reference address and key-address files for 128-, 192- and 256-bit seeds'
 	'generated reference address and key-address files for 128-, 192- and 256-bit seeds'
@@ -223,112 +223,112 @@ class CmdTestRef3Addr(CmdTestRef3Seed):
 		'lens': (128, 192, 256),
 		'lens': (128, 192, 256),
 		'sids': ('FE3C6545', '1378FC64', '98831F3A'),
 		'sids': ('FE3C6545', '1378FC64', '98831F3A'),
 		'refaddrgen_legacy_1': {
 		'refaddrgen_legacy_1': {
-			'btc': ('B230 7526 638F 38CB','A9DC 5A13 12CB 1317'),
-			'bch': ('026D AFE0 8C60 6CFF','B406 4937 D884 6E48'),
-			'ltc': ('2B23 5E97 848A B961','AEC3 E774 0B21 0202'),
+			'btc': ('B230 7526 638F 38CB', 'A9DC 5A13 12CB 1317'),
+			'bch': ('026D AFE0 8C60 6CFF', 'B406 4937 D884 6E48'),
+			'ltc': ('2B23 5E97 848A B961', 'AEC3 E774 0B21 0202'),
 		},
 		},
 		'refaddrgen_segwit_1': {
 		'refaddrgen_segwit_1': {
-			'btc': ('9914 6D10 2307 F348','83C8 A6B6 ADA8 25B2'),
-			'ltc': ('CC09 A190 B7DF B7CD','0425 7893 C6F1 ECA3'),
+			'btc': ('9914 6D10 2307 F348', '83C8 A6B6 ADA8 25B2'),
+			'ltc': ('CC09 A190 B7DF B7CD', '0425 7893 C6F1 ECA3'),
 		},
 		},
 		'refaddrgen_bech32_1': {
 		'refaddrgen_bech32_1': {
-			'btc': ('C529 D686 31AA ACD4','21D0 26AD 3A22 5465'),
-			'ltc': ('3DFB CFCC E180 DC9D','8C72 D5C2 07E0 5F7B'),
+			'btc': ('C529 D686 31AA ACD4', '21D0 26AD 3A22 5465'),
+			'ltc': ('3DFB CFCC E180 DC9D', '8C72 D5C2 07E0 5F7B'),
 		},
 		},
 		'refaddrgen_compressed_1': {
 		'refaddrgen_compressed_1': {
-			'btc': ('95EB 8CC0 7B3B 7856','16E6 6170 154D 2202'),
-			'bch': ('C560 A343 CEAB 118E','3F56 8DC5 0383 CD78'),
-			'ltc': ('35D5 8ECA 9A42 46C3','15B3 5492 D3D3 6854'),
+			'btc': ('95EB 8CC0 7B3B 7856', '16E6 6170 154D 2202'),
+			'bch': ('C560 A343 CEAB 118E', '3F56 8DC5 0383 CD78'),
+			'ltc': ('35D5 8ECA 9A42 46C3', '15B3 5492 D3D3 6854'),
 		},
 		},
 		'refkeyaddrgen_legacy_1': {
 		'refkeyaddrgen_legacy_1': {
-			'btc': ('CF83 32FB 8A8B 08E2','1F67 B73A FF8C 5D15'),
-			'bch': ('6909 4C64 119A 7681','7E48 5071 5E41 D1AE'),
-			'ltc': ('1896 A26C 7F14 2D01','FA0E CD4E ADAF DBF4'),
+			'btc': ('CF83 32FB 8A8B 08E2', '1F67 B73A FF8C 5D15'),
+			'bch': ('6909 4C64 119A 7681', '7E48 5071 5E41 D1AE'),
+			'ltc': ('1896 A26C 7F14 2D01', 'FA0E CD4E ADAF DBF4'),
 		},
 		},
 		'refkeyaddrgen_compressed_1': {
 		'refkeyaddrgen_compressed_1': {
-			'btc': ('E43A FA46 5751 720A','FDEE 8E45 1C0A 02AD'),
-			'bch': ('7068 9B37 8ABF 3E31','C688 29A5 BA4C 21B2'),
-			'ltc': ('7603 2FE3 2145 FFAD','3FE0 5A8E 5FBE FF3E'),
+			'btc': ('E43A FA46 5751 720A', 'FDEE 8E45 1C0A 02AD'),
+			'bch': ('7068 9B37 8ABF 3E31', 'C688 29A5 BA4C 21B2'),
+			'ltc': ('7603 2FE3 2145 FFAD', '3FE0 5A8E 5FBE FF3E'),
 		},
 		},
 		'refkeyaddrgen_segwit_1': {
 		'refkeyaddrgen_segwit_1': {
-			'btc': ('C13B F717 D4E8 CF59','BB71 175C 5416 19D8'),
-			'ltc': ('054B 9794 55B4 5D82','DE85 3CF3 9636 FE2E'),
+			'btc': ('C13B F717 D4E8 CF59', 'BB71 175C 5416 19D8'),
+			'ltc': ('054B 9794 55B4 5D82', 'DE85 3CF3 9636 FE2E'),
 		},
 		},
 		'refkeyaddrgen_bech32_1': {
 		'refkeyaddrgen_bech32_1': {
-			'btc': ('934F 1C33 6C06 B18C','A283 5BAB 7AF3 3EA4'),
-			'ltc': ('A6AD DF53 5968 7B6A','9572 43E0 A4DC 0B2E'),
+			'btc': ('934F 1C33 6C06 B18C', 'A283 5BAB 7AF3 3EA4'),
+			'ltc': ('A6AD DF53 5968 7B6A', '9572 43E0 A4DC 0B2E'),
 		},
 		},
 		'refaddrgen_legacy_2': {
 		'refaddrgen_legacy_2': {
-			'btc': ('8C17 A5FA 0470 6E89','764C 66F9 7502 AAEA'),
-			'bch': ('8117 24B6 3FDA 6B40','E58C A8A4 C371 66AE'),
-			'ltc': ('2B77 A009 D5D0 22AD','51D1 979D 0A35 F24B'),
+			'btc': ('8C17 A5FA 0470 6E89', '764C 66F9 7502 AAEA'),
+			'bch': ('8117 24B6 3FDA 6B40', 'E58C A8A4 C371 66AE'),
+			'ltc': ('2B77 A009 D5D0 22AD', '51D1 979D 0A35 F24B'),
 		},
 		},
 		'refaddrgen_compressed_2': {
 		'refaddrgen_compressed_2': {
-			'btc': ('2615 8401 2E98 7ECA','A386 EE07 A356 906D'),
-			'bch': ('3364 0F9D 8355 2A53','3451 F741 0A8A FA56'),
-			'ltc': ('197C C48C 3C37 AB0F','8DDC 5FE3 BFF9 1226'),
+			'btc': ('2615 8401 2E98 7ECA', 'A386 EE07 A356 906D'),
+			'bch': ('3364 0F9D 8355 2A53', '3451 F741 0A8A FA56'),
+			'ltc': ('197C C48C 3C37 AB0F', '8DDC 5FE3 BFF9 1226'),
 		},
 		},
 		'refaddrgen_segwit_2': {
 		'refaddrgen_segwit_2': {
-			'btc': ('91C4 0414 89E4 2089','BF9F C67F ED22 A47B'),
-			'ltc': ('8F12 FA7B 9F12 594C','2609 8494 A23C F836'),
+			'btc': ('91C4 0414 89E4 2089', 'BF9F C67F ED22 A47B'),
+			'ltc': ('8F12 FA7B 9F12 594C', '2609 8494 A23C F836'),
 		},
 		},
 		'refaddrgen_bech32_2': {
 		'refaddrgen_bech32_2': {
-			'btc': ('2AA3 78DF B965 82EB','027B 1C1F 7FB2 D859'),
-			'ltc': ('951C 8FB2 FCA5 87D1','4A5D 67E0 8210 FEF2'),
+			'btc': ('2AA3 78DF B965 82EB', '027B 1C1F 7FB2 D859'),
+			'ltc': ('951C 8FB2 FCA5 87D1', '4A5D 67E0 8210 FEF2'),
 		},
 		},
 		'refkeyaddrgen_legacy_2': {
 		'refkeyaddrgen_legacy_2': {
-			'btc': ('9648 5132 B98E 3AD9','1BD3 5A36 D51C 256D'),
-			'bch': ('C4D8 7C36 DC77 F8C2','953D 245C 8CFF AC72'),
-			'ltc': ('DBD4 FAB6 7E46 CD07','8822 3FDF FEC0 6A8C'),
+			'btc': ('9648 5132 B98E 3AD9', '1BD3 5A36 D51C 256D'),
+			'bch': ('C4D8 7C36 DC77 F8C2', '953D 245C 8CFF AC72'),
+			'ltc': ('DBD4 FAB6 7E46 CD07', '8822 3FDF FEC0 6A8C'),
 		},
 		},
 		'refkeyaddrgen_compressed_2': {
 		'refkeyaddrgen_compressed_2': {
-			'btc': ('6D6D 3D35 04FD B9C3','94BF 4BCF 10B2 394B'),
-			'bch': ('3E7F C369 2AB9 BD58','0C99 14CD 5ADE 6782'),
-			'ltc': ('F5DA 9D60 6798 C4E9','7918 88DE 9096 DD7A'),
+			'btc': ('6D6D 3D35 04FD B9C3', '94BF 4BCF 10B2 394B'),
+			'bch': ('3E7F C369 2AB9 BD58', '0C99 14CD 5ADE 6782'),
+			'ltc': ('F5DA 9D60 6798 C4E9', '7918 88DE 9096 DD7A'),
 		},
 		},
 		'refkeyaddrgen_segwit_2': {
 		'refkeyaddrgen_segwit_2': {
-			'btc': ('C98B DF08 A3D5 204B','7E7F DF50 FE04 6F68'),
-			'ltc': ('1829 7FE7 2567 CB91','BE92 D19C 7589 EF30'),
+			'btc': ('C98B DF08 A3D5 204B', '7E7F DF50 FE04 6F68'),
+			'ltc': ('1829 7FE7 2567 CB91', 'BE92 D19C 7589 EF30'),
 		},
 		},
 		'refkeyaddrgen_bech32_2': {
 		'refkeyaddrgen_bech32_2': {
-			'btc': ('4A6B 3762 DF30 9368','12DD 1888 36BA 85F7'),
-			'ltc': ('5C12 FDD4 17AB F179','E195 B28C 59C4 C5EC'),
+			'btc': ('4A6B 3762 DF30 9368', '12DD 1888 36BA 85F7'),
+			'ltc': ('5C12 FDD4 17AB F179', 'E195 B28C 59C4 C5EC'),
 		},
 		},
 		'refaddrgen_legacy_3': {
 		'refaddrgen_legacy_3': {
-			'btc': ('6FEF 6FB9 7B13 5D91','424E 4326 CFFE 5F51'),
-			'bch': ('E580 43BB 0F96 AA93','630E 174A 8DDE 1BCE'),
-			'ltc': ('AD52 C3FE 8924 AAF0','4EBE 2E85 E969 1B30'),
+			'btc': ('6FEF 6FB9 7B13 5D91', '424E 4326 CFFE 5F51'),
+			'bch': ('E580 43BB 0F96 AA93', '630E 174A 8DDE 1BCE'),
+			'ltc': ('AD52 C3FE 8924 AAF0', '4EBE 2E85 E969 1B30'),
 		},
 		},
 		'refaddrgen_compressed_3': {
 		'refaddrgen_compressed_3': {
-			'btc': ('A33C 4FDE F515 F5BC','6C48 AA57 2056 C8C8'),
-			'bch': ('E37B AF41 7997 A28C','0D5D 9A58 D6E9 92EE'),
-			'ltc': ('3FC0 8F03 C2D6 BD19','4C0A 49B6 2DD1 1BE0'),
+			'btc': ('A33C 4FDE F515 F5BC', '6C48 AA57 2056 C8C8'),
+			'bch': ('E37B AF41 7997 A28C', '0D5D 9A58 D6E9 92EE'),
+			'ltc': ('3FC0 8F03 C2D6 BD19', '4C0A 49B6 2DD1 1BE0'),
 		},
 		},
 		'refaddrgen_segwit_3': {
 		'refaddrgen_segwit_3': {
-			'btc': ('06C1 9C87 F25C 4EE6','072C 8B07 2730 CB7A'),
-			'ltc': ('63DF E42A 0827 21C3','5DD1 D186 DBE1 59F2'),
+			'btc': ('06C1 9C87 F25C 4EE6', '072C 8B07 2730 CB7A'),
+			'ltc': ('63DF E42A 0827 21C3', '5DD1 D186 DBE1 59F2'),
 		},
 		},
 		'refaddrgen_bech32_3': {
 		'refaddrgen_bech32_3': {
-			'btc': ('9D2A D4B6 5117 F02E','0527 9C39 6C1B E39A'),
-			'ltc': ('FF1C 7939 5967 AB82','ED3D 8AA4 BED4 0B40'),
+			'btc': ('9D2A D4B6 5117 F02E', '0527 9C39 6C1B E39A'),
+			'ltc': ('FF1C 7939 5967 AB82', 'ED3D 8AA4 BED4 0B40'),
 		},
 		},
 		'refkeyaddrgen_legacy_3': {
 		'refkeyaddrgen_legacy_3': {
-			'btc': ('9F2D D781 1812 8BAD','88CC 5120 9A91 22C2'),
-			'bch': ('A0EE B039 48F4 24AE','B014 E0AB 5F87 EC64'),
-			'ltc': ('B804 978A 8796 3ED4','98B5 AC35 F334 0398'),
+			'btc': ('9F2D D781 1812 8BAD', '88CC 5120 9A91 22C2'),
+			'bch': ('A0EE B039 48F4 24AE', 'B014 E0AB 5F87 EC64'),
+			'ltc': ('B804 978A 8796 3ED4', '98B5 AC35 F334 0398'),
 		},
 		},
 		'refkeyaddrgen_compressed_3': {
 		'refkeyaddrgen_compressed_3': {
-			'btc': ('420A 8EB5 A9E2 7814','F43A CB4A 81F3 F735'),
-			'bch': ('33E7 5C06 88CF 2792','6E09 FF73 B7C8 00D4'),
-			'ltc': ('8D1C 781F EB7F 44BC','05F3 5C68 FD31 FCEF'),
+			'btc': ('420A 8EB5 A9E2 7814', 'F43A CB4A 81F3 F735'),
+			'bch': ('33E7 5C06 88CF 2792', '6E09 FF73 B7C8 00D4'),
+			'ltc': ('8D1C 781F EB7F 44BC', '05F3 5C68 FD31 FCEF'),
 		},
 		},
 		'refkeyaddrgen_segwit_3': {
 		'refkeyaddrgen_segwit_3': {
-			'btc': ('A447 12C2 DD14 5A9B','C770 7391 C415 21F9'),
-			'ltc': ('E8A3 9F6E E164 A521','D3D5 BFDD F5D5 20BD'),
+			'btc': ('A447 12C2 DD14 5A9B', 'C770 7391 C415 21F9'),
+			'ltc': ('E8A3 9F6E E164 A521', 'D3D5 BFDD F5D5 20BD'),
 		},
 		},
 		'refkeyaddrgen_bech32_3': {
 		'refkeyaddrgen_bech32_3': {
-			'btc': ('D0DD BDE3 87BE 15AE','7552 D70C AAB8 DEAA'),
-			'ltc': ('74A0 7DD5 963B 6326','2CDA A007 4B9F E9A5'),
+			'btc': ('D0DD BDE3 87BE 15AE', '7552 D70C AAB8 DEAA'),
+			'ltc': ('74A0 7DD5 963B 6326', '2CDA A007 4B9F E9A5'),
 		},
 		},
 	}
 	}
 
 
@@ -446,7 +446,7 @@ class CmdTestRef3Passwd(CmdTestRef3Seed):
 			no_passthru_opts = True)
 			no_passthru_opts = True)
 
 
 	def refpasswdgen(self):
 	def refpasswdgen(self):
-		return self.pwgen('pass','alice@crypto.org')
+		return self.pwgen('pass', 'alice@crypto.org')
 
 
 	def refpasswdgen_half(self):
 	def refpasswdgen_half(self):
 		return self.pwgen('pass', 'alice@crypto.org', pwlen='h')
 		return self.pwgen('pass', 'alice@crypto.org', pwlen='h')

+ 91 - 87
test/cmdtest_py_d/ct_ref_altcoin.py

@@ -22,62 +22,60 @@ test.cmdtest_py_d.ct_ref_altcoin: Altcoin reference file tests for the cmdtest.p
 
 
 from mmgen.color import set_vt100
 from mmgen.color import set_vt100
 
 
-from .common import pwfile,dfl_wpasswd,ref_dir,dfl_words_file,dfl_addr_idx_list
-from ..include.common import cfg,joinpath,start_test_daemons,stop_test_daemons,cmp_or_die
+from .common import pwfile, dfl_wpasswd, ref_dir, dfl_words_file, dfl_addr_idx_list
+from ..include.common import cfg, joinpath, start_test_daemons, stop_test_daemons, cmp_or_die
 from .ct_ref import CmdTestRef
 from .ct_ref import CmdTestRef
 from .ct_base import CmdTestBase
 from .ct_base import CmdTestBase
 
 
-class CmdTestRefAltcoin(CmdTestRef,CmdTestBase):
+class CmdTestRefAltcoin(CmdTestRef, CmdTestBase):
 	'saved and generated altcoin reference files'
 	'saved and generated altcoin reference files'
 	tmpdir_nums = [8]
 	tmpdir_nums = [8]
 	networks = ('btc',)
 	networks = ('btc',)
 	chk_data = {
 	chk_data = {
-		'ref_addrfile_chksum_zec': '903E 7225 DD86 6E01',
-		'ref_addrfile_chksum_zec_z': '9C7A 72DC 3D4A B3AF',
-		'ref_addrfile_chksum_xmr': '4369 0253 AC2C 0E38',
-		'ref_addrfile_chksum_dash':'FBC1 6B6A 0988 4403',
-		'ref_addrfile_chksum_eth': 'E554 076E 7AF6 66A3',
-		'ref_addrfile_chksum_etc': 'E97A D796 B495 E8BC',
-		'ref_keyaddrfile_chksum_zec': 'F05A 5A5C 0C8E 2617',
-		'ref_keyaddrfile_chksum_zec_z': '6B87 9B2D 0D8D 8D1E',
-		'ref_keyaddrfile_chksum_xmr': 'E0D7 9612 3D67 404A',
+		'ref_addrfile_chksum_zec':        '903E 7225 DD86 6E01',
+		'ref_addrfile_chksum_zec_z':      '9C7A 72DC 3D4A B3AF',
+		'ref_addrfile_chksum_xmr':        '4369 0253 AC2C 0E38',
+		'ref_addrfile_chksum_dash':       'FBC1 6B6A 0988 4403',
+		'ref_addrfile_chksum_eth':        'E554 076E 7AF6 66A3',
+		'ref_addrfile_chksum_etc':        'E97A D796 B495 E8BC',
+		'ref_keyaddrfile_chksum_zec':     'F05A 5A5C 0C8E 2617',
+		'ref_keyaddrfile_chksum_zec_z':   '6B87 9B2D 0D8D 8D1E',
+		'ref_keyaddrfile_chksum_xmr':     'E0D7 9612 3D67 404A',
 		'ref_viewkeyaddrfile_chksum_xmr': '40C9 0E61 B743 229C',
 		'ref_viewkeyaddrfile_chksum_xmr': '40C9 0E61 B743 229C',
-		'ref_keyaddrfile_chksum_dash': 'E83D 2C63 FEA2 4142',
-		'ref_keyaddrfile_chksum_eth': 'E400 70D9 0AE3 C7C2',
-		'ref_keyaddrfile_chksum_etc': 'EF49 967D BD6C FE45',
+		'ref_keyaddrfile_chksum_dash':    'E83D 2C63 FEA2 4142',
+		'ref_keyaddrfile_chksum_eth':     'E400 70D9 0AE3 C7C2',
+		'ref_keyaddrfile_chksum_etc':     'EF49 967D BD6C FE45',
 	}
 	}
 	cmd_group = (
 	cmd_group = (
-		('ref_altcoin_tx_chk',    'signing saved reference tx files'),
-		('ref_addrfile_gen_eth',  'generate address file (ETH)'),
-		('ref_addrfile_gen_etc',  'generate address file (ETC)'),
-		('ref_addrfile_gen_dash', 'generate address file (DASH)'),
-		('ref_addrfile_gen_zec',  'generate address file (ZEC-T)'),
-		('ref_addrfile_gen_zec_z','generate address file (ZEC-Z)'),
-		('ref_addrfile_gen_xmr',  'generate address file (XMR)'),
-		# we test the unoptimized ed25519 mod in unit_tests.py, so skip this
-#		('ref_addrfile_gen_xmr_slow','generate address file (XMR - unoptimized ed25519 module)'),
-
-		('ref_keyaddrfile_gen_eth',  'generate key-address file (ETH)'),
-		('ref_keyaddrfile_gen_etc',  'generate key-address file (ETC)'),
-		('ref_keyaddrfile_gen_dash', 'generate key-address file (DASH)'),
-		('ref_keyaddrfile_gen_zec',  'generate key-address file (ZEC-T)'),
-		('ref_keyaddrfile_gen_zec_z','generate key-address file (ZEC-Z)'),
-		('ref_keyaddrfile_gen_xmr',  'generate key-address file (XMR)'),
-		('ref_viewkeyaddrfile_gen_xmr','generate viewkey-address file (XMR)'),
-
-		('ref_addrfile_chk_eth', 'reference address file (ETH)'),
-		('ref_addrfile_chk_etc', 'reference address file (ETC)'),
-		('ref_addrfile_chk_dash','reference address file (DASH)'),
-		('ref_addrfile_chk_zec', 'reference address file (ZEC-T)'),
-		('ref_addrfile_chk_zec_z','reference address file (ZEC-Z)'),
-		('ref_addrfile_chk_xmr', 'reference address file (XMR)'),
-
-		('ref_keyaddrfile_chk_eth', 'reference key-address file (ETH)'),
-		('ref_keyaddrfile_chk_etc', 'reference key-address file (ETC)'),
-		('ref_keyaddrfile_chk_dash','reference key-address file (DASH)'),
-		('ref_keyaddrfile_chk_zec', 'reference key-address file (ZEC-T)'),
-		('ref_keyaddrfile_chk_zec_z','reference key-address file (ZEC-Z)'),
-		('ref_keyaddrfile_chk_xmr', 'reference key-address file (XMR)'),
+		('ref_altcoin_tx_chk',          'signing saved reference tx files'),
+		('ref_addrfile_gen_eth',        'generate address file (ETH)'),
+		('ref_addrfile_gen_etc',        'generate address file (ETC)'),
+		('ref_addrfile_gen_dash',       'generate address file (DASH)'),
+		('ref_addrfile_gen_zec',        'generate address file (ZEC-T)'),
+		('ref_addrfile_gen_zec_z',      'generate address file (ZEC-Z)'),
+		('ref_addrfile_gen_xmr',        'generate address file (XMR)'),
+
+		('ref_keyaddrfile_gen_eth',     'generate key-address file (ETH)'),
+		('ref_keyaddrfile_gen_etc',     'generate key-address file (ETC)'),
+		('ref_keyaddrfile_gen_dash',    'generate key-address file (DASH)'),
+		('ref_keyaddrfile_gen_zec',     'generate key-address file (ZEC-T)'),
+		('ref_keyaddrfile_gen_zec_z',   'generate key-address file (ZEC-Z)'),
+		('ref_keyaddrfile_gen_xmr',     'generate key-address file (XMR)'),
+		('ref_viewkeyaddrfile_gen_xmr', 'generate viewkey-address file (XMR)'),
+
+		('ref_addrfile_chk_eth',        'reference address file (ETH)'),
+		('ref_addrfile_chk_etc',        'reference address file (ETC)'),
+		('ref_addrfile_chk_dash',       'reference address file (DASH)'),
+		('ref_addrfile_chk_zec',        'reference address file (ZEC-T)'),
+		('ref_addrfile_chk_zec_z',      'reference address file (ZEC-Z)'),
+		('ref_addrfile_chk_xmr',        'reference address file (XMR)'),
+
+		('ref_keyaddrfile_chk_eth',     'reference key-address file (ETH)'),
+		('ref_keyaddrfile_chk_etc',     'reference key-address file (ETC)'),
+		('ref_keyaddrfile_chk_dash',    'reference key-address file (DASH)'),
+		('ref_keyaddrfile_chk_zec',     'reference key-address file (ZEC-T)'),
+		('ref_keyaddrfile_chk_zec_z',   'reference key-address file (ZEC-Z)'),
+		('ref_keyaddrfile_chk_xmr',     'reference key-address file (XMR)'),
 		('ref_viewkeyaddrfile_chk_xmr', 'reference viewkey-address file (XMR)'),
 		('ref_viewkeyaddrfile_chk_xmr', 'reference viewkey-address file (XMR)'),
 	)
 	)
 
 
@@ -87,11 +85,11 @@ class CmdTestRefAltcoin(CmdTestRef,CmdTestBase):
 		Though this basically duplicates the autosign test, here we do everything
 		Though this basically duplicates the autosign test, here we do everything
 		via the command line, so it's worth doing
 		via the command line, so it's worth doing
 		"""
 		"""
-		self.write_to_tmpfile(pwfile,dfl_wpasswd)
-		passfile = joinpath(self.tmpdir,pwfile)
+		self.write_to_tmpfile(pwfile, dfl_wpasswd)
+		passfile = joinpath(self.tmpdir, pwfile)
 		from mmgen.tx.file import MMGenTxFile
 		from mmgen.tx.file import MMGenTxFile
 		src = CmdTestRef.sources['ref_tx_file']
 		src = CmdTestRef.sources['ref_tx_file']
-		for coin,files in src.items():
+		for coin, files in src.items():
 			if coin == 'mm1':
 			if coin == 'mm1':
 				coin = 'eth'
 				coin = 'eth'
 				token_desc = ':MM1'
 				token_desc = ':MM1'
@@ -103,14 +101,14 @@ class CmdTestRefAltcoin(CmdTestRef,CmdTestBase):
 				txfile = joinpath(
 				txfile = joinpath(
 					ref_dir,
 					ref_dir,
 					self._get_ref_subdir_by_coin(coin),
 					self._get_ref_subdir_by_coin(coin),
-					fn )
-				proto = MMGenTxFile.get_proto(cfg,txfile,quiet_open=True)
+					fn)
+				proto = MMGenTxFile.get_proto(cfg, txfile, quiet_open=True)
 				if proto.sign_mode == 'daemon':
 				if proto.sign_mode == 'daemon':
 					start_test_daemons(proto.network_id)
 					start_test_daemons(proto.network_id)
 					set_vt100()
 					set_vt100()
 				t = self.spawn(
 				t = self.spawn(
 					'mmgen-txsign',
 					'mmgen-txsign',
-					['--outdir=test/trash','--yes', f'--passwd-file={passfile}', dfl_words_file, txfile],
+					['--outdir=test/trash', '--yes', f'--passwd-file={passfile}', dfl_words_file, txfile],
 					extra_desc = f'{proto.coin}{token_desc} {proto.network}')
 					extra_desc = f'{proto.coin}{token_desc} {proto.network}')
 				t.read()
 				t.read()
 				t.ok()
 				t.ok()
@@ -118,64 +116,71 @@ class CmdTestRefAltcoin(CmdTestRef,CmdTestBase):
 					stop_test_daemons(proto.network_id)
 					stop_test_daemons(proto.network_id)
 		return 'ok'
 		return 'ok'
 
 
-	def ref_altcoin_addrgen(self,coin,mmtype,gen_what='addr',coin_suf='',add_args=[],addr_idx_list=None):
+	def ref_altcoin_addrgen(
+			self,
+			coin,
+			mmtype,
+			gen_what      = 'addr',
+			coin_suf      = '',
+			add_args      = [],
+			addr_idx_list = None):
 		wf = dfl_words_file
 		wf = dfl_words_file
 		t = self.spawn(
 		t = self.spawn(
 				'mmgen-keygen' if 'key' in gen_what else 'mmgen-addrgen',
 				'mmgen-keygen' if 'key' in gen_what else 'mmgen-addrgen',
-				['-Sq','--coin='+coin] +
+				['-Sq', '--coin='+coin] +
 				(['--type='+mmtype] if mmtype else []) +
 				(['--type='+mmtype] if mmtype else []) +
 				add_args +
 				add_args +
-				[wf,addr_idx_list or dfl_addr_idx_list])
+				[wf, addr_idx_list or dfl_addr_idx_list])
 		if 'key' in gen_what:
 		if 'key' in gen_what:
-			t.expect('Encrypt key list? (y/N): ','N')
-		chk = t.expect_getend(r'.* data checksum for \S*: ',regex=True)
+			t.expect('Encrypt key list? (y/N): ', 'N')
+		chk = t.expect_getend(r'.* data checksum for \S*: ', regex=True)
 		chk_ref = self.chk_data[
 		chk_ref = self.chk_data[
 			'ref_{}addrfile_chksum_{}{}'.format(
 			'ref_{}addrfile_chksum_{}{}'.format(
 				(gen_what if 'key' in gen_what else ''),
 				(gen_what if 'key' in gen_what else ''),
 				coin.lower(),
 				coin.lower(),
-				coin_suf )
+				coin_suf)
 		]
 		]
-		cmp_or_die(chk,chk_ref,desc=f'{gen_what}list data checksum')
+		cmp_or_die(chk, chk_ref, desc=f'{gen_what}list data checksum')
 		return t
 		return t
 
 
 	def ref_addrfile_gen_eth(self):
 	def ref_addrfile_gen_eth(self):
-		return self.ref_altcoin_addrgen(coin='ETH',mmtype='ethereum')
+		return self.ref_altcoin_addrgen(coin='ETH', mmtype='ethereum')
 
 
 	def ref_addrfile_gen_etc(self):
 	def ref_addrfile_gen_etc(self):
-		return self.ref_altcoin_addrgen(coin='ETC',mmtype='ethereum')
+		return self.ref_altcoin_addrgen(coin='ETC', mmtype='ethereum')
 
 
 	def ref_addrfile_gen_dash(self):
 	def ref_addrfile_gen_dash(self):
-		return self.ref_altcoin_addrgen(coin='DASH',mmtype='compressed')
+		return self.ref_altcoin_addrgen(coin='DASH', mmtype='compressed')
 
 
 	def ref_addrfile_gen_zec(self):
 	def ref_addrfile_gen_zec(self):
-		return self.ref_altcoin_addrgen(coin='ZEC',mmtype='compressed')
+		return self.ref_altcoin_addrgen(coin='ZEC', mmtype='compressed')
 
 
 	def ref_addrfile_gen_zec_z(self):
 	def ref_addrfile_gen_zec_z(self):
-		return self.ref_altcoin_addrgen(coin='ZEC',mmtype='zcash_z',coin_suf='_z')
+		return self.ref_altcoin_addrgen(coin='ZEC', mmtype='zcash_z', coin_suf='_z')
 
 
 	def ref_addrfile_gen_xmr(self):
 	def ref_addrfile_gen_xmr(self):
-		return self.ref_altcoin_addrgen(coin='XMR',mmtype='monero')
+		return self.ref_altcoin_addrgen(coin='XMR', mmtype='monero')
 
 
 	def ref_addrfile_gen_xmr_slow(self):
 	def ref_addrfile_gen_xmr_slow(self):
-		return self.ref_altcoin_addrgen(coin='XMR',mmtype='monero',add_args=['--keygen-backend=2'])
+		return self.ref_altcoin_addrgen(coin='XMR', mmtype='monero', add_args=['--keygen-backend=2'])
 
 
 	def ref_keyaddrfile_gen_eth(self):
 	def ref_keyaddrfile_gen_eth(self):
-		return self.ref_altcoin_addrgen(coin='ETH',mmtype='ethereum',gen_what='key')
+		return self.ref_altcoin_addrgen(coin='ETH', mmtype='ethereum', gen_what='key')
 
 
 	def ref_keyaddrfile_gen_etc(self):
 	def ref_keyaddrfile_gen_etc(self):
-		return self.ref_altcoin_addrgen(coin='ETC',mmtype='ethereum',gen_what='key')
+		return self.ref_altcoin_addrgen(coin='ETC', mmtype='ethereum', gen_what='key')
 
 
 	def ref_keyaddrfile_gen_dash(self):
 	def ref_keyaddrfile_gen_dash(self):
-		return self.ref_altcoin_addrgen(coin='DASH',mmtype='compressed',gen_what='key')
+		return self.ref_altcoin_addrgen(coin='DASH', mmtype='compressed', gen_what='key')
 
 
 	def ref_keyaddrfile_gen_zec(self):
 	def ref_keyaddrfile_gen_zec(self):
-		return self.ref_altcoin_addrgen(coin='ZEC',mmtype='compressed',gen_what='key')
+		return self.ref_altcoin_addrgen(coin='ZEC', mmtype='compressed', gen_what='key')
 
 
 	def ref_keyaddrfile_gen_zec_z(self):
 	def ref_keyaddrfile_gen_zec_z(self):
-		return self.ref_altcoin_addrgen(coin='ZEC',mmtype='zcash_z',coin_suf='_z',gen_what='key')
+		return self.ref_altcoin_addrgen(coin='ZEC', mmtype='zcash_z', coin_suf='_z', gen_what='key')
 
 
 	def ref_keyaddrfile_gen_xmr(self):
 	def ref_keyaddrfile_gen_xmr(self):
-		return self.ref_altcoin_addrgen(coin='XMR',mmtype='monero',gen_what='key')
+		return self.ref_altcoin_addrgen(coin='XMR', mmtype='monero', gen_what='key')
 
 
 	def ref_viewkeyaddrfile_gen_xmr(self):
 	def ref_viewkeyaddrfile_gen_xmr(self):
 		return self.ref_altcoin_addrgen(
 		return self.ref_altcoin_addrgen(
@@ -183,57 +188,56 @@ class CmdTestRefAltcoin(CmdTestRef,CmdTestBase):
 			mmtype        = 'monero',
 			mmtype        = 'monero',
 			gen_what      = 'viewkey',
 			gen_what      = 'viewkey',
 			add_args      = ['--viewkeys'],
 			add_args      = ['--viewkeys'],
-			addr_idx_list = '1-3' )
+			addr_idx_list = '1-3')
 
 
 	def ref_addrfile_chk_eth(self):
 	def ref_addrfile_chk_eth(self):
-		return self.ref_addrfile_chk(ftype='addr',coin='ETH',subdir='ethereum',pfx='-ETH',
+		return self.ref_addrfile_chk(ftype='addr', coin='ETH', subdir='ethereum', pfx='-ETH',
 				pat='ETH Mainnet.*Ethereum')
 				pat='ETH Mainnet.*Ethereum')
 
 
 	def ref_addrfile_chk_etc(self):
 	def ref_addrfile_chk_etc(self):
-		return self.ref_addrfile_chk(ftype='addr',coin='ETC',subdir='ethereum_classic',pfx='-ETC',
+		return self.ref_addrfile_chk(ftype='addr', coin='ETC', subdir='ethereum_classic', pfx='-ETC',
 				pat='ETH Mainnet.*Ethereum')
 				pat='ETH Mainnet.*Ethereum')
 
 
 	def ref_addrfile_chk_dash(self):
 	def ref_addrfile_chk_dash(self):
-		return self.ref_addrfile_chk(ftype='addr',coin='DASH',subdir='dash',pfx='-DASH-C',
+		return self.ref_addrfile_chk(ftype='addr', coin='DASH', subdir='dash', pfx='-DASH-C',
 				pat='DASH Mainnet.*Compressed')
 				pat='DASH Mainnet.*Compressed')
 
 
 	def ref_addrfile_chk_zec(self):
 	def ref_addrfile_chk_zec(self):
-		return self.ref_addrfile_chk(ftype='addr',coin='ZEC',subdir='zcash',pfx='-ZEC-C',
+		return self.ref_addrfile_chk(ftype='addr', coin='ZEC', subdir='zcash', pfx='-ZEC-C',
 				pat='ZEC Mainnet.*Compressed')
 				pat='ZEC Mainnet.*Compressed')
 
 
 	def ref_addrfile_chk_zec_z(self):
 	def ref_addrfile_chk_zec_z(self):
-		return self.ref_addrfile_chk(ftype='addr',coin='ZEC',subdir='zcash',pfx='-ZEC-Z',mmtype='z',
+		return self.ref_addrfile_chk(ftype='addr', coin='ZEC', subdir='zcash', pfx='-ZEC-Z', mmtype='z',
 				pat='ZEC Mainnet.*Zcash_z')
 				pat='ZEC Mainnet.*Zcash_z')
 
 
 	def ref_addrfile_chk_xmr(self):
 	def ref_addrfile_chk_xmr(self):
-		return self.ref_addrfile_chk(ftype='addr',coin='XMR',subdir='monero',pfx='-XMR-M',
+		return self.ref_addrfile_chk(ftype='addr', coin='XMR', subdir='monero', pfx='-XMR-M',
 				pat='XMR Mainnet.*Monero')
 				pat='XMR Mainnet.*Monero')
 
 
-
 	def ref_keyaddrfile_chk_eth(self):
 	def ref_keyaddrfile_chk_eth(self):
-		return self.ref_addrfile_chk(ftype='keyaddr',coin='ETH',subdir='ethereum',pfx='-ETH',
+		return self.ref_addrfile_chk(ftype='keyaddr', coin='ETH', subdir='ethereum', pfx='-ETH',
 				pat='ETH Mainnet.*Ethereum')
 				pat='ETH Mainnet.*Ethereum')
 
 
 	def ref_keyaddrfile_chk_etc(self):
 	def ref_keyaddrfile_chk_etc(self):
-		return self.ref_addrfile_chk(ftype='keyaddr',coin='ETC',subdir='ethereum_classic',pfx='-ETC',
+		return self.ref_addrfile_chk(ftype='keyaddr', coin='ETC', subdir='ethereum_classic', pfx='-ETC',
 				pat='ETH Mainnet.*Ethereum')
 				pat='ETH Mainnet.*Ethereum')
 
 
 	def ref_keyaddrfile_chk_dash(self):
 	def ref_keyaddrfile_chk_dash(self):
-		return self.ref_addrfile_chk(ftype='keyaddr',coin='DASH',subdir='dash',pfx='-DASH-C',
+		return self.ref_addrfile_chk(ftype='keyaddr', coin='DASH', subdir='dash', pfx='-DASH-C',
 				pat='DASH Mainnet.*Compressed')
 				pat='DASH Mainnet.*Compressed')
 
 
 	def ref_keyaddrfile_chk_zec(self):
 	def ref_keyaddrfile_chk_zec(self):
-		return self.ref_addrfile_chk(ftype='keyaddr',coin='ZEC',subdir='zcash',pfx='-ZEC-C',
+		return self.ref_addrfile_chk(ftype='keyaddr', coin='ZEC', subdir='zcash', pfx='-ZEC-C',
 				pat='ZEC Mainnet.*Compressed')
 				pat='ZEC Mainnet.*Compressed')
 
 
 	def ref_keyaddrfile_chk_zec_z(self):
 	def ref_keyaddrfile_chk_zec_z(self):
-		return self.ref_addrfile_chk(ftype='keyaddr',coin='ZEC',subdir='zcash',pfx='-ZEC-Z',mmtype='z',
+		return self.ref_addrfile_chk(ftype='keyaddr', coin='ZEC', subdir='zcash', pfx='-ZEC-Z', mmtype='z',
 				pat='ZEC Mainnet.*Zcash_z')
 				pat='ZEC Mainnet.*Zcash_z')
 
 
 	def ref_keyaddrfile_chk_xmr(self):
 	def ref_keyaddrfile_chk_xmr(self):
-		return self.ref_addrfile_chk(ftype='keyaddr',coin='XMR',subdir='monero',pfx='-XMR-M',
+		return self.ref_addrfile_chk(ftype='keyaddr', coin='XMR', subdir='monero', pfx='-XMR-M',
 				pat='XMR Mainnet.*Monero')
 				pat='XMR Mainnet.*Monero')
 
 
 	def ref_viewkeyaddrfile_chk_xmr(self):
 	def ref_viewkeyaddrfile_chk_xmr(self):
-		return self.ref_addrfile_chk(ftype='viewkeyaddr',coin='XMR',subdir='monero',pfx='-XMR-M',
+		return self.ref_addrfile_chk(ftype='viewkeyaddr', coin='XMR', subdir='monero', pfx='-XMR-M',
 				pat='XMR Mainnet.*Monero')
 				pat='XMR Mainnet.*Monero')

File diff suppressed because it is too large
+ 250 - 244
test/cmdtest_py_d/ct_regtest.py


+ 100 - 100
test/cmdtest_py_d/ct_seedsplit.py

@@ -25,7 +25,7 @@ import os
 from mmgen.wallet import get_wallet_cls
 from mmgen.wallet import get_wallet_cls
 from mmgen.util import capfirst
 from mmgen.util import capfirst
 
 
-from ..include.common import strip_ansi_escapes,cmp_or_die
+from ..include.common import strip_ansi_escapes, cmp_or_die
 from .common import get_file_with_ext
 from .common import get_file_with_ext
 from .ct_base import CmdTestBase
 from .ct_base import CmdTestBase
 
 
@@ -41,85 +41,85 @@ class CmdTestSeedSplit(CmdTestBase):
 	tmpdir_nums = [23]
 	tmpdir_nums = [23]
 	color = True
 	color = True
 	cmd_group = (
 	cmd_group = (
-		('ss_walletgen',                'wallet generation'),
-		('ss_2way_A_dfl1',              '2-way seed split (share A)'),
-		('ss_2way_B_dfl1',              '2-way seed split (share B)'),
-		('ss_2way_join_dfl1',           '2-way seed join'),
-		('ss_2way_A_dfl2',              "2-way seed split 'default' (share A)"),
-		('ss_2way_B_dfl2',              "2-way seed split 'default' (share B)"),
-		('ss_2way_join_dfl2',           "2-way seed join 'default'"),
-		('ss_2way_A_alice',             "2-way seed split 'alice' (share A)"),
-		('ss_2way_B_alice',             "2-way seed split 'alice' (share B)"),
-		('ss_2way_join_alice',          "2-way seed join 'alice'"),
-		('ss_2way_join_alice_mix',      "2-way seed join 'alice' (out of order)"),
-		('ss_2way_A_dfl_master3',       '2-way seed split with master share #3 (share A)'),
-		('ss_2way_B_dfl_master3',       '2-way seed split with master share #3 (share B)'),
-		('ss_2way_join_dfl_master3',    '2-way seed join with master share #3'),
-		('ss_2way_A_dfl_usw',           '2-way seed split of user-specified wallet (share A)'),
-		('ss_2way_B_dfl_usw',           '2-way seed split of user-specified wallet (share B)'),
-		('ss_2way_join_dfl_usw',        '2-way seed join of user-specified wallet'),
-		('ss_3way_A_dfl',               '3-way seed split (share A)'),
-		('ss_3way_B_dfl',               '3-way seed split (share B)'),
-		('ss_3way_C_dfl',               '3-way seed split (share C)'),
-		('ss_3way_join_dfl',            '3-way seed join'),
-		('ss_3way_join_dfl_mix',        '3-way seed join (out of order)'),
-		('ss_3way_A_foobar_master7',    "3-way seed split 'φυβαρ' with master share #7 (share A)"),
-		('ss_3way_B_foobar_master7',    "3-way seed split 'φυβαρ' with master share #7 (share B)"),
-		('ss_3way_C_foobar_master7',    "3-way seed split 'φυβαρ' with master share #7 (share C)"),
-		('ss_3way_join_foobar_master7', "3-way seed join 'φυβαρ' with master share #7"),
-		('ss_3way_join_foobar_master7_mix',"3-way seed join 'φυβαρ' with master share #7 (out of order)"),
-
-		('ss_3way_join_dfl_bad_invocation',"bad invocation of 'mmgen-seedjoin' - --id-str with non-master join"),
-		('ss_bad_invocation1',          "bad invocation of 'mmgen-seedsplit' - no arguments"),
-		('ss_bad_invocation2',          "bad invocation of 'mmgen-seedsplit' - master share with split specifier"),
-		('ss_bad_invocation3',          "bad invocation of 'mmgen-seedsplit' - nonexistent file"),
-		('ss_bad_invocation4',          "bad invocation of 'mmgen-seedsplit' - invalid file extension"),
-		('ss_bad_invocation5',          "bad invocation of 'mmgen-seedjoin' - no arguments"),
-		('ss_bad_invocation6',          "bad invocation of 'mmgen-seedjoin' - one file argument"),
-		('ss_bad_invocation7',          "bad invocation of 'mmgen-seedjoin' - invalid file extension"),
-		('ss_bad_invocation8',          "bad invocation of 'mmgen-seedjoin' - nonexistent file"),
-		('ss_bad_invocation9',          "bad invocation of 'mmgen-seedsplit' - bad specifier"),
-		('ss_bad_invocation10',         "bad invocation of 'mmgen-seedsplit' - nonexistent file"),
-		('ss_bad_invocation11',         "bad invocation of 'mmgen-seedsplit' - invalid file extension"),
+		('ss_walletgen',             'wallet generation'),
+		('ss_2way_A_dfl1',           '2-way seed split (share A)'),
+		('ss_2way_B_dfl1',           '2-way seed split (share B)'),
+		('ss_2way_join_dfl1',        '2-way seed join'),
+		('ss_2way_A_dfl2',           '2-way seed split ‘default’ (share A)'),
+		('ss_2way_B_dfl2',           '2-way seed split ‘default’ (share B)'),
+		('ss_2way_join_dfl2',        '2-way seed join ‘default’'),
+		('ss_2way_A_alice',          '2-way seed split ‘alice’ (share A)'),
+		('ss_2way_B_alice',          '2-way seed split ‘alice’ (share B)'),
+		('ss_2way_join_alice',       '2-way seed join ‘alice’'),
+		('ss_2way_join_alice_mix',   '2-way seed join ‘alice’ (out of order)'),
+		('ss_2way_A_dfl_master3',    '2-way seed split with master share #3 (share A)'),
+		('ss_2way_B_dfl_master3',    '2-way seed split with master share #3 (share B)'),
+		('ss_2way_join_dfl_master3', '2-way seed join with master share #3'),
+		('ss_2way_A_dfl_usw',        '2-way seed split of user-specified wallet (share A)'),
+		('ss_2way_B_dfl_usw',        '2-way seed split of user-specified wallet (share B)'),
+		('ss_2way_join_dfl_usw',     '2-way seed join of user-specified wallet'),
+		('ss_3way_A_dfl',            '3-way seed split (share A)'),
+		('ss_3way_B_dfl',            '3-way seed split (share B)'),
+		('ss_3way_C_dfl',            '3-way seed split (share C)'),
+		('ss_3way_join_dfl',         '3-way seed join'),
+		('ss_3way_join_dfl_mix',     '3-way seed join (out of order)'),
+		('ss_3way_A_foobar_master7', '3-way seed split ‘φυβαρ’ with master share #7 (share A)'),
+		('ss_3way_B_foobar_master7', '3-way seed split ‘φυβαρ’ with master share #7 (share B)'),
+		('ss_3way_C_foobar_master7', '3-way seed split ‘φυβαρ’ with master share #7 (share C)'),
+		('ss_3way_join_foobar_master7', '3-way seed join ‘φυβαρ’ with master share #7'),
+		('ss_3way_join_foobar_master7_mix', '3-way seed join ‘φυβαρ’ with master share #7 (out of order)'),
+
+		('ss_3way_join_dfl_bad_invocation', 'bad invocation of ‘mmgen-seedjoin’ - --id-str with non-master join'),
+		('ss_bad_invocation1',       'bad invocation of ‘mmgen-seedsplit’ - no arguments'),
+		('ss_bad_invocation2',       'bad invocation of ‘mmgen-seedsplit’ - master share with split specifier'),
+		('ss_bad_invocation3',       'bad invocation of ‘mmgen-seedsplit’ - nonexistent file'),
+		('ss_bad_invocation4',       'bad invocation of ‘mmgen-seedsplit’ - invalid file extension'),
+		('ss_bad_invocation5',       'bad invocation of ‘mmgen-seedjoin’ - no arguments'),
+		('ss_bad_invocation6',       'bad invocation of ‘mmgen-seedjoin’ - one file argument'),
+		('ss_bad_invocation7',       'bad invocation of ‘mmgen-seedjoin’ - invalid file extension'),
+		('ss_bad_invocation8',       'bad invocation of ‘mmgen-seedjoin’ - nonexistent file'),
+		('ss_bad_invocation9',       'bad invocation of ‘mmgen-seedsplit’ - bad specifier'),
+		('ss_bad_invocation10',      'bad invocation of ‘mmgen-seedsplit’ - nonexistent file'),
+		('ss_bad_invocation11',      'bad invocation of ‘mmgen-seedsplit’ - invalid file extension'),
 	)
 	)
 
 
-	def get_tmp_subdir(self,subdir):
-		return os.path.join(self.tmpdir,subdir)
+	def get_tmp_subdir(self, subdir):
+		return os.path.join(self.tmpdir, subdir)
 
 
 	def ss_walletgen(self):
 	def ss_walletgen(self):
-		t = self.spawn('mmgen-walletgen', ['-r0','-p1'])
-		t.passphrase_new('new '+dfl_wcls.desc,wpasswd)
+		t = self.spawn('mmgen-walletgen', ['-r0', '-p1'])
+		t.passphrase_new('new '+dfl_wcls.desc, wpasswd)
 		t.label()
 		t.label()
-		self.write_to_tmpfile('dfl.sid',strip_ansi_escapes(t.expect_getend('Seed ID: ')))
-		t.expect('move it to the data directory? (Y/n): ','y')
+		self.write_to_tmpfile('dfl.sid', strip_ansi_escapes(t.expect_getend('Seed ID: ')))
+		t.expect('move it to the data directory? (Y/n): ', 'y')
 		t.written_to_file(capfirst(dfl_wcls.desc))
 		t.written_to_file(capfirst(dfl_wcls.desc))
 		return t
 		return t
 
 
-	def ss_splt(self,tdir,ofmt,spec,add_args=[],wf=None,master=None):
+	def ss_splt(self, tdir, ofmt, spec, add_args=[], wf=None, master=None):
 		try:
 		try:
 			os.mkdir(self.get_tmp_subdir(tdir))
 			os.mkdir(self.get_tmp_subdir(tdir))
 		except:
 		except:
 			pass
 			pass
 		t = self.spawn('mmgen-seedsplit',
 		t = self.spawn('mmgen-seedsplit',
-				['-q','-d',self.get_tmp_subdir(tdir),'-r0','-o',ofmt]
-				+ (['-L',(spec or 'label')] if ofmt == 'w' else [])
+				['-q', '-d', self.get_tmp_subdir(tdir), '-r0', '-o', ofmt]
+				+ (['-L', (spec or 'label')] if ofmt == 'w' else [])
 				+ add_args
 				+ add_args
 				+ ([f'--master-share={master}'] if master else [])
 				+ ([f'--master-share={master}'] if master else [])
 				+ ([wf] if wf else [])
 				+ ([wf] if wf else [])
 				+ ([spec] if spec else []))
 				+ ([spec] if spec else []))
 		if not wf:
 		if not wf:
-			t.passphrase(dfl_wcls.desc,wpasswd)
+			t.passphrase(dfl_wcls.desc, wpasswd)
 		if spec:
 		if spec:
 			from mmgen.seedsplit import SeedSplitSpecifier
 			from mmgen.seedsplit import SeedSplitSpecifier
 			sss = SeedSplitSpecifier(spec)
 			sss = SeedSplitSpecifier(spec)
 			pat = rf'Processing .*\b{sss.idx}\b of \b{sss.count}\b of .* id .*‘{sss.id}’'
 			pat = rf'Processing .*\b{sss.idx}\b of \b{sss.count}\b of .* id .*‘{sss.id}’'
 		else:
 		else:
 			pat = f'master share #{master}'
 			pat = f'master share #{master}'
-		t.expect(pat,regex=True)
+		t.expect(pat, regex=True)
 		ocls = get_wallet_cls(fmt_code=ofmt)
 		ocls = get_wallet_cls(fmt_code=ofmt)
 		if ocls.enc:
 		if ocls.enc:
-			t.hash_preset('new '+ocls.desc,'1')
-			t.passphrase_new('new '+ocls.desc,sh1_passwd)
+			t.hash_preset('new '+ocls.desc, '1')
+			t.passphrase_new('new '+ocls.desc, sh1_passwd)
 			if ocls.type == 'incog_hidden':
 			if ocls.type == 'incog_hidden':
 				t.hincog_create(1234)
 				t.hincog_create(1234)
 		t.written_to_file(capfirst(ocls.desc))
 		t.written_to_file(capfirst(ocls.desc))
@@ -136,119 +136,119 @@ class CmdTestSeedSplit(CmdTestBase):
 			master   = None,
 			master   = None,
 			id_str   = None):
 			id_str   = None):
 		td = self.get_tmp_subdir(tdir)
 		td = self.get_tmp_subdir(tdir)
-		shares = [get_file_with_ext(td,f) for f in in_exts]
+		shares = [get_file_with_ext(td, f) for f in in_exts]
 		if not sid:
 		if not sid:
 			sid = self.read_from_tmpfile('dfl.sid')
 			sid = self.read_from_tmpfile('dfl.sid')
 		t = self.spawn('mmgen-seedjoin',
 		t = self.spawn('mmgen-seedjoin',
 				add_args
 				add_args
 				+ ([f'--master-share={master}'] if master else [])
 				+ ([f'--master-share={master}'] if master else [])
 				+ ([f'--id-str={id_str}'] if id_str else [])
 				+ ([f'--id-str={id_str}'] if id_str else [])
-				+ ['-d',td,'-o',ofmt]
-				+ (['--label','Joined Wallet Label','-r0'] if ofmt == 'w' else [])
+				+ ['-d', td, '-o', ofmt]
+				+ (['--label', 'Joined Wallet Label', '-r0'] if ofmt == 'w' else [])
 				+ shares,
 				+ shares,
 				exit_val = exit_val)
 				exit_val = exit_val)
 		if exit_val:
 		if exit_val:
 			return t
 			return t
-		icls = ( dfl_wcls if 'mmdat' in in_exts
+		icls = (dfl_wcls if 'mmdat' in in_exts
 			else get_wallet_cls('incog') if 'mmincog' in in_exts
 			else get_wallet_cls('incog') if 'mmincog' in in_exts
 			else get_wallet_cls('incog_hex') if 'mmincox' in in_exts
 			else get_wallet_cls('incog_hex') if 'mmincox' in in_exts
 			else get_wallet_cls('incog_hidden') if '-H' in add_args
 			else get_wallet_cls('incog_hidden') if '-H' in add_args
-			else None )
+			else None)
 		if icls.type.startswith('incog'):
 		if icls.type.startswith('incog'):
-			t.hash_preset(icls.desc,'1')
+			t.hash_preset(icls.desc, '1')
 		if icls:
 		if icls:
-			t.passphrase(icls.desc,sh1_passwd)
+			t.passphrase(icls.desc, sh1_passwd)
 		if master:
 		if master:
 			fs = "master share #{}, split id.*‘{}’.*, share count {}"
 			fs = "master share #{}, split id.*‘{}’.*, share count {}"
 			pat = fs.format(
 			pat = fs.format(
 				master,
 				master,
 				id_str or 'default',
 				id_str or 'default',
-				len(shares) + (icls.type=='incog_hidden') )
-			t.expect(pat,regex=True)
+				len(shares) + (icls.type=='incog_hidden'))
+			t.expect(pat, regex=True)
 		sid_cmp = strip_ansi_escapes(t.expect_getend('Joined Seed ID: '))
 		sid_cmp = strip_ansi_escapes(t.expect_getend('Joined Seed ID: '))
-		cmp_or_die(sid,sid_cmp)
+		cmp_or_die(sid, sid_cmp)
 		ocls = get_wallet_cls(fmt_code=ofmt)
 		ocls = get_wallet_cls(fmt_code=ofmt)
 		if ocls.type == 'mmgen':
 		if ocls.type == 'mmgen':
-			t.hash_preset('new '+ocls.desc,'1')
-			t.passphrase_new('new '+ocls.desc,wpasswd)
+			t.hash_preset('new '+ocls.desc, '1')
+			t.passphrase_new('new '+ocls.desc, wpasswd)
 		t.written_to_file(capfirst(ocls.desc))
 		t.written_to_file(capfirst(ocls.desc))
 		return t
 		return t
 
 
-	def get_hincog_arg(self,tdir,suf='-default-2of2'):
+	def get_hincog_arg(self, tdir, suf='-default-2of2'):
 		sid = self.read_from_tmpfile('dfl.sid')
 		sid = self.read_from_tmpfile('dfl.sid')
-		return os.path.join(self.tmpdir,tdir,sid+suf+'.hincog') + ',123'
+		return os.path.join(self.tmpdir, tdir, sid+suf+'.hincog') + ',123'
 
 
 	def ss_2way_A_dfl1(self):
 	def ss_2way_A_dfl1(self):
-		return self.ss_splt('2way_dfl1','w','1:2')
+		return self.ss_splt('2way_dfl1', 'w', '1:2')
 	def ss_2way_B_dfl1(self):
 	def ss_2way_B_dfl1(self):
-		return self.ss_splt('2way_dfl1','bip39','2:2')
+		return self.ss_splt('2way_dfl1', 'bip39', '2:2')
 	def ss_2way_join_dfl1(self):
 	def ss_2way_join_dfl1(self):
-		return self.ss_join('2way_dfl1','w',['mmdat','bip39'])
+		return self.ss_join('2way_dfl1', 'w', ['mmdat', 'bip39'])
 
 
 	def ss_2way_A_dfl2(self):
 	def ss_2way_A_dfl2(self):
-		return self.ss_splt('2way_dfl2','seed','default:1:2')
+		return self.ss_splt('2way_dfl2', 'seed', 'default:1:2')
 	def ss_2way_B_dfl2(self):
 	def ss_2way_B_dfl2(self):
-		return self.ss_splt('2way_dfl2','hincog','default:2:2',['-J',self.get_hincog_arg('2way_dfl2')])
+		return self.ss_splt('2way_dfl2', 'hincog', 'default:2:2', ['-J', self.get_hincog_arg('2way_dfl2')])
 	def ss_2way_join_dfl2(self):
 	def ss_2way_join_dfl2(self):
-		return self.ss_join('2way_dfl2','mmhex',['mmseed'],['-H',self.get_hincog_arg('2way_dfl2')])
+		return self.ss_join('2way_dfl2', 'mmhex', ['mmseed'], ['-H', self.get_hincog_arg('2way_dfl2')])
 
 
 	def ss_2way_A_alice(self):
 	def ss_2way_A_alice(self):
-		return self.ss_splt('2way_alice','w','alice:1:2')
+		return self.ss_splt('2way_alice', 'w', 'alice:1:2')
 	def ss_2way_B_alice(self):
 	def ss_2way_B_alice(self):
-		return self.ss_splt('2way_alice','mmhex','alice:2:2')
+		return self.ss_splt('2way_alice', 'mmhex', 'alice:2:2')
 	def ss_2way_join_alice(self):
 	def ss_2way_join_alice(self):
-		return self.ss_join('2way_alice','seed',['mmdat','mmhex'])
+		return self.ss_join('2way_alice', 'seed', ['mmdat', 'mmhex'])
 	def ss_2way_join_alice_mix(self):
 	def ss_2way_join_alice_mix(self):
-		return self.ss_join('2way_alice','seed',['mmhex','mmdat'])
+		return self.ss_join('2way_alice', 'seed', ['mmhex', 'mmdat'])
 
 
 	def ss_2way_A_dfl_usw(self):
 	def ss_2way_A_dfl_usw(self):
-		return self.ss_splt('2way_dfl_usw','words','1:2',[],wf=ref_wf)
+		return self.ss_splt('2way_dfl_usw', 'words', '1:2', [], wf=ref_wf)
 	def ss_2way_B_dfl_usw(self):
 	def ss_2way_B_dfl_usw(self):
-		return self.ss_splt('2way_dfl_usw','incog','2:2',[],wf=ref_wf)
+		return self.ss_splt('2way_dfl_usw', 'incog', '2:2', [], wf=ref_wf)
 	def ss_2way_join_dfl_usw(self):
 	def ss_2way_join_dfl_usw(self):
-		return self.ss_join('2way_dfl_usw','mmhex',['mmwords','mmincog'],sid=ref_sid)
+		return self.ss_join('2way_dfl_usw', 'mmhex', ['mmwords', 'mmincog'], sid=ref_sid)
 
 
 	def ss_3way_A_dfl(self):
 	def ss_3way_A_dfl(self):
-		return self.ss_splt('3way_dfl','words','1:3')
+		return self.ss_splt('3way_dfl', 'words', '1:3')
 	def ss_3way_B_dfl(self):
 	def ss_3way_B_dfl(self):
-		return self.ss_splt('3way_dfl','incog_hex','2:3')
+		return self.ss_splt('3way_dfl', 'incog_hex', '2:3')
 	def ss_3way_C_dfl(self):
 	def ss_3way_C_dfl(self):
-		return self.ss_splt('3way_dfl','bip39','3:3')
+		return self.ss_splt('3way_dfl', 'bip39', '3:3')
 	def ss_3way_join_dfl(self):
 	def ss_3way_join_dfl(self):
-		return self.ss_join('3way_dfl','mmhex',['mmwords','mmincox','bip39'])
+		return self.ss_join('3way_dfl', 'mmhex', ['mmwords', 'mmincox', 'bip39'])
 	def ss_3way_join_dfl_mix(self):
 	def ss_3way_join_dfl_mix(self):
-		return self.ss_join('3way_dfl','mmhex',['bip39','mmwords','mmincox'])
+		return self.ss_join('3way_dfl', 'mmhex', ['bip39', 'mmwords', 'mmincox'])
 
 
 	def ss_2way_A_dfl_master3(self):
 	def ss_2way_A_dfl_master3(self):
-		return self.ss_splt('2way_dfl_master3','w','',master=3)
+		return self.ss_splt('2way_dfl_master3', 'w', '', master=3)
 	def ss_2way_B_dfl_master3(self):
 	def ss_2way_B_dfl_master3(self):
-		return self.ss_splt('2way_dfl_master3','bip39','2:2',master=3)
+		return self.ss_splt('2way_dfl_master3', 'bip39', '2:2', master=3)
 	def ss_2way_join_dfl_master3(self):
 	def ss_2way_join_dfl_master3(self):
-		return self.ss_join('2way_dfl_master3','mmhex',['mmdat','bip39'],master=3)
+		return self.ss_join('2way_dfl_master3', 'mmhex', ['mmdat', 'bip39'], master=3)
 
 
 	tdir2 = '3way_foobar_master7'
 	tdir2 = '3way_foobar_master7'
 	def ss_3way_C_foobar_master7(self):
 	def ss_3way_C_foobar_master7(self):
-		return self.ss_splt(self.tdir2,'hincog','',
-					['-J',self.get_hincog_arg(self.tdir2,'-master7')],master=7)
+		return self.ss_splt(self.tdir2, 'hincog', '',
+					['-J', self.get_hincog_arg(self.tdir2, '-master7')], master=7)
 	def ss_3way_B_foobar_master7(self):
 	def ss_3way_B_foobar_master7(self):
-		return self.ss_splt(self.tdir2,'bip39','φυβαρ:2:3',master=7)
+		return self.ss_splt(self.tdir2, 'bip39', 'φυβαρ:2:3', master=7)
 	def ss_3way_A_foobar_master7(self):
 	def ss_3way_A_foobar_master7(self):
-		return self.ss_splt(self.tdir2,'mmhex','φυβαρ:3:3',master=7)
+		return self.ss_splt(self.tdir2, 'mmhex', 'φυβαρ:3:3', master=7)
 	def ss_3way_join_foobar_master7(self):
 	def ss_3way_join_foobar_master7(self):
-		return self.ss_join(self.tdir2,'seed', ['bip39','mmhex'],
-							['-H',self.get_hincog_arg(self.tdir2,'-master7')],master=7,id_str='φυβαρ')
+		return self.ss_join(self.tdir2, 'seed', ['bip39', 'mmhex'],
+							['-H', self.get_hincog_arg(self.tdir2, '-master7')], master=7, id_str='φυβαρ')
 	def ss_3way_join_foobar_master7_mix(self):
 	def ss_3way_join_foobar_master7_mix(self):
-		return self.ss_join(self.tdir2,'seed', ['mmhex','bip39'],
-							['-H',self.get_hincog_arg(self.tdir2,'-master7')],master=7,id_str='φυβαρ')
+		return self.ss_join(self.tdir2, 'seed', ['mmhex', 'bip39'],
+							['-H', self.get_hincog_arg(self.tdir2, '-master7')], master=7, id_str='φυβαρ')
 
 
-	def ss_bad_invocation(self,cmd,args,exit_val,errmsg):
+	def ss_bad_invocation(self, cmd, args, exit_val, errmsg):
 		t = self.spawn(cmd, args, exit_val=exit_val)
 		t = self.spawn(cmd, args, exit_val=exit_val)
 		t.expect(errmsg, regex=True)
 		t.expect(errmsg, regex=True)
 		return t
 		return t
 
 
 	def ss_3way_join_dfl_bad_invocation(self):
 	def ss_3way_join_dfl_bad_invocation(self):
-		t = self.ss_join('3way_dfl','mmhex',
-			['mmwords','mmincox','bip39'],
+		t = self.ss_join('3way_dfl', 'mmhex',
+			['mmwords', 'mmincox', 'bip39'],
 			id_str   = 'foo',
 			id_str   = 'foo',
 			exit_val = 1)
 			exit_val = 1)
 		t.expect('option meaningless')
 		t.expect('option meaningless')

+ 56 - 56
test/cmdtest_py_d/ct_shared.py

@@ -26,14 +26,14 @@ from mmgen.addrlist import AddrList
 from mmgen.passwdlist import PasswordList
 from mmgen.passwdlist import PasswordList
 
 
 from ..include.common import cfg, cmp_or_die, strip_ansi_escapes, joinpath, silence, end_silence
 from ..include.common import cfg, cmp_or_die, strip_ansi_escapes, joinpath, silence, end_silence
-from .common import ref_bw_file,ref_bw_hash_preset,ref_dir
+from .common import ref_bw_file, ref_bw_hash_preset, ref_dir
 
 
 class CmdTestShared:
 class CmdTestShared:
 	'shared methods for the cmdtest.py test suite'
 	'shared methods for the cmdtest.py test suite'
 
 
 	@property
 	@property
 	def segwit_mmtype(self):
 	def segwit_mmtype(self):
-		return ('segwit','bech32')[bool(cfg.bech32)] if self.segwit else None
+		return ('segwit', 'bech32')[bool(cfg.bech32)] if self.segwit else None
 
 
 	@property
 	@property
 	def segwit_arg(self):
 	def segwit_arg(self):
@@ -66,48 +66,48 @@ class CmdTestShared:
 		confirm_pat = r'Is this what you want.*:.'
 		confirm_pat = r'Is this what you want.*:.'
 
 
 		if used_chg_addr_resp is not None:
 		if used_chg_addr_resp is not None:
-			t.expect('reuse harms your privacy.*:.*',used_chg_addr_resp,regex=True)
+			t.expect('reuse harms your privacy.*:.*', used_chg_addr_resp, regex=True)
 
 
 		if auto_chg_addr is not None:
 		if auto_chg_addr is not None:
 			e1 = 'Choose a change address:.*Enter a number> '
 			e1 = 'Choose a change address:.*Enter a number> '
 			e2 = fr'Using .*{auto_chg_addr}.* as.*address'
 			e2 = fr'Using .*{auto_chg_addr}.* as.*address'
-			res = t.expect([e1,e2],regex=True)
+			res = t.expect([e1, e2], regex=True)
 			if res == 0:
 			if res == 0:
 				choice = [s.split(')')[0].lstrip() for s in t.p.match[0].split('\n') if auto_chg_addr in s][0]
 				choice = [s.split(')')[0].lstrip() for s in t.p.match[0].split('\n') if auto_chg_addr in s][0]
 				t.send(f'{choice}\n')
 				t.send(f'{choice}\n')
-				t.expect(e2,regex=True)
+				t.expect(e2, regex=True)
 			t.send('y')
 			t.send('y')
 
 
 		pat = expect_pat
 		pat = expect_pat
 		for choice in menu + ['q']:
 		for choice in menu + ['q']:
-			t.expect(pat,choice,regex=True)
+			t.expect(pat, choice, regex=True)
 			if self.proto.base_proto == 'Ethereum':
 			if self.proto.base_proto == 'Ethereum':
 				pat = confirm_pat if pat == delete_pat else delete_pat if choice == 'D' else expect_pat
 				pat = confirm_pat if pat == delete_pat else delete_pat if choice == 'D' else expect_pat
 
 
 		if bad_input_sels:
 		if bad_input_sels:
-			for r in ('x','3-1','9999'):
-				t.expect(input_sels_prompt+': ',r+'\n')
+			for r in ('x', '3-1', '9999'):
+				t.expect(input_sels_prompt+': ', r+'\n')
 
 
-		t.expect(input_sels_prompt+': ',inputs+'\n')
+		t.expect(input_sels_prompt+': ', inputs+'\n')
 
 
-		have_est_fee = t.expect([f'{fee_desc}: ','OK? (Y/n): ']) == 1
+		have_est_fee = t.expect([f'{fee_desc}: ', 'OK? (Y/n): ']) == 1
 
 
 		if have_est_fee and not interactive_fee:
 		if have_est_fee and not interactive_fee:
 			t.send('y')
 			t.send('y')
 		else:
 		else:
 			if have_est_fee:
 			if have_est_fee:
 				t.send('n')
 				t.send('n')
-				t.expect(f'{fee_desc}: ',interactive_fee+'\n')
+				t.expect(f'{fee_desc}: ', interactive_fee+'\n')
 			else:
 			else:
 				t.send(interactive_fee+'\n')
 				t.send(interactive_fee+'\n')
 			if fee_info_pat:
 			if fee_info_pat:
-				t.expect(fee_info_pat,regex=True)
-			t.expect('OK? (Y/n): ','y')
+				t.expect(fee_info_pat, regex=True)
+			t.expect('OK? (Y/n): ', 'y')
 
 
-		t.expect('(Y/n): ','\n') # chg amt OK prompt
+		t.expect('(Y/n): ', '\n') # chg amt OK prompt
 
 
 		if 'confirm_non_mmgen' in tweaks:
 		if 'confirm_non_mmgen' in tweaks:
-			t.expect('Continue? (Y/n)','\n')
+			t.expect('Continue? (Y/n)', '\n')
 
 
 		t.do_comment(add_comment)
 		t.do_comment(add_comment)
 
 
@@ -116,7 +116,7 @@ class CmdTestShared:
 
 
 		t.view_tx(view)
 		t.view_tx(view)
 		if not txdo:
 		if not txdo:
-			t.expect('(y/N): ',('n','y')[save])
+			t.expect('(y/N): ', ('n', 'y')[save])
 			t.written_to_file(file_desc)
 			t.written_to_file(file_desc)
 
 
 		return t
 		return t
@@ -136,12 +136,12 @@ class CmdTestShared:
 		txdo = (caller or self.test_name)[:4] == 'txdo'
 		txdo = (caller or self.test_name)[:4] == 'txdo'
 
 
 		if do_passwd:
 		if do_passwd:
-			t.passphrase('MMGen wallet',self.wpasswd)
+			t.passphrase('MMGen wallet', self.wpasswd)
 
 
 		if not ni and not txdo:
 		if not ni and not txdo:
 			t.view_tx(view)
 			t.view_tx(view)
-			t.do_comment(add_comment,has_label=has_label)
-			t.expect('(Y/n): ',('n','y')[save])
+			t.do_comment(add_comment, has_label=has_label)
+			t.expect('(Y/n): ', ('n', 'y')[save])
 
 
 		t.written_to_file(file_desc)
 		t.written_to_file(file_desc)
 
 
@@ -164,9 +164,9 @@ class CmdTestShared:
 		if not txdo:
 		if not txdo:
 			t.license() # MMGEN_NO_LICENSE is set, so does nothing
 			t.license() # MMGEN_NO_LICENSE is set, so does nothing
 			t.view_tx(view)
 			t.view_tx(view)
-			t.do_comment(add_comment,has_label=has_label)
+			t.do_comment(add_comment, has_label=has_label)
 
 
-		self._do_confirm_send(t,quiet=quiet,confirm_send=confirm_send)
+		self._do_confirm_send(t, quiet=quiet, confirm_send=confirm_send)
 
 
 		if bogus_send:
 		if bogus_send:
 			txid = ''
 			txid = ''
@@ -179,10 +179,10 @@ class CmdTestShared:
 
 
 		return txid
 		return txid
 
 
-	def txsign_end(self,t,tnum=None,has_label=False):
+	def txsign_end(self, t, tnum=None, has_label=False):
 		t.expect('Signing transaction')
 		t.expect('Signing transaction')
-		t.do_comment(False,has_label=has_label)
-		t.expect(r'Save signed transaction.*?\? \(Y/n\): ','y',regex=True)
+		t.do_comment(False, has_label=has_label)
+		t.expect(r'Save signed transaction.*?\? \(Y/n\): ', 'y', regex=True)
 		t.written_to_file('Signed transaction' + (' #' + tnum if tnum else ''))
 		t.written_to_file('Signed transaction' + (' #' + tnum if tnum else ''))
 		return t
 		return t
 
 
@@ -196,7 +196,7 @@ class CmdTestShared:
 			extra_desc = '',
 			extra_desc = '',
 			view       = 'n',
 			view       = 'n',
 			dfl_wallet = False):
 			dfl_wallet = False):
-		opts = extra_opts + ['-d',self.tmpdir,txfile] + ([wf] if wf else [])
+		opts = extra_opts + ['-d', self.tmpdir, txfile] + ([wf] if wf else [])
 		wcls = get_wallet_cls(ext = 'mmdat' if dfl_wallet else get_extension(wf))
 		wcls = get_wallet_cls(ext = 'mmdat' if dfl_wallet else get_extension(wf))
 		t = self.spawn(
 		t = self.spawn(
 			'mmgen-txsign',
 			'mmgen-txsign',
@@ -206,19 +206,19 @@ class CmdTestShared:
 		t.license()
 		t.license()
 		t.view_tx(view)
 		t.view_tx(view)
 		if wcls.enc and wcls.type != 'brain':
 		if wcls.enc and wcls.type != 'brain':
-			t.passphrase(wcls.desc,self.wpasswd)
+			t.passphrase(wcls.desc, self.wpasswd)
 		if save:
 		if save:
-			self.txsign_end(t,has_label=has_label)
+			self.txsign_end(t, has_label=has_label)
 		else:
 		else:
-			t.do_comment(False,has_label=has_label)
-			t.expect('Save signed transaction? (Y/n): ','n')
+			t.do_comment(False, has_label=has_label)
+			t.expect('Save signed transaction? (Y/n): ', 'n')
 			t.expect('not saved')
 			t.expect('not saved')
 		return t
 		return t
 
 
-	def ref_brain_chk(self,bw_file=ref_bw_file):
-		wf = joinpath(ref_dir,bw_file)
+	def ref_brain_chk(self, bw_file=ref_bw_file):
+		wf = joinpath(ref_dir, bw_file)
 		add_args = [f'-l{self.seed_len}', f'-p{ref_bw_hash_preset}']
 		add_args = [f'-l{self.seed_len}', f'-p{ref_bw_hash_preset}']
-		return self.walletchk(wf,add_args=add_args,sid=self.ref_bw_seed_id)
+		return self.walletchk(wf, add_args=add_args, sid=self.ref_bw_seed_id)
 
 
 	def walletchk(
 	def walletchk(
 			self,
 			self,
@@ -228,21 +228,21 @@ class CmdTestShared:
 			sid        = None,
 			sid        = None,
 			extra_desc = '',
 			extra_desc = '',
 			dfl_wallet = False):
 			dfl_wallet = False):
-		hp = self.hash_preset if hasattr(self,'hash_preset') else '1'
+		hp = self.hash_preset if hasattr(self, 'hash_preset') else '1'
 		wcls = wcls or get_wallet_cls(ext=get_extension(wf))
 		wcls = wcls or get_wallet_cls(ext=get_extension(wf))
 		t = self.spawn(
 		t = self.spawn(
 				'mmgen-walletchk',
 				'mmgen-walletchk',
-				([] if dfl_wallet else ['-i',wcls.fmt_codes[0]])
+				([] if dfl_wallet else ['-i', wcls.fmt_codes[0]])
 				+ self.testnet_opt
 				+ self.testnet_opt
-				+ add_args + ['-p',hp]
+				+ add_args + ['-p', hp]
 				+ ([wf] if wf else []),
 				+ ([wf] if wf else []),
 				extra_desc       = extra_desc,
 				extra_desc       = extra_desc,
 				no_passthru_opts = True)
 				no_passthru_opts = True)
 		if wcls.type != 'incog_hidden':
 		if wcls.type != 'incog_hidden':
 			t.expect(f"Getting {wcls.desc} from file ‘")
 			t.expect(f"Getting {wcls.desc} from file ‘")
 		if wcls.enc and wcls.type != 'brain':
 		if wcls.enc and wcls.type != 'brain':
-			t.passphrase(wcls.desc,self.wpasswd)
-			t.expect(['Passphrase is OK', 'Passphrase.* are correct'],regex=True)
+			t.passphrase(wcls.desc, self.wpasswd)
+			t.expect(['Passphrase is OK', 'Passphrase.* are correct'], regex=True)
 		chksum = t.expect_getend(f'Valid {wcls.desc} for Seed ID ')[:8]
 		chksum = t.expect_getend(f'Valid {wcls.desc} for Seed ID ')[:8]
 		if sid:
 		if sid:
 			cmp_or_die(chksum, sid)
 			cmp_or_die(chksum, sid)
@@ -265,19 +265,19 @@ class CmdTestShared:
 			mmtype = self.segwit_mmtype
 			mmtype = self.segwit_mmtype
 		t = self.spawn(
 		t = self.spawn(
 				f'mmgen-{list_type}gen',
 				f'mmgen-{list_type}gen',
-				['-d',self.tmpdir] + extra_opts +
-				([],['--type='+str(mmtype)])[bool(mmtype)] +
-				([],['--stdout'])[stdout] +
-				([],[wf])[bool(wf)] +
-				([],[id_str])[bool(id_str)] +
-				[getattr(self,f'{list_type}_idx_list')],
-				extra_desc       = f'({mmtype})' if mmtype in ('segwit','bech32') else '',
+				['-d', self.tmpdir] + extra_opts +
+				([], ['--type='+str(mmtype)])[bool(mmtype)] +
+				([], ['--stdout'])[stdout] +
+				([], [wf])[bool(wf)] +
+				([], [id_str])[bool(id_str)] +
+				[getattr(self, f'{list_type}_idx_list')],
+				extra_desc       = f'({mmtype})' if mmtype in ('segwit', 'bech32') else '',
 				no_passthru_opts = no_passthru_opts)
 				no_passthru_opts = no_passthru_opts)
 		t.license()
 		t.license()
-		wcls = get_wallet_cls( ext = 'mmdat' if dfl_wallet else get_extension(wf) )
-		t.passphrase(wcls.desc,self.wpasswd)
+		wcls = get_wallet_cls(ext = 'mmdat' if dfl_wallet else get_extension(wf))
+		t.passphrase(wcls.desc, self.wpasswd)
 		t.expect('Passphrase is OK')
 		t.expect('Passphrase is OK')
-		desc = ('address','password')[passgen]
+		desc = ('address', 'password')[passgen]
 		chksum = strip_ansi_escapes(t.expect_getend(rf'Checksum for {desc} data .*?: ', regex=True))
 		chksum = strip_ansi_escapes(t.expect_getend(rf'Checksum for {desc} data .*?: ', regex=True))
 		if check_ref:
 		if check_ref:
 			chksum_chk = (
 			chksum_chk = (
@@ -285,7 +285,7 @@ class CmdTestShared:
 				self.chk_data[self.test_name][self.fork][self.proto.testnet])
 				self.chk_data[self.test_name][self.fork][self.proto.testnet])
 			cmp_or_die(chksum, chksum_chk, desc=f'{ftype}list data checksum')
 			cmp_or_die(chksum, chksum_chk, desc=f'{ftype}list data checksum')
 		if passgen:
 		if passgen:
-			t.expect('Encrypt password list? (y/N): ','N')
+			t.expect('Encrypt password list? (y/N): ', 'N')
 		if stdout:
 		if stdout:
 			t.read()
 			t.read()
 		else:
 		else:
@@ -306,20 +306,20 @@ class CmdTestShared:
 				extra_desc = f'({mmtype})' if mmtype in ('segwit', 'bech32') else '')
 				extra_desc = f'({mmtype})' if mmtype in ('segwit', 'bech32') else '')
 		t.license()
 		t.license()
 		wcls = get_wallet_cls(ext=get_extension(wf))
 		wcls = get_wallet_cls(ext=get_extension(wf))
-		t.passphrase(wcls.desc,self.wpasswd)
-		chksum = t.expect_getend(r'Checksum for key-address data .*?: ',regex=True)
+		t.passphrase(wcls.desc, self.wpasswd)
+		chksum = t.expect_getend(r'Checksum for key-address data .*?: ', regex=True)
 		if check_ref:
 		if check_ref:
 			chksum_chk = self.chk_data[self.test_name][self.fork][self.proto.testnet]
 			chksum_chk = self.chk_data[self.test_name][self.fork][self.proto.testnet]
 			cmp_or_die(chksum, chksum_chk, desc='key-address list data checksum')
 			cmp_or_die(chksum, chksum_chk, desc='key-address list data checksum')
-		t.expect('Encrypt key list? (y/N): ','y')
+		t.expect('Encrypt key list? (y/N): ', 'y')
 		t.usr_rand(self.usr_rand_chars)
 		t.usr_rand(self.usr_rand_chars)
-		t.hash_preset('new key-address list','1')
-		t.passphrase_new('new key-address list',self.kapasswd)
+		t.hash_preset('new key-address list', '1')
+		t.passphrase_new('new key-address list', self.kapasswd)
 		t.written_to_file('Encrypted secret keys')
 		t.written_to_file('Encrypted secret keys')
 		return t
 		return t
 
 
-	def _do_confirm_send(self,t,quiet=False,confirm_send=True,sure=True):
+	def _do_confirm_send(self, t, quiet=False, confirm_send=True, sure=True):
 		if sure:
 		if sure:
 			t.expect('Are you sure you want to broadcast this')
 			t.expect('Are you sure you want to broadcast this')
-		m = ('YES, I REALLY WANT TO DO THIS','YES')[quiet]
-		t.expect(f'{m!r} to confirm: ',('',m)[confirm_send]+'\n')
+		m = ('YES, I REALLY WANT TO DO THIS', 'YES')[quiet]
+		t.expect(f'{m!r} to confirm: ', ('', m)[confirm_send]+'\n')

+ 52 - 36
test/cmdtest_py_d/ct_tool.py

@@ -10,7 +10,7 @@
 test.cmdtest_py_d.ct_tool: tool tests for the MMGen cmdtest.py test suite
 test.cmdtest_py_d.ct_tool: tool tests for the MMGen cmdtest.py test suite
 """
 """
 
 
-import sys,os
+import sys, os
 
 
 from mmgen.util import suf
 from mmgen.util import suf
 from mmgen.color import cyan
 from mmgen.color import cyan
@@ -24,35 +24,51 @@ from ..include.common import (
 	joinpath,
 	joinpath,
 	getrand
 	getrand
 )
 )
-from .common import hincog_fn,incog_id_fn,hincog_offset,tool_enc_passwd,ref_dir
+from .common import hincog_fn, incog_id_fn, hincog_offset, tool_enc_passwd, ref_dir
 from .ct_base import CmdTestBase
 from .ct_base import CmdTestBase
 from .ct_main import CmdTestMain
 from .ct_main import CmdTestMain
 
 
-class CmdTestTool(CmdTestMain,CmdTestBase):
+class CmdTestTool(CmdTestMain, CmdTestBase):
 	"interactive 'mmgen-tool' commands"
 	"interactive 'mmgen-tool' commands"
 	networks = ('btc',)
 	networks = ('btc',)
 	segwit_opts_ok = False
 	segwit_opts_ok = False
 	tmpdir_nums = [9]
 	tmpdir_nums = [9]
 	enc_infn = 'tool_encrypt.in'
 	enc_infn = 'tool_encrypt.in'
 	cmd_group = (
 	cmd_group = (
-		('tool_find_incog_data', (9,"'mmgen-tool find_incog_data'", [[[hincog_fn],1],[[incog_id_fn],1]])),
-		('tool_rand2file',       (9,"'mmgen-tool rand2file'", [])),
-		('tool_encrypt',         (9,"'mmgen-tool encrypt' (random data)",     [])),
-		('tool_decrypt',         (9,"'mmgen-tool decrypt' (random data)", [[[enc_infn+'.mmenc'],9]])),
-		('tool_twview_bad_comment',(9,"'mmgen-tool twview' (with bad comment)", [])),
-		('tool_decrypt_keystore',(9,"'mmgen-tool decrypt_keystore'", [])),
-		('tool_decrypt_geth_keystore',(9,"'mmgen-tool decrypt_geth_keystore'", [])),
-		('tool_api',             (9,'tool API (initialization, config methods, wif2addr)',[])),
-		# ('tool_encrypt_ref', (9,"'mmgen-tool encrypt' (reference text)",  [])),
+		('tool_find_incog_data',
+			(9, '‘mmgen-tool find_incog_data’', [[[hincog_fn], 1], [[incog_id_fn], 1]])
+		),
+		('tool_rand2file',
+			(9, '‘mmgen-tool rand2file’', [])
+		),
+		('tool_encrypt',
+			(9, '‘mmgen-tool encrypt’ (random data)', [])
+		),
+		('tool_decrypt',
+			(9, '‘mmgen-tool decrypt’ (random data)', [[[enc_infn+'.mmenc'], 9]])
+		),
+		('tool_twview_bad_comment',
+			(9, '‘mmgen-tool twview’ (with bad comment)', [])
+		),
+		('tool_decrypt_keystore',
+			(9, '‘mmgen-tool decrypt_keystore’', [])
+		),
+		('tool_decrypt_geth_keystore',
+			(9, '‘mmgen-tool decrypt_geth_keystore’', [])
+		),
+		('tool_api',
+			(9, 'tool API (initialization, config methods, wif2addr)', [])
+		),
+		# ('tool_encrypt_ref', (9, '‘mmgen-tool encrypt’ (reference text)', [])),
 	)
 	)
 
 
 	def tool_rand2file(self):
 	def tool_rand2file(self):
 		from mmgen.util2 import parse_bytespec
 		from mmgen.util2 import parse_bytespec
-		for nbytes in ('1','1023','1K','1048575','1M','1048577','123M'):
+		for nbytes in ('1', '1023', '1K', '1048575', '1M', '1048577', '123M'):
 			t = self.spawn(
 			t = self.spawn(
 				'mmgen-tool',
 				'mmgen-tool',
-				['-d',self.tmpdir,'-r0','rand2file','rand2file.out',nbytes],
-				extra_desc='({} byte{})'.format( nbytes, suf(parse_bytespec(nbytes)) )
+				['-d', self.tmpdir, '-r0', 'rand2file', 'rand2file.out', nbytes],
+				extra_desc='({} byte{})'.format(nbytes, suf(parse_bytespec(nbytes)))
 			)
 			)
 			t.expect('random data written to file')
 			t.expect('random data written to file')
 			t.read()
 			t.read()
@@ -62,49 +78,49 @@ class CmdTestTool(CmdTestMain,CmdTestBase):
 		return t
 		return t
 
 
 	def tool_encrypt(self):
 	def tool_encrypt(self):
-		infile = joinpath(self.tmpdir,self.enc_infn)
-		write_to_file(infile,getrand(1033),binary=True)
-		t = self.spawn('mmgen-tool',['-d',self.tmpdir,self.usr_rand_arg,'encrypt',infile])
+		infile = joinpath(self.tmpdir, self.enc_infn)
+		write_to_file(infile, getrand(1033), binary=True)
+		t = self.spawn('mmgen-tool', ['-d', self.tmpdir, self.usr_rand_arg, 'encrypt', infile])
 		t.usr_rand(self.usr_rand_chars)
 		t.usr_rand(self.usr_rand_chars)
-		t.hash_preset('data','1')
-		t.passphrase_new('data',tool_enc_passwd)
+		t.hash_preset('data', '1')
+		t.passphrase_new('data', tool_enc_passwd)
 		t.written_to_file('Encrypted data')
 		t.written_to_file('Encrypted data')
 		return t
 		return t
 
 
-	def tool_decrypt(self,f1):
+	def tool_decrypt(self, f1):
 		out_fn = 'tool_encrypt.out'
 		out_fn = 'tool_encrypt.out'
-		t = self.spawn('mmgen-tool',['-d',self.tmpdir,'decrypt',f1,'outfile='+out_fn,'hash_preset=1'])
-		t.passphrase('data',tool_enc_passwd)
+		t = self.spawn('mmgen-tool', ['-d', self.tmpdir, 'decrypt', f1, 'outfile='+out_fn, 'hash_preset=1'])
+		t.passphrase('data', tool_enc_passwd)
 		t.written_to_file('Decrypted data')
 		t.written_to_file('Decrypted data')
-		d1 = self.read_from_tmpfile(self.enc_infn,binary=True)
-		d2 = self.read_from_tmpfile(out_fn,binary=True)
-		cmp_or_die(d1,d2)
+		d1 = self.read_from_tmpfile(self.enc_infn, binary=True)
+		d2 = self.read_from_tmpfile(out_fn, binary=True)
+		cmp_or_die(d1, d2)
 		return t
 		return t
 
 
-	def tool_find_incog_data(self,f1,f2):
+	def tool_find_incog_data(self, f1, f2):
 		i_id = read_from_file(f2).rstrip()
 		i_id = read_from_file(f2).rstrip()
 		vmsg(f'Incog ID: {cyan(i_id)}')
 		vmsg(f'Incog ID: {cyan(i_id)}')
-		t = self.spawn('mmgen-tool',['-d',self.tmpdir,'find_incog_data',f1,i_id])
+		t = self.spawn('mmgen-tool', ['-d', self.tmpdir, 'find_incog_data', f1, i_id])
 		o = t.expect_getend(f'Incog data for ID {i_id} found at offset ')
 		o = t.expect_getend(f'Incog data for ID {i_id} found at offset ')
 		if not sys.platform == 'win32':
 		if not sys.platform == 'win32':
 			os.unlink(f1) # causes problems with MSYS2
 			os.unlink(f1) # causes problems with MSYS2
-		cmp_or_die(hincog_offset,int(o))
+		cmp_or_die(hincog_offset, int(o))
 		return t
 		return t
 
 
 	def tool_twview_bad_comment(self): # test correct operation of get_tw_label()
 	def tool_twview_bad_comment(self): # test correct operation of get_tw_label()
 		t = self.spawn(
 		t = self.spawn(
 			'mmgen-tool',
 			'mmgen-tool',
 			['twview'],
 			['twview'],
-			env = { 'MMGEN_BOGUS_UNSPENT_DATA': joinpath(ref_dir,'bad-comment-unspent.json') },
+			env = {'MMGEN_BOGUS_UNSPENT_DATA': joinpath(ref_dir, 'bad-comment-unspent.json')},
 			exit_val = 2)
 			exit_val = 2)
 		t.expect('cannot be converted to TwComment')
 		t.expect('cannot be converted to TwComment')
 		return t
 		return t
 
 
-	def _decrypt_keystore(self,cmd,fn,pw,chk):
+	def _decrypt_keystore(self, cmd, fn, pw, chk):
 		if cfg.no_altcoin:
 		if cfg.no_altcoin:
 			return 'skip'
 			return 'skip'
-		t = self.spawn('mmgen-tool',['-d',self.tmpdir,cmd,fn])
-		t.expect('Enter passphrase: ',pw+'\n')
+		t = self.spawn('mmgen-tool', ['-d', self.tmpdir, cmd, fn])
+		t.expect('Enter passphrase: ', pw+'\n')
 		t.expect(chk)
 		t.expect(chk)
 		return t
 		return t
 
 
@@ -113,7 +129,7 @@ class CmdTestTool(CmdTestMain,CmdTestBase):
 			cmd = 'decrypt_keystore',
 			cmd = 'decrypt_keystore',
 			fn  = 'test/ref/altcoin/98831F3A-keystore-wallet.json',
 			fn  = 'test/ref/altcoin/98831F3A-keystore-wallet.json',
 			pw = 'abc',
 			pw = 'abc',
-			chk = read_from_file('test/ref/98831F3A.bip39').strip() )
+			chk = read_from_file('test/ref/98831F3A.bip39').strip())
 
 
 	def tool_decrypt_geth_keystore(self):
 	def tool_decrypt_geth_keystore(self):
 		return self._decrypt_keystore(
 		return self._decrypt_keystore(
@@ -126,6 +142,6 @@ class CmdTestTool(CmdTestMain,CmdTestBase):
 		t = self.spawn(
 		t = self.spawn(
 				'tool_api_test.py',
 				'tool_api_test.py',
 				(['no_altcoin'] if cfg.no_altcoin else []),
 				(['no_altcoin'] if cfg.no_altcoin else []),
-				cmd_dir = 'test/misc' )
-		t.expect('legacy.*compressed.*segwit.*bech32',regex=True)
+				cmd_dir = 'test/misc')
+		t.expect('legacy.*compressed.*segwit.*bech32', regex=True)
 		return t
 		return t

+ 100 - 98
test/cmdtest_py_d/ct_wallet.py

@@ -22,84 +22,85 @@ test.cmdtest_py_d.ct_wallet: Wallet conversion tests for the cmdtest.py test sui
 
 
 import sys, os
 import sys, os
 
 
-from mmgen.util import msg,capfirst,get_extension
+from mmgen.util import msg, capfirst, get_extension
 from mmgen.wallet import get_wallet_cls
 from mmgen.wallet import get_wallet_cls
 
 
 from ..include.common import cfg, joinpath, VirtBlockDevice
 from ..include.common import cfg, joinpath, VirtBlockDevice
-from .common import ref_dir,ref_wallet_brainpass,ref_wallet_incog_offset,hincog_fn,hincog_bytes
+from .common import ref_dir, ref_wallet_brainpass, ref_wallet_incog_offset, hincog_fn, hincog_bytes
 from .ct_base import CmdTestBase
 from .ct_base import CmdTestBase
 from .ct_shared import CmdTestShared
 from .ct_shared import CmdTestShared
 
 
-class CmdTestWalletConv(CmdTestBase,CmdTestShared):
+class CmdTestWalletConv(CmdTestBase, CmdTestShared):
 	'wallet conversion to and from reference data'
 	'wallet conversion to and from reference data'
 	networks = ('btc',)
 	networks = ('btc',)
-	tmpdir_nums = [11,12,13]
-	sources = { '128': {
-					'ref_wallet':      'FE3C6545-D782B529[128,1].mmdat',
-					'ic_wallet':       'FE3C6545-E29303EA-5E229E30[128,1].mmincog',
-					'ic_wallet_hex':   'FE3C6545-BC4BE3F2-32586837[128,1].mmincox',
-
-					'hic_wallet':       'FE3C6545-161E495F-BEB7548E[128,1].incog-offset123',
-					'hic_wallet_old':   'FE3C6545-161E495F-9860A85B[128,1].incog-old.offset123',
-				},
-				'192': {
-					'ref_wallet':      '1378FC64-6F0F9BB4[192,1].mmdat',
-					'ic_wallet':       '1378FC64-2907DE97-F980D21F[192,1].mmincog',
-					'ic_wallet_hex':   '1378FC64-4DCB5174-872806A7[192,1].mmincox',
-
-					'hic_wallet':      '1378FC64-B55E9958-77256FC1[192,1].incog.offset123',
-					'hic_wallet_old':  '1378FC64-B55E9958-D85FF20C[192,1].incog-old.offset123',
-				},
-				'256': {
-					'ref_wallet':      '98831F3A-27F2BF93[256,1].mmdat',
-					'ic_wallet':       '98831F3A-5482381C-18460FB1[256,1].mmincog',
-					'ic_wallet_hex':   '98831F3A-1630A9F2-870376A9[256,1].mmincox',
-
-					'hic_wallet':       '98831F3A-F59B07A0-559CEF19[256,1].incog.offset123',
-					'hic_wallet_old':   '98831F3A-F59B07A0-848535F3[256,1].incog-old.offset123',
-
-				},
-			}
+	tmpdir_nums = [11, 12, 13]
+	sources = {
+		'128': {
+			'ref_wallet':     'FE3C6545-D782B529[128,1].mmdat',
+			'ic_wallet':      'FE3C6545-E29303EA-5E229E30[128,1].mmincog',
+			'ic_wallet_hex':  'FE3C6545-BC4BE3F2-32586837[128,1].mmincox',
+
+			'hic_wallet':      'FE3C6545-161E495F-BEB7548E[128,1].incog-offset123',
+			'hic_wallet_old':  'FE3C6545-161E495F-9860A85B[128,1].incog-old.offset123',
+		},
+		'192': {
+			'ref_wallet':     '1378FC64-6F0F9BB4[192,1].mmdat',
+			'ic_wallet':      '1378FC64-2907DE97-F980D21F[192,1].mmincog',
+			'ic_wallet_hex':  '1378FC64-4DCB5174-872806A7[192,1].mmincox',
+
+			'hic_wallet':     '1378FC64-B55E9958-77256FC1[192,1].incog.offset123',
+			'hic_wallet_old': '1378FC64-B55E9958-D85FF20C[192,1].incog-old.offset123',
+		},
+		'256': {
+			'ref_wallet':     '98831F3A-27F2BF93[256,1].mmdat',
+			'ic_wallet':      '98831F3A-5482381C-18460FB1[256,1].mmincog',
+			'ic_wallet_hex':  '98831F3A-1630A9F2-870376A9[256,1].mmincox',
+
+			'hic_wallet':      '98831F3A-F59B07A0-559CEF19[256,1].incog.offset123',
+			'hic_wallet_old':  '98831F3A-F59B07A0-848535F3[256,1].incog-old.offset123',
+
+		},
+	}
 	cmd_group = (
 	cmd_group = (
 		# reading
 		# reading
-		('ref_wallet_conv',    'conversion of saved reference wallet'),
-		('ref_mn_conv',        'conversion of saved MMGen native mnemonic'),
-		('ref_bip39_conv',     'conversion of saved BIP39 mnemonic'),
-		('ref_seed_conv',      'conversion of saved seed file'),
-		('ref_hex_conv',       'conversion of saved MMGen hexadecimal seed file'),
-		('ref_plainhex_conv',  'conversion of saved plain hexadecimal seed file'),
-		('ref_dieroll_conv',   'conversion of saved dieroll (b6d) seed file'),
-		('ref_brain_conv',     'conversion of ref brainwallet'),
-		('ref_incog_conv',     'conversion of saved incog wallet'),
-		('ref_incox_conv',     'conversion of saved hex incog wallet'),
-		('ref_hincog_conv',    'conversion of saved hidden incog wallet'),
-		('ref_hincog_conv_old','conversion of saved hidden incog wallet (old format)'),
+		('ref_wallet_conv',            'conversion of saved reference wallet'),
+		('ref_mn_conv',                'conversion of saved MMGen native mnemonic'),
+		('ref_bip39_conv',             'conversion of saved BIP39 mnemonic'),
+		('ref_seed_conv',              'conversion of saved seed file'),
+		('ref_hex_conv',               'conversion of saved MMGen hexadecimal seed file'),
+		('ref_plainhex_conv',          'conversion of saved plain hexadecimal seed file'),
+		('ref_dieroll_conv',           'conversion of saved dieroll (b6d) seed file'),
+		('ref_brain_conv',             'conversion of ref brainwallet'),
+		('ref_incog_conv',             'conversion of saved incog wallet'),
+		('ref_incox_conv',             'conversion of saved hex incog wallet'),
+		('ref_hincog_conv',            'conversion of saved hidden incog wallet'),
+		('ref_hincog_conv_old',        'conversion of saved hidden incog wallet (old format)'),
 		# writing
 		# writing
-		('ref_wallet_conv_out', 'ref seed conversion to wallet'),
-		('ref_mn_conv_out',     'ref seed conversion to MMGen native mnemonic'),
-		('ref_bip39_conv_out',  'ref seed conversion to BIP39 mnemonic'),
-		('ref_hex_conv_out',    'ref seed conversion to MMGen hex seed'),
-		('ref_plainhex_conv_out','ref seed conversion to plain hex seed'),
-		('ref_dieroll_conv_out','ref seed conversion to dieroll (b6d) seed'),
-		('ref_seed_conv_out',   'ref seed conversion to seed'),
-		('ref_incog_conv_out',  'ref seed conversion to incog data'),
-		('ref_incox_conv_out',  'ref seed conversion to hex incog data'),
-		('ref_hincog_conv_out', 'ref seed conversion to hidden incog data'),
+		('ref_wallet_conv_out',        'ref seed conversion to wallet'),
+		('ref_mn_conv_out',            'ref seed conversion to MMGen native mnemonic'),
+		('ref_bip39_conv_out',         'ref seed conversion to BIP39 mnemonic'),
+		('ref_hex_conv_out',           'ref seed conversion to MMGen hex seed'),
+		('ref_plainhex_conv_out',      'ref seed conversion to plain hex seed'),
+		('ref_dieroll_conv_out',       'ref seed conversion to dieroll (b6d) seed'),
+		('ref_seed_conv_out',          'ref seed conversion to seed'),
+		('ref_incog_conv_out',         'ref seed conversion to incog data'),
+		('ref_incox_conv_out',         'ref seed conversion to hex incog data'),
+		('ref_hincog_conv_out',        'ref seed conversion to hidden incog data'),
 		('ref_hincog_blkdev_conv_out', 'ref seed conversion to hidden incog data on block device')
 		('ref_hincog_blkdev_conv_out', 'ref seed conversion to hidden incog data on block device')
 	)
 	)
 
 
-	def __init__(self,trunner,cfgs,spawn):
-		for k,_ in self.cmd_group:
-			for n in (1,2,3):
-				setattr(self,f'{k}_{n}',getattr(self,k))
-		CmdTestBase.__init__(self,trunner,cfgs,spawn)
+	def __init__(self, trunner, cfgs, spawn):
+		for k, _ in self.cmd_group:
+			for n in (1, 2, 3):
+				setattr(self, f'{k}_{n}', getattr(self, k))
+		CmdTestBase.__init__(self, trunner, cfgs, spawn)
 
 
 	def ref_wallet_conv(self):
 	def ref_wallet_conv(self):
-		wf = joinpath(ref_dir,self.sources[str(self.seed_len)]['ref_wallet'])
+		wf = joinpath(ref_dir, self.sources[str(self.seed_len)]['ref_wallet'])
 		return self.walletconv_in(wf)
 		return self.walletconv_in(wf)
 
 
-	def ref_mn_conv(self,ext='mmwords'):
-		wf = joinpath(ref_dir,self.seed_id+'.'+ext)
+	def ref_mn_conv(self, ext='mmwords'):
+		wf = joinpath(ref_dir, self.seed_id+'.'+ext)
 		return self.walletconv_in(wf)
 		return self.walletconv_in(wf)
 
 
 	def ref_bip39_conv(self):
 	def ref_bip39_conv(self):
@@ -114,28 +115,28 @@ class CmdTestWalletConv(CmdTestBase,CmdTestShared):
 		return self.ref_mn_conv(ext='b6d')
 		return self.ref_mn_conv(ext='b6d')
 
 
 	def ref_brain_conv(self):
 	def ref_brain_conv(self):
-		uopts = ['-i','bw','-p','1','-l',str(self.seed_len)]
-		return self.walletconv_in(None,uopts,icls=get_wallet_cls('brain'))
+		uopts = ['-i', 'bw', '-p', '1', '-l', str(self.seed_len)]
+		return self.walletconv_in(None, uopts, icls=get_wallet_cls('brain'))
 
 
-	def ref_incog_conv(self,wfk='ic_wallet',in_fmt='i'):
-		uopts = ['-i',in_fmt,'-p','1','-l',str(self.seed_len)]
-		wf = joinpath(ref_dir,self.sources[str(self.seed_len)][wfk])
-		return self.walletconv_in(wf,uopts)
+	def ref_incog_conv(self, wfk='ic_wallet', in_fmt='i'):
+		uopts = ['-i', in_fmt, '-p', '1', '-l', str(self.seed_len)]
+		wf = joinpath(ref_dir, self.sources[str(self.seed_len)][wfk])
+		return self.walletconv_in(wf, uopts)
 
 
 	def ref_incox_conv(self):
 	def ref_incox_conv(self):
-		return self.ref_incog_conv(in_fmt='xi',wfk='ic_wallet_hex')
+		return self.ref_incog_conv(in_fmt='xi', wfk='ic_wallet_hex')
 
 
-	def ref_hincog_conv(self,wfk='hic_wallet',add_uopts=[]):
-		ic_f = joinpath(ref_dir,self.sources[str(self.seed_len)][wfk])
-		uopts = ['-i','hi','-p','1','-l',str(self.seed_len)] + add_uopts
-		hi_opt = ['-H',f'{ic_f},{ref_wallet_incog_offset}']
+	def ref_hincog_conv(self, wfk='hic_wallet', add_uopts=[]):
+		ic_f = joinpath(ref_dir, self.sources[str(self.seed_len)][wfk])
+		uopts = ['-i', 'hi', '-p', '1', '-l', str(self.seed_len)] + add_uopts
+		hi_opt = ['-H', f'{ic_f},{ref_wallet_incog_offset}']
 		return self.walletconv_in(
 		return self.walletconv_in(
 			None,
 			None,
 			uopts + hi_opt,
 			uopts + hi_opt,
-			icls = get_wallet_cls('incog_hidden') )
+			icls = get_wallet_cls('incog_hidden'))
 
 
 	def ref_hincog_conv_old(self):
 	def ref_hincog_conv_old(self):
-		return self.ref_hincog_conv(wfk='hic_wallet_old',add_uopts=['-O'])
+		return self.ref_hincog_conv(wfk='hic_wallet_old', add_uopts=['-O'])
 
 
 	def ref_wallet_conv_out(self):
 	def ref_wallet_conv_out(self):
 		return self.walletconv_out('w')
 		return self.walletconv_out('w')
@@ -156,14 +157,15 @@ class CmdTestWalletConv(CmdTestBase,CmdTestShared):
 	def ref_incox_conv_out(self):
 	def ref_incox_conv_out(self):
 		return self.walletconv_out('xi')
 		return self.walletconv_out('xi')
 
 
-	def ref_hincog_conv_out(self,ic_f=None):
+	def ref_hincog_conv_out(self, ic_f=None):
 		if not ic_f:
 		if not ic_f:
-			ic_f = joinpath(self.tmpdir,hincog_fn)
+			ic_f = joinpath(self.tmpdir, hincog_fn)
 		hi_parms = f'{ic_f},{ref_wallet_incog_offset}'
 		hi_parms = f'{ic_f},{ref_wallet_incog_offset}'
 		sl_parm = '-l' + str(self.seed_len)
 		sl_parm = '-l' + str(self.seed_len)
-		return self.walletconv_out('hi',
-									uopts     = ['-J',hi_parms,sl_parm],
-									uopts_chk = ['-H',hi_parms,sl_parm] )
+		return self.walletconv_out(
+			'hi',
+			uopts     = ['-J', hi_parms, sl_parm],
+			uopts_chk = ['-H', hi_parms, sl_parm])
 
 
 	def ref_hincog_blkdev_conv_out(self):
 	def ref_hincog_blkdev_conv_out(self):
 
 
@@ -179,41 +181,41 @@ class CmdTestWalletConv(CmdTestBase,CmdTestShared):
 		return 'ok'
 		return 'ok'
 
 
 	# wallet conversion tests
 	# wallet conversion tests
-	def walletconv_in(self,infile,uopts=[],icls=None):
+	def walletconv_in(self, infile, uopts=[], icls=None):
 		ocls = get_wallet_cls('words')
 		ocls = get_wallet_cls('words')
-		opts = ['-d',self.tmpdir,'-o',ocls.fmt_codes[0],self.usr_rand_arg]
+		opts = ['-d', self.tmpdir, '-o', ocls.fmt_codes[0], self.usr_rand_arg]
 		if_arg = [infile] if infile else []
 		if_arg = [infile] if infile else []
 		d = '(convert)'
 		d = '(convert)'
-		t = self.spawn('mmgen-walletconv',opts+uopts+if_arg,extra_desc=d)
+		t = self.spawn('mmgen-walletconv', opts+uopts+if_arg, extra_desc=d)
 		t.license()
 		t.license()
 		icls = icls or get_wallet_cls(ext=get_extension(infile))
 		icls = icls or get_wallet_cls(ext=get_extension(infile))
 		if icls.type == 'brain':
 		if icls.type == 'brain':
-			t.expect('Enter brainwallet: ',ref_wallet_brainpass+'\n')
+			t.expect('Enter brainwallet: ', ref_wallet_brainpass+'\n')
 		if icls.enc and icls.type != 'brain':
 		if icls.enc and icls.type != 'brain':
-			t.passphrase(icls.desc,self.wpasswd)
+			t.passphrase(icls.desc, self.wpasswd)
 			if self.test_name[:19] == 'ref_hincog_conv_old':
 			if self.test_name[:19] == 'ref_hincog_conv_old':
-				t.expect('Is the Seed ID correct? (Y/n): ','\n')
+				t.expect('Is the Seed ID correct? (Y/n): ', '\n')
 			else:
 			else:
-				t.expect(['Passphrase is OK',' are correct'])
+				t.expect(['Passphrase is OK', ' are correct'])
 		wf = t.written_to_file(capfirst(ocls.desc))
 		wf = t.written_to_file(capfirst(ocls.desc))
 		t.p.wait()
 		t.p.wait()
 		# back check of result
 		# back check of result
 		msg('' if cfg.profile else ' OK')
 		msg('' if cfg.profile else ' OK')
 		return self.walletchk(
 		return self.walletchk(
-				wf,
-				extra_desc = '(check)',
-				sid        = self.seed_id)
+			wf,
+			extra_desc = '(check)',
+			sid        = self.seed_id)
 
 
-	def walletconv_out(self,out_fmt='w',uopts=[],uopts_chk=[]):
+	def walletconv_out(self, out_fmt='w', uopts=[], uopts_chk=[]):
 		wcls = get_wallet_cls(fmt_code=out_fmt)
 		wcls = get_wallet_cls(fmt_code=out_fmt)
-		opts = ['-d',self.tmpdir,'-p1','-o',out_fmt] + uopts
-		infile = joinpath(ref_dir,self.seed_id+'.mmwords')
-		t = self.spawn('mmgen-walletconv',[self.usr_rand_arg]+opts+[infile],extra_desc='(convert)')
+		opts = ['-d', self.tmpdir, '-p1', '-o', out_fmt] + uopts
+		infile = joinpath(ref_dir, self.seed_id+'.mmwords')
+		t = self.spawn('mmgen-walletconv', [self.usr_rand_arg]+opts+[infile], extra_desc='(convert)')
 
 
 		add_args = [f'-l{self.seed_len}']
 		add_args = [f'-l{self.seed_len}']
 		t.license()
 		t.license()
 		if wcls.enc and wcls.type != 'brain':
 		if wcls.enc and wcls.type != 'brain':
-			t.passphrase_new('new '+wcls.desc,self.wpasswd)
+			t.passphrase_new('new '+wcls.desc, self.wpasswd)
 			t.usr_rand(self.usr_rand_chars)
 			t.usr_rand(self.usr_rand_chars)
 		if wcls.type.startswith('incog'):
 		if wcls.type.startswith('incog'):
 			for _ in range(3):
 			for _ in range(3):
@@ -229,8 +231,8 @@ class CmdTestWalletConv(CmdTestBase,CmdTestShared):
 			wf = None
 			wf = None
 		msg('' if cfg.profile else ' OK')
 		msg('' if cfg.profile else ' OK')
 		return self.walletchk(
 		return self.walletchk(
-				wf,
-				wcls       = wcls,
-				extra_desc = '(check)',
-				sid        = self.seed_id,
-				add_args   = add_args)
+			wf,
+			wcls       = wcls,
+			extra_desc = '(check)',
+			sid        = self.seed_id,
+			add_args   = add_args)

+ 42 - 42
test/cmdtest_py_d/ct_xmr_autosign.py

@@ -30,9 +30,9 @@ def make_burn_addr():
 		cfg     = cfg,
 		cfg     = cfg,
 		cmdname = 'privhex2addr',
 		cmdname = 'privhex2addr',
 		proto   = cfg._proto,
 		proto   = cfg._proto,
-		mmtype  = 'monero' ).privhex2addr('beadcafe'*8)
+		mmtype  = 'monero').privhex2addr('beadcafe'*8)
 
 
-class CmdTestXMRAutosign(CmdTestXMRWallet,CmdTestAutosignThreaded):
+class CmdTestXMRAutosign(CmdTestXMRWallet, CmdTestAutosignThreaded):
 	"""
 	"""
 	Monero autosigning operations
 	Monero autosigning operations
 	"""
 	"""
@@ -99,10 +99,10 @@ class CmdTestXMRAutosign(CmdTestXMRWallet,CmdTestAutosignThreaded):
 		('check_tx_dirs',            'cleaning and checking signable file directories'),
 		('check_tx_dirs',            'cleaning and checking signable file directories'),
 	)
 	)
 
 
-	def __init__(self,trunner,cfgs,spawn):
+	def __init__(self, trunner, cfgs, spawn):
 
 
-		CmdTestAutosignThreaded.__init__(self,trunner,cfgs,spawn)
-		CmdTestXMRWallet.__init__(self,trunner,cfgs,spawn)
+		CmdTestAutosignThreaded.__init__(self, trunner, cfgs, spawn)
+		CmdTestXMRWallet.__init__(self, trunner, cfgs, spawn)
 
 
 		if trunner is None:
 		if trunner is None:
 			return
 			return
@@ -123,7 +123,7 @@ class CmdTestXMRAutosign(CmdTestXMRWallet,CmdTestAutosignThreaded):
 		self.spawn_env['MMGEN_TEST_SUITE_XMR_AUTOSIGN'] = '1'
 		self.spawn_env['MMGEN_TEST_SUITE_XMR_AUTOSIGN'] = '1'
 
 
 	def create_tmp_wallets(self):
 	def create_tmp_wallets(self):
-		self.spawn('',msg_only=True)
+		self.spawn('', msg_only=True)
 		data = self.users['alice']
 		data = self.users['alice']
 		from mmgen.wallet import Wallet
 		from mmgen.wallet import Wallet
 		from mmgen.xmrwallet import op
 		from mmgen.xmrwallet import op
@@ -133,22 +133,22 @@ class CmdTestXMRAutosign(CmdTestXMRWallet,CmdTestAutosignThreaded):
 			cfg       = self.cfg,
 			cfg       = self.cfg,
 			proto     = self.proto,
 			proto     = self.proto,
 			addr_idxs = '1-2',
 			addr_idxs = '1-2',
-			seed      = Wallet(cfg,data.mmwords).seed,
+			seed      = Wallet(cfg, data.mmwords).seed,
 			skip_chksum_msg = True,
 			skip_chksum_msg = True,
-			key_address_validity_check = False )
+			key_address_validity_check = False)
 		kal.file.write(ask_overwrite=False)
 		kal.file.write(ask_overwrite=False)
-		fn = get_file_with_ext(data.udir,'akeys')
+		fn = get_file_with_ext(data.udir, 'akeys')
 		m = op('create', self.cfg, fn, '1-2')
 		m = op('create', self.cfg, fn, '1-2')
 		async_run(m.main())
 		async_run(m.main())
 		async_run(m.stop_wallet_daemon())
 		async_run(m.stop_wallet_daemon())
 		end_silence()
 		end_silence()
 		return 'ok'
 		return 'ok'
 
 
-	def _new_addr_alice(self,*args):
+	def _new_addr_alice(self, *args):
 		data = self.users['alice']
 		data = self.users['alice']
 		return self.new_addr_alice(
 		return self.new_addr_alice(
 			*args,
 			*args,
-			kafile = get_file_with_ext(data.udir,'akeys') )
+			kafile = get_file_with_ext(data.udir, 'akeys'))
 
 
 	def new_account_alice(self):
 	def new_account_alice(self):
 		return self._new_addr_alice(
 		return self._new_addr_alice(
@@ -174,7 +174,7 @@ class CmdTestXMRAutosign(CmdTestXMRWallet,CmdTestAutosignThreaded):
 	def dump_wallets(self):
 	def dump_wallets(self):
 		return self._dump_wallets(autosign=True)
 		return self._dump_wallets(autosign=True)
 
 
-	def _dump_wallets(self,autosign):
+	def _dump_wallets(self, autosign):
 		data = self.users['alice']
 		data = self.users['alice']
 		self.insert_device_online()
 		self.insert_device_online()
 		t = self.spawn(
 		t = self.spawn(
@@ -183,27 +183,27 @@ class CmdTestXMRAutosign(CmdTestXMRWallet,CmdTestAutosignThreaded):
 			+ [f'--wallet-dir={data.udir}', f'--daemon=localhost:{data.md.rpc_port}']
 			+ [f'--wallet-dir={data.udir}', f'--daemon=localhost:{data.md.rpc_port}']
 			+ (self.autosign_opts if autosign else [])
 			+ (self.autosign_opts if autosign else [])
 			+ ['dump']
 			+ ['dump']
-			+ ([] if autosign else [get_file_with_ext(data.udir,'akeys')]) )
+			+ ([] if autosign else [get_file_with_ext(data.udir, 'akeys')]))
 		t.expect('2 wallets dumped')
 		t.expect('2 wallets dumped')
 		t.read()
 		t.read()
 		self.remove_device_online()
 		self.remove_device_online()
 		return t
 		return t
 
 
-	def _delete_files(self,*ext_list):
+	def _delete_files(self, *ext_list):
 		data = self.users['alice']
 		data = self.users['alice']
-		self.spawn('',msg_only=True)
+		self.spawn('', msg_only=True)
 		for ext in ext_list:
 		for ext in ext_list:
-			get_file_with_ext(data.udir,ext,no_dot=True,delete_all=True)
+			get_file_with_ext(data.udir, ext, no_dot=True, delete_all=True)
 		return 'ok'
 		return 'ok'
 
 
 	def delete_tmp_wallets(self):
 	def delete_tmp_wallets(self):
-		return self._delete_files( 'MoneroWallet', 'MoneroWallet.keys', '.akeys' )
+		return self._delete_files('MoneroWallet', 'MoneroWallet.keys', '.akeys')
 
 
 	def delete_wallets(self):
 	def delete_wallets(self):
-		return self._delete_files( 'MoneroWatchOnlyWallet', '.keys', '.address.txt' )
+		return self._delete_files('MoneroWatchOnlyWallet', '.keys', '.address.txt')
 
 
 	def delete_tmp_dump_files(self):
 	def delete_tmp_dump_files(self):
-		return self._delete_files( '.dump' )
+		return self._delete_files('.dump')
 
 
 	def gen_kafile_miner(self):
 	def gen_kafile_miner(self):
 		return self.gen_kafiles(['miner'])
 		return self.gen_kafiles(['miner'])
@@ -212,7 +212,7 @@ class CmdTestXMRAutosign(CmdTestXMRWallet,CmdTestAutosignThreaded):
 		return self.create_wallets_miner()
 		return self.create_wallets_miner()
 
 
 	def delete_dump_files(self):
 	def delete_dump_files(self):
-		return self._delete_files( '.dump' )
+		return self._delete_files('.dump')
 
 
 	def fund_alice1(self):
 	def fund_alice1(self):
 		return self.fund_alice(wallet=1)
 		return self.fund_alice(wallet=1)
@@ -279,7 +279,7 @@ class CmdTestXMRAutosign(CmdTestXMRWallet,CmdTestAutosignThreaded):
 
 
 	create_transfer_tx2a = create_transfer_tx2
 	create_transfer_tx2a = create_transfer_tx2
 
 
-	def _abort_tx(self,expect,send=None,exit_val=None):
+	def _abort_tx(self, expect, send=None, exit_val=None):
 		self.insert_device_online()
 		self.insert_device_online()
 		t = self.spawn('mmgen-xmrwallet', ['--autosign', 'abort'], exit_val=exit_val)
 		t = self.spawn('mmgen-xmrwallet', ['--autosign', 'abort'], exit_val=exit_val)
 		t.expect(expect)
 		t.expect(expect)
@@ -312,40 +312,40 @@ class CmdTestXMRAutosign(CmdTestXMRWallet,CmdTestAutosignThreaded):
 			+ self.autosign_opts
 			+ self.autosign_opts
 			+ [f'--wallet-dir={data.udir}', f'--daemon=localhost:{data.md.rpc_port}']
 			+ [f'--wallet-dir={data.udir}', f'--daemon=localhost:{data.md.rpc_port}']
 			+ add_opts
 			+ add_opts
-			+ [ op ]
-			+ ([get_file_with_ext(self.asi.xmr_tx_dir,ext)] if ext else [])
+			+ [op]
+			+ ([get_file_with_ext(self.asi.xmr_tx_dir, ext)] if ext else [])
 			+ ([wallet_arg] if wallet_arg else [])
 			+ ([wallet_arg] if wallet_arg else [])
 		)
 		)
 		desc_pfx = f'{desc}, ' if desc else ''
 		desc_pfx = f'{desc}, ' if desc else ''
 		self.insert_device_online() # device must be removed by calling method
 		self.insert_device_online() # device must be removed by calling method
-		return self.spawn( 'mmgen-xmrwallet', args, extra_desc=f'({desc_pfx}Alice)' )
+		return self.spawn('mmgen-xmrwallet', args, extra_desc=f'({desc_pfx}Alice)')
 
 
-	def _sync_chkbal(self,wallet_arg,bal_chk_func):
+	def _sync_chkbal(self, wallet_arg, bal_chk_func):
 		return self.sync_wallets(
 		return self.sync_wallets(
 			'alice',
 			'alice',
 			op           = 'sync',
 			op           = 'sync',
 			wallets      = wallet_arg,
 			wallets      = wallet_arg,
-			bal_chk_func = bal_chk_func )
+			bal_chk_func = bal_chk_func)
 
 
 	def sync_chkbal1(self):
 	def sync_chkbal1(self):
-		return self._sync_chkbal( '1', lambda n,b,ub: b == ub and 1 < b < 1.12 )
+		return self._sync_chkbal('1', lambda n, b, ub: b == ub and 1 < b < 1.12)
 		# 1.234567891234 - 0.124 = 1.110567891234 (minus fees)
 		# 1.234567891234 - 0.124 = 1.110567891234 (minus fees)
 
 
 	def sync_chkbal2(self):
 	def sync_chkbal2(self):
-		return self._sync_chkbal( '1', lambda n,b,ub: b == ub and 0.8 < b < 0.86 )
+		return self._sync_chkbal('1', lambda n, b, ub: b == ub and 0.8 < b < 0.86)
 		# 1.234567891234 - 0.124 - 0.257 = 0.853567891234 (minus fees)
 		# 1.234567891234 - 0.124 - 0.257 = 0.853567891234 (minus fees)
 
 
 	def sync_chkbal3(self):
 	def sync_chkbal3(self):
 		return self._sync_chkbal(
 		return self._sync_chkbal(
 			'1-2',
 			'1-2',
-			lambda n,b,ub: b == ub and ((n == 1 and 0.8 < b < 0.86) or (n == 2 and b > 1.23)) )
+			lambda n, b, ub: b == ub and ((n == 1 and 0.8 < b < 0.86) or (n == 2 and b > 1.23)))
 
 
-	def _mine_chk(self,desc):
-		bal_type = {'locked':'b','unlocked':'ub'}[desc]
+	def _mine_chk(self, desc):
+		bal_type = {'locked':'b', 'unlocked':'ub'}[desc]
 		return self.mine_chk(
 		return self.mine_chk(
 			'alice', 1, 0,
 			'alice', 1, 0,
-			lambda x: 0 < getattr(x,bal_type) < 1.234567891234,
-			f'{desc} balance 0 < 1.234567891234' )
+			lambda x: 0 < getattr(x, bal_type) < 1.234567891234,
+			f'{desc} balance 0 < 1.234567891234')
 
 
 	def submit_transfer_tx1(self):
 	def submit_transfer_tx1(self):
 		return self._submit_transfer_tx()
 		return self._submit_transfer_tx()
@@ -357,16 +357,16 @@ class CmdTestXMRAutosign(CmdTestXMRWallet,CmdTestAutosignThreaded):
 				check_bal  = False)
 				check_bal  = False)
 
 
 	def submit_transfer_tx2(self):
 	def submit_transfer_tx2(self):
-		return self._submit_transfer_tx( relay_parm=self.tx_relay_daemon_parm )
+		return self._submit_transfer_tx(relay_parm=self.tx_relay_daemon_parm)
 
 
-	def _submit_transfer_tx(self,relay_parm=None,ext=None,op='submit',check_bal=True):
+	def _submit_transfer_tx(self, relay_parm=None, ext=None, op='submit', check_bal=True):
 		t = self._xmr_autosign_op(
 		t = self._xmr_autosign_op(
 			op            = op,
 			op            = op,
 			add_opts      = [f'--tx-relay-daemon={relay_parm}'] if relay_parm else [],
 			add_opts      = [f'--tx-relay-daemon={relay_parm}'] if relay_parm else [],
 			ext           = ext,
 			ext           = ext,
 			signable_desc = 'transaction',
 			signable_desc = 'transaction',
 			wait_signed   = op == 'submit')
 			wait_signed   = op == 'submit')
-		t.expect( f'{op.capitalize()} transaction? (y/N): ', 'y' )
+		t.expect(f'{op.capitalize()} transaction? (y/N): ', 'y')
 		t.written_to_file('Submitted transaction')
 		t.written_to_file('Submitted transaction')
 		t.read()
 		t.read()
 		self.remove_device_online() # device was inserted by _xmr_autosign_op()
 		self.remove_device_online() # device was inserted by _xmr_autosign_op()
@@ -395,7 +395,7 @@ class CmdTestXMRAutosign(CmdTestXMRWallet,CmdTestAutosignThreaded):
 	def export_outputs3(self):
 	def export_outputs3(self):
 		return self._export_outputs('1-2', op='export-outputs-sign')
 		return self._export_outputs('1-2', op='export-outputs-sign')
 
 
-	def _import_key_images(self,wallet_arg):
+	def _import_key_images(self, wallet_arg):
 		t = self._xmr_autosign_op(
 		t = self._xmr_autosign_op(
 			op            = 'import-key-images',
 			op            = 'import-key-images',
 			wallet_arg    = wallet_arg,
 			wallet_arg    = wallet_arg,
@@ -413,12 +413,12 @@ class CmdTestXMRAutosign(CmdTestXMRWallet,CmdTestAutosignThreaded):
 
 
 	def txlist(self):
 	def txlist(self):
 		self.insert_device_online()
 		self.insert_device_online()
-		t = self.spawn( 'mmgen-xmrwallet', self.autosign_opts + ['txlist'] )
+		t = self.spawn('mmgen-xmrwallet', self.autosign_opts + ['txlist'])
 		t.match_expect_list([
 		t.match_expect_list([
 			'SUBMITTED',
 			'SUBMITTED',
-			'Network','Submitted',
-			'transfer 1:0','-> ext',
-			'transfer 1:0','-> ext'
+			'Network', 'Submitted',
+			'transfer 1:0', '-> ext',
+			'transfer 1:0', '-> ext'
 		])
 		])
 		t.read()
 		t.read()
 		self.remove_device_online()
 		self.remove_device_online()
@@ -466,7 +466,7 @@ class CmdTestXMRAutosign(CmdTestXMRWallet,CmdTestAutosignThreaded):
 		imsg(f'\nBefore cleaning:\n{before}')
 		imsg(f'\nBefore cleaning:\n{before}')
 		imsg(f'\nAfter cleaning:\n{after}')
 		imsg(f'\nAfter cleaning:\n{after}')
 		pat = r'xmr/tx: \s*\S+\.subtx \S+\.subtx\s+xmr/outputs:\s*$'
 		pat = r'xmr/tx: \s*\S+\.subtx \S+\.subtx\s+xmr/outputs:\s*$'
-		assert re.search( pat, after, re.DOTALL ), f'regex search for {pat} failed'
+		assert re.search(pat, after, re.DOTALL), f'regex search for {pat} failed'
 		return t
 		return t
 
 
 	def view(self):
 	def view(self):

+ 167 - 170
test/cmdtest_py_d/ct_xmrwallet.py

@@ -20,14 +20,14 @@
 test.cmdtest_py_d.ct_xmrwallet: xmrwallet tests for the cmdtest.py test suite
 test.cmdtest_py_d.ct_xmrwallet: xmrwallet tests for the cmdtest.py test suite
 """
 """
 
 
-import sys,os,time,re,atexit,asyncio,shutil
-from subprocess import run,PIPE
+import sys, os, time, re, atexit, asyncio, shutil
+from subprocess import run, PIPE
 from collections import namedtuple
 from collections import namedtuple
 
 
-from mmgen.util import msg,fmt,async_run,capfirst,is_int,die,list_gen
+from mmgen.util import msg, fmt, async_run, capfirst, is_int, die, list_gen
 from mmgen.obj import MMGenRange
 from mmgen.obj import MMGenRange
 from mmgen.amt import XMRAmt
 from mmgen.amt import XMRAmt
-from mmgen.addrlist import ViewKeyAddrList,KeyAddrList,AddrIdxList
+from mmgen.addrlist import ViewKeyAddrList, KeyAddrList, AddrIdxList
 
 
 from ..include.common import (
 from ..include.common import (
 	cfg,
 	cfg,
@@ -56,10 +56,10 @@ def stop_daemons(self):
 def stop_miner_wallet_daemon(self):
 def stop_miner_wallet_daemon(self):
 	async_run(self.users['miner'].wd_rpc.stop_daemon())
 	async_run(self.users['miner'].wd_rpc.stop_daemon())
 
 
-def kill_proxy(cls,args):
+def kill_proxy(cls, args):
 	if sys.platform in ('linux', 'darwin'):
 	if sys.platform in ('linux', 'darwin'):
 		omsg(f'Killing SSH SOCKS server at localhost:{cls.socks_port}')
 		omsg(f'Killing SSH SOCKS server at localhost:{cls.socks_port}')
-		cmd = [ 'pkill', '-f', ' '.join(args) ]
+		cmd = ['pkill', '-f', ' '.join(args)]
 		run(cmd)
 		run(cmd)
 
 
 class CmdTestXMRWallet(CmdTestBase):
 class CmdTestXMRWallet(CmdTestBase):
@@ -81,66 +81,66 @@ class CmdTestXMRWallet(CmdTestBase):
 		('bob',   '1378FC64', False, 140, None,  ['--restricted-rpc']),
 		('bob',   '1378FC64', False, 140, None,  ['--restricted-rpc']),
 	)
 	)
 	tx_relay_user = 'bob'
 	tx_relay_user = 'bob'
-	datadir_base = os.path.join('test','daemons','xmrtest')
+	datadir_base = os.path.join('test', 'daemons', 'xmrtest')
 
 
 	cmd_group = (
 	cmd_group = (
-		('daemon_version',            'checking daemon version'),
-		('gen_kafiles_miner_alice',   'generating key-address files for Miner and Alice'),
-		('create_wallets_miner',      'creating Monero wallets (Miner)'),
-		('set_label_miner',           'setting an address label (Miner, primary account)'),
-		('mine_initial_coins',        'mining initial coins'),
-		('create_wallets_alice',      'creating Monero wallets (Alice)'),
-		('fund_alice',                'sending funds'),
-		('check_bal_alice',           'mining, checking balance'),
-
-		('sync_wallets_all',          'syncing all wallets'),
-		('new_account_alice',         'creating a new account (Alice)'),
-		('new_account_alice_label',   'creating a new account (Alice, with label)'),
-		('new_address_alice',         'creating a new address (Alice)'),
-		('new_address_alice_label',   'creating a new address (Alice, with label)'),
-		('remove_label_alice',        'removing an address label (Alice, subaddress)'),
-		('set_label_alice',           'setting an address label (Alice, subaddress)'),
-		('sync_wallets_selected',     'syncing selected wallets'),
-
-		('sweep_to_wallet',           'sweeping to new account in another wallet'),
-		('sweep_to_account',          'sweeping to specific account in same wallet'),
-		('sweep_to_wallet_account',   'sweeping to specific account in another wallet'),
+		('daemon_version',                'checking daemon version'),
+		('gen_kafiles_miner_alice',       'generating key-address files for Miner and Alice'),
+		('create_wallets_miner',          'creating Monero wallets (Miner)'),
+		('set_label_miner',               'setting an address label (Miner, primary account)'),
+		('mine_initial_coins',            'mining initial coins'),
+		('create_wallets_alice',          'creating Monero wallets (Alice)'),
+		('fund_alice',                    'sending funds'),
+		('check_bal_alice',               'mining, checking balance'),
+
+		('sync_wallets_all',              'syncing all wallets'),
+		('new_account_alice',             'creating a new account (Alice)'),
+		('new_account_alice_label',       'creating a new account (Alice, with label)'),
+		('new_address_alice',             'creating a new address (Alice)'),
+		('new_address_alice_label',       'creating a new address (Alice, with label)'),
+		('remove_label_alice',            'removing an address label (Alice, subaddress)'),
+		('set_label_alice',               'setting an address label (Alice, subaddress)'),
+		('sync_wallets_selected',         'syncing selected wallets'),
+
+		('sweep_to_wallet',               'sweeping to new account in another wallet'),
+		('sweep_to_account',              'sweeping to specific account in same wallet'),
+		('sweep_to_wallet_account',       'sweeping to specific account in another wallet'),
 		('sweep_to_wallet_account_proxy', 'sweeping to specific account in another wallet (via TX relay + proxy)'),
 		('sweep_to_wallet_account_proxy', 'sweeping to specific account in another wallet (via TX relay + proxy)'),
 		('sweep_to_same_account_noproxy', 'sweeping to same account (via TX relay, no proxy)'),
 		('sweep_to_same_account_noproxy', 'sweeping to same account (via TX relay, no proxy)'),
-		('transfer_to_miner_proxy',   'transferring funds to Miner (via TX relay + proxy)'),
-		('transfer_to_miner_noproxy', 'transferring funds to Miner (via TX relay, no proxy)'),
+		('transfer_to_miner_proxy',       'transferring funds to Miner (via TX relay + proxy)'),
+		('transfer_to_miner_noproxy',     'transferring funds to Miner (via TX relay, no proxy)'),
 
 
-		('transfer_to_miner_create1', 'transferring funds to Miner (create TX)'),
-		('transfer_to_miner_send1',   'transferring funds to Miner (send TX via proxy)'),
-		('transfer_to_miner_create2', 'transferring funds to Miner (create TX)'),
-		('transfer_to_miner_send2',   'transferring funds to Miner (send TX, no proxy)'),
+		('transfer_to_miner_create1',     'transferring funds to Miner (create TX)'),
+		('transfer_to_miner_send1',       'transferring funds to Miner (send TX via proxy)'),
+		('transfer_to_miner_create2',     'transferring funds to Miner (create TX)'),
+		('transfer_to_miner_send2',       'transferring funds to Miner (send TX, no proxy)'),
 
 
-		('sweep_create_and_send',     'sweeping to new account (create TX + send TX, in stages)'),
-		('list_wallets_all',          'listing wallets'),
-		('stop_daemons',              'stopping all wallet and coin daemons'),
+		('sweep_create_and_send',         'sweeping to new account (create TX + send TX, in stages)'),
+		('list_wallets_all',              'listing wallets'),
+		('stop_daemons',                  'stopping all wallet and coin daemons'),
 	)
 	)
 
 
-	def __init__(self,trunner,cfgs,spawn):
-		CmdTestBase.__init__(self,trunner,cfgs,spawn)
+	def __init__(self, trunner, cfgs, spawn):
+		CmdTestBase.__init__(self, trunner, cfgs, spawn)
 		if trunner is None:
 		if trunner is None:
 			return
 			return
 
 
 		from mmgen.protocol import init_proto
 		from mmgen.protocol import init_proto
-		self.proto = init_proto( cfg, 'XMR', network='mainnet' )
+		self.proto = init_proto(cfg, 'XMR', network='mainnet')
 		self.extra_opts = ['--wallet-rpc-password=passw0rd']
 		self.extra_opts = ['--wallet-rpc-password=passw0rd']
 		self.init_users()
 		self.init_users()
 		self.init_daemon_args()
 		self.init_daemon_args()
 
 
 		for v in self.users.values():
 		for v in self.users.values():
-			run(['mkdir','-p',v.udir])
+			run(['mkdir', '-p', v.udir])
 
 
-		self.tx_relay_daemon_parm = 'localhost:{}'.format( self.users[self.tx_relay_user].md.rpc_port )
+		self.tx_relay_daemon_parm = 'localhost:{}'.format(self.users[self.tx_relay_user].md.rpc_port)
 		self.tx_relay_daemon_proxy_parm = (
 		self.tx_relay_daemon_proxy_parm = (
-			self.tx_relay_daemon_parm + f':127.0.0.1:{self.socks_port}' ) # must be IP, not 'localhost'
+			self.tx_relay_daemon_parm + f':127.0.0.1:{self.socks_port}') # must be IP, not 'localhost'
 
 
 		if not cfg.no_daemon_stop:
 		if not cfg.no_daemon_stop:
-			atexit.register(stop_daemons,self)
-			atexit.register(stop_miner_wallet_daemon,self)
+			atexit.register(stop_daemons, self)
+			atexit.register(stop_miner_wallet_daemon, self)
 
 
 		if not cfg.no_daemon_autostart:
 		if not cfg.no_daemon_autostart:
 			stop_daemons(self)
 			stop_daemons(self)
@@ -156,12 +156,12 @@ class CmdTestXMRWallet(CmdTestBase):
 	# init methods
 	# init methods
 
 
 	@classmethod
 	@classmethod
-	def init_proxy(cls,external_call=False):
+	def init_proxy(cls, external_call=False):
 
 
 		def port_in_use(port):
 		def port_in_use(port):
 			import socket
 			import socket
 			try:
 			try:
-				socket.create_connection(('localhost',port)).close()
+				socket.create_connection(('localhost', port)).close()
 			except:
 			except:
 				return False
 				return False
 			else:
 			else:
@@ -172,16 +172,16 @@ class CmdTestXMRWallet(CmdTestBase):
 				run(a+b2)
 				run(a+b2)
 				omsg(f'SSH SOCKS server started, listening at localhost:{cls.socks_port}')
 				omsg(f'SSH SOCKS server started, listening at localhost:{cls.socks_port}')
 
 
-		debug_file = os.path.join('' if external_call else cls.datadir_base,'txrelay-proxy.debug')
-		a = ['ssh','-x','-o','ExitOnForwardFailure=True','-D',f'localhost:{cls.socks_port}']
-		b0 = ['-o','PasswordAuthentication=False']
-		b1 = ['localhost','true']
-		b2 = ['-fN','-E', debug_file, 'localhost']
+		debug_file = os.path.join('' if external_call else cls.datadir_base, 'txrelay-proxy.debug')
+		a = ['ssh', '-x', '-o', 'ExitOnForwardFailure=True', '-D', f'localhost:{cls.socks_port}']
+		b0 = ['-o', 'PasswordAuthentication=False']
+		b1 = ['localhost', 'true']
+		b2 = ['-fN', '-E', debug_file, 'localhost']
 
 
 		if port_in_use(cls.socks_port):
 		if port_in_use(cls.socks_port):
 			omsg(f'Port {cls.socks_port} already in use.  Assuming SSH SOCKS server is running')
 			omsg(f'Port {cls.socks_port} already in use.  Assuming SSH SOCKS server is running')
 		else:
 		else:
-			cp = run(a+b0+b1,stdout=PIPE,stderr=PIPE)
+			cp = run(a+b0+b1, stdout=PIPE, stderr=PIPE)
 			err = cp.stderr.decode()
 			err = cp.stderr.decode()
 			if err:
 			if err:
 				omsg(err)
 				omsg(err)
@@ -189,12 +189,12 @@ class CmdTestXMRWallet(CmdTestBase):
 			if cp.returncode == 0:
 			if cp.returncode == 0:
 				start_proxy()
 				start_proxy()
 			elif 'onnection refused' in err:
 			elif 'onnection refused' in err:
-				die(2,fmt("""
+				die(2, fmt("""
 					The SSH daemon must be running and listening on localhost in order to test
 					The SSH daemon must be running and listening on localhost in order to test
 					XMR TX relaying via SOCKS proxy.  If sshd is not running, please start it.
 					XMR TX relaying via SOCKS proxy.  If sshd is not running, please start it.
 					Otherwise, add the line 'ListenAddress 127.0.0.1' to your sshd_config, and
 					Otherwise, add the line 'ListenAddress 127.0.0.1' to your sshd_config, and
 					then restart the daemon.
 					then restart the daemon.
-				""",indent='    '))
+				""", indent='    '))
 			elif 'ermission denied' in err:
 			elif 'ermission denied' in err:
 				msg(fmt(f"""
 				msg(fmt(f"""
 					In order to test XMR TX relaying via SOCKS proxy, it’s desirable to enable
 					In order to test XMR TX relaying via SOCKS proxy, it’s desirable to enable
@@ -211,21 +211,21 @@ class CmdTestXMRWallet(CmdTestBase):
 					   following command, and restart the test:
 					   following command, and restart the test:
 
 
 					      {' '.join(a+b2)}
 					      {' '.join(a+b2)}
-				""",indent='    ',strip_char='\t'))
+				""", indent='    ', strip_char='\t'))
 
 
 				from mmgen.ui import keypress_confirm
 				from mmgen.ui import keypress_confirm
-				if keypress_confirm(cfg,'Continue?'):
+				if keypress_confirm(cfg, 'Continue?'):
 					start_proxy()
 					start_proxy()
 				else:
 				else:
-					die(1,'Exiting at user request')
+					die(1, 'Exiting at user request')
 			else:
 			else:
-				die(2,fmt(f"""
+				die(2, fmt(f"""
 					Please start the SSH SOCKS proxy by entering the following command:
 					Please start the SSH SOCKS proxy by entering the following command:
 
 
 						{' '.join(a+b2)}
 						{' '.join(a+b2)}
 
 
 					Then restart the test.
 					Then restart the test.
-				""",indent='    '))
+				""", indent='    '))
 
 
 		if not (external_call or cfg.no_daemon_stop):
 		if not (external_call or cfg.no_daemon_stop):
 			atexit.unregister(kill_proxy)
 			atexit.unregister(kill_proxy)
@@ -236,10 +236,10 @@ class CmdTestXMRWallet(CmdTestBase):
 	def init_users(self):
 	def init_users(self):
 		from mmgen.daemon import CoinDaemon
 		from mmgen.daemon import CoinDaemon
 		from mmgen.proto.xmr.daemon import MoneroWalletDaemon
 		from mmgen.proto.xmr.daemon import MoneroWalletDaemon
-		from mmgen.proto.xmr.rpc import MoneroRPCClient,MoneroWalletRPCClient
+		from mmgen.proto.xmr.rpc import MoneroRPCClient, MoneroWalletRPCClient
 		self.users = {}
 		self.users = {}
 		tmpdir_num = self.tmpdir_nums[0]
 		tmpdir_num = self.tmpdir_nums[0]
-		ud = namedtuple('user_data',[
+		ud = namedtuple('user_data', [
 			'sid',
 			'sid',
 			'mmwords',
 			'mmwords',
 			'autosign',
 			'autosign',
@@ -256,15 +256,16 @@ class CmdTestXMRWallet(CmdTestBase):
 			'add_coind_args',
 			'add_coind_args',
 		])
 		])
 		# kal_range must be None, a single digit, or a single hyphenated range
 		# kal_range must be None, a single digit, or a single hyphenated range
-		for (   user,
+		for (
+				user,
 				sid,
 				sid,
 				autosign,
 				autosign,
 				shift,
 				shift,
 				kal_range,
 				kal_range,
-				add_coind_args ) in self.user_data:
-			tmpdir = os.path.join('test','tmp',str(tmpdir_num))
-			udir = os.path.join(tmpdir,user)
-			datadir = os.path.join(self.datadir_base,user)
+				add_coind_args) in self.user_data:
+			tmpdir = os.path.join('test', 'tmp', str(tmpdir_num))
+			udir = os.path.join(tmpdir, user)
+			datadir = os.path.join(self.datadir_base, user)
 			md = CoinDaemon(
 			md = CoinDaemon(
 				cfg        = cfg,
 				cfg        = cfg,
 				proto      = self.proto,
 				proto      = self.proto,
@@ -284,13 +285,13 @@ class CmdTestXMRWallet(CmdTestBase):
 				daemon = md,
 				daemon = md,
 			)
 			)
 			wd = MoneroWalletDaemon(
 			wd = MoneroWalletDaemon(
-				cfg        = cfg,
-				proto      = self.proto,
-				test_suite = True,
-				wallet_dir = udir,
-				user       = 'foo',
-				passwd     = 'bar',
-				port_shift = shift,
+				cfg          = cfg,
+				proto        = self.proto,
+				test_suite   = True,
+				wallet_dir   = udir,
+				user         = 'foo',
+				passwd       = 'bar',
+				port_shift   = shift,
 				monerod_addr = f'127.0.0.1:{md.rpc_port}',
 				monerod_addr = f'127.0.0.1:{md.rpc_port}',
 			)
 			)
 			wd_rpc = MoneroWalletRPCClient(
 			wd_rpc = MoneroWalletRPCClient(
@@ -307,53 +308,53 @@ class CmdTestXMRWallet(CmdTestBase):
 				fn_stem    = 'MoneroWallet'
 				fn_stem    = 'MoneroWallet'
 				kafile_dir = udir
 				kafile_dir = udir
 			self.users[user] = ud(
 			self.users[user] = ud(
-				sid           = sid,
-				mmwords       = f'test/ref/{sid}.mmwords',
-				autosign      = autosign,
-				udir          = udir,
-				datadir       = datadir,
-				kal_range     = kal_range,
-				kafile        = f'{kafile_dir}/{sid}-XMR-M[{kal_range}].{kafile_suf}',
-				walletfile_fs = f'{udir}/{sid}-{{}}-{fn_stem}',
-				addrfile_fs   = f'{udir}/{sid}-{{}}-{fn_stem}.address.txt',
-				md            = md,
-				md_rpc        = md_rpc,
-				wd            = wd,
-				wd_rpc        = wd_rpc,
+				sid            = sid,
+				mmwords        = f'test/ref/{sid}.mmwords',
+				autosign       = autosign,
+				udir           = udir,
+				datadir        = datadir,
+				kal_range      = kal_range,
+				kafile         = f'{kafile_dir}/{sid}-XMR-M[{kal_range}].{kafile_suf}',
+				walletfile_fs  = f'{udir}/{sid}-{{}}-{fn_stem}',
+				addrfile_fs    = f'{udir}/{sid}-{{}}-{fn_stem}.address.txt',
+				md             = md,
+				md_rpc         = md_rpc,
+				wd             = wd,
+				wd_rpc         = wd_rpc,
 				add_coind_args = add_coind_args,
 				add_coind_args = add_coind_args,
 			)
 			)
 
 
 	def init_daemon_args(self):
 	def init_daemon_args(self):
-		common_args = ['--p2p-bind-ip=127.0.0.1','--fixed-difficulty=1','--regtest'] # ,'--rpc-ssl-allow-any-cert']
+		common_args = ['--p2p-bind-ip=127.0.0.1', '--fixed-difficulty=1', '--regtest'] # --rpc-ssl-allow-any-cert
 		for u in self.users:
 		for u in self.users:
 			other_ports = [self.users[u2].md.p2p_port for u2 in self.users if u2 != u]
 			other_ports = [self.users[u2].md.p2p_port for u2 in self.users if u2 != u]
 			node_args = [f'--add-exclusive-node=127.0.0.1:{p}' for p in other_ports]
 			node_args = [f'--add-exclusive-node=127.0.0.1:{p}' for p in other_ports]
 			self.users[u].md.usr_coind_args = (
 			self.users[u].md.usr_coind_args = (
-				common_args +
-				node_args +
-				self.users[u].add_coind_args )
+				common_args
+				+ node_args
+				+ self.users[u].add_coind_args)
 
 
 	# cmd_group methods
 	# cmd_group methods
 
 
 	def daemon_version(self):
 	def daemon_version(self):
 		rpc_port = self.users['miner'].md.rpc_port
 		rpc_port = self.users['miner'].md.rpc_port
-		return self.spawn( 'mmgen-tool', ['--coin=xmr', f'--rpc-port={rpc_port}', 'daemon_version'] )
+		return self.spawn('mmgen-tool', ['--coin=xmr', f'--rpc-port={rpc_port}', 'daemon_version'])
 
 
 	def gen_kafiles_miner_alice(self):
 	def gen_kafiles_miner_alice(self):
 		return self.gen_kafiles(['miner', 'alice'])
 		return self.gen_kafiles(['miner', 'alice'])
 
 
 	def gen_kafiles(self, users):
 	def gen_kafiles(self, users):
-		for user,data in self.users.items():
+		for user, data in self.users.items():
 			if not user in users:
 			if not user in users:
 				continue
 				continue
-			run(['mkdir','-p',data.udir])
-			run(f'rm -f {data.kafile}',shell=True)
+			run(['mkdir', '-p', data.udir])
+			run(f'rm -f {data.kafile}', shell=True)
 			t = self.spawn(
 			t = self.spawn(
 				'mmgen-keygen', [
 				'mmgen-keygen', [
 					'-q', '--accept-defaults', '--coin=xmr',
 					'-q', '--accept-defaults', '--coin=xmr',
 					f'--outdir={data.udir}', data.mmwords, data.kal_range
 					f'--outdir={data.udir}', data.mmwords, data.kal_range
 				],
 				],
-				extra_desc = f'({capfirst(user)})' )
+				extra_desc = f'({capfirst(user)})')
 			t.read()
 			t.read()
 			t.ok()
 			t.ok()
 		t.skip_ok = True
 		t.skip_ok = True
@@ -365,15 +366,15 @@ class CmdTestXMRWallet(CmdTestBase):
 	def create_wallets_alice(self):
 	def create_wallets_alice(self):
 		return self.create_wallets('alice')
 		return self.create_wallets('alice')
 
 
-	def create_wallets(self,user,wallet=None,add_opts=[],op='create'):
+	def create_wallets(self, user, wallet=None, add_opts=[], op='create'):
 		assert wallet is None or is_int(wallet), 'wallet arg'
 		assert wallet is None or is_int(wallet), 'wallet arg'
 		data = self.users[user]
 		data = self.users[user]
 		stem_glob = data.walletfile_fs.format(wallet or '*')
 		stem_glob = data.walletfile_fs.format(wallet or '*')
 		for glob in (
 		for glob in (
 				stem_glob,
 				stem_glob,
 				stem_glob + '.keys',
 				stem_glob + '.keys',
-				stem_glob + '.address.txt' ):
-			run( f'rm -f {glob}', shell=True )
+				stem_glob + '.address.txt'):
+			run(f'rm -f {glob}', shell=True)
 		t = self.spawn(
 		t = self.spawn(
 			'mmgen-xmrwallet',
 			'mmgen-xmrwallet',
 			[f'--wallet-dir={data.udir}']
 			[f'--wallet-dir={data.udir}']
@@ -393,15 +394,15 @@ class CmdTestXMRWallet(CmdTestBase):
 			)
 			)
 		return t
 		return t
 
 
-	def new_addr_alice(self,spec,cfg,expect,kafile=None):
+	def new_addr_alice(self, spec, cfg, expect, kafile=None):
 		data = self.users['alice']
 		data = self.users['alice']
 		t = self.spawn(
 		t = self.spawn(
 			'mmgen-xmrwallet',
 			'mmgen-xmrwallet',
 			self.extra_opts
 			self.extra_opts
 			+ [f'--wallet-dir={data.udir}']
 			+ [f'--wallet-dir={data.udir}']
 			+ [f'--daemon=localhost:{data.md.rpc_port}']
 			+ [f'--daemon=localhost:{data.md.rpc_port}']
-			+ (['--no-start-wallet-daemon'] if cfg in ('continue','stop') else [])
-			+ (['--no-stop-wallet-daemon'] if cfg in ('start','continue') else [])
+			+ (['--no-start-wallet-daemon'] if cfg in ('continue', 'stop') else [])
+			+ (['--no-stop-wallet-daemon'] if cfg in ('start', 'continue') else [])
 			+ ['new', (kafile or data.kafile), spec])
 			+ ['new', (kafile or data.kafile), spec])
 		t.expect(expect, 'y', regex=True)
 		t.expect(expect, 'y', regex=True)
 		return t
 		return t
@@ -434,10 +435,10 @@ class CmdTestXMRWallet(CmdTestBase):
 
 
 	async def mine_initial_coins(self):
 	async def mine_initial_coins(self):
 		self.spawn('', msg_only=True, extra_desc='(opening wallet)')
 		self.spawn('', msg_only=True, extra_desc='(opening wallet)')
-		await self.open_wallet_user('miner',1)
+		await self.open_wallet_user('miner', 1)
 		ok()
 		ok()
 		# NB: a large balance is required to avoid ‘insufficient outputs’ error
 		# NB: a large balance is required to avoid ‘insufficient outputs’ error
-		return await self.mine_chk('miner',1,0,lambda x: x.ub > 2000,'unlocked balance > 2000')
+		return await self.mine_chk('miner', 1, 0, lambda x: x.ub > 2000, 'unlocked balance > 2000')
 
 
 	async def fund_alice(self, wallet=1, amt=1234567891234):
 	async def fund_alice(self, wallet=1, amt=1234567891234):
 		self.spawn('', msg_only=True, extra_desc='(transferring funds from Miner wallet)')
 		self.spawn('', msg_only=True, extra_desc='(transferring funds from Miner wallet)')
@@ -451,7 +452,7 @@ class CmdTestXMRWallet(CmdTestBase):
 	async def check_bal_alice(self, wallet=1, bal='1.234567891234'):
 	async def check_bal_alice(self, wallet=1, bal='1.234567891234'):
 		return await self.mine_chk(
 		return await self.mine_chk(
 			'alice', wallet, 0,
 			'alice', wallet, 0,
-			lambda x: str(x.ub) == bal,f'unlocked balance == {bal}',
+			lambda x: str(x.ub) == bal, f'unlocked balance == {bal}',
 			random_txs = self.dfl_random_txs
 			random_txs = self.dfl_random_txs
 		)
 		)
 
 
@@ -474,7 +475,7 @@ class CmdTestXMRWallet(CmdTestBase):
 			+ cmd_opts
 			+ cmd_opts
 			+ ['label', data.kafile, label_spec]
 			+ ['label', data.kafile, label_spec]
 		)
 		)
-		t.expect('(y/N): ','y')
+		t.expect('(y/N): ', 'y')
 		t.expect(f'Label successfully {expect}')
 		t.expect(f'Label successfully {expect}')
 		return t
 		return t
 
 
@@ -496,7 +497,7 @@ class CmdTestXMRWallet(CmdTestBase):
 	def sync_wallets_miner(self):
 	def sync_wallets_miner(self):
 		return self.sync_wallets('miner')
 		return self.sync_wallets('miner')
 
 
-	def sync_wallets(self,user,op='sync',wallets=None,add_opts=[],bal_chk_func=None):
+	def sync_wallets(self, user, op='sync', wallets=None, add_opts=[], bal_chk_func=None):
 		data = self.users[user]
 		data = self.users[user]
 		if data.autosign:
 		if data.autosign:
 			self.insert_device_online()
 			self.insert_device_online()
@@ -515,22 +516,22 @@ class CmdTestXMRWallet(CmdTestBase):
 			+ ([wallets] if wallets else [])
 			+ ([wallets] if wallets else [])
 		)
 		)
 		wlist = AddrIdxList(wallets) if wallets else MMGenRange(data.kal_range).items
 		wlist = AddrIdxList(wallets) if wallets else MMGenRange(data.kal_range).items
-		for n,wnum in enumerate(wlist,1):
+		for n, wnum in enumerate(wlist, 1):
 			t.expect('ing wallet {}/{} ({})'.format(
 			t.expect('ing wallet {}/{} ({})'.format(
 				n,
 				n,
 				len(wlist),
 				len(wlist),
 				os.path.basename(data.walletfile_fs.format(wnum)),
 				os.path.basename(data.walletfile_fs.format(wnum)),
 			))
 			))
-			if op in ('view','listview'):
+			if op in ('view', 'listview'):
 				t.expect('Wallet height: ')
 				t.expect('Wallet height: ')
 			else:
 			else:
 				t.expect('Chain height: ')
 				t.expect('Chain height: ')
 				t.expect('Wallet height: ')
 				t.expect('Wallet height: ')
 				res = strip_ansi_escapes(t.expect_getend('Balance: '))
 				res = strip_ansi_escapes(t.expect_getend('Balance: '))
 				if bal_chk_func:
 				if bal_chk_func:
-					m = re.match( r'(\S+) Unlocked balance: (\S+)', res, re.DOTALL )
+					m = re.match(r'(\S+) Unlocked balance: (\S+)', res, re.DOTALL)
 					amts = [XMRAmt(amt) for amt in m.groups()]
 					amts = [XMRAmt(amt) for amt in m.groups()]
-					assert bal_chk_func(n,*amts), f'balance check for wallet {n} failed!'
+					assert bal_chk_func(n, *amts), f'balance check for wallet {n} failed!'
 		if data.autosign:
 		if data.autosign:
 			t.read()
 			t.read()
 			self.remove_device_online()
 			self.remove_device_online()
@@ -567,27 +568,24 @@ class CmdTestXMRWallet(CmdTestBase):
 			+ [op]
 			+ [op]
 			+ ([] if data.autosign else [data.kafile])
 			+ ([] if data.autosign else [data.kafile])
 			+ [arg2],
 			+ [arg2],
-			extra_desc = f'({capfirst(user)}{add_desc})' )
+			extra_desc = f'({capfirst(user)}{add_desc})')
 
 
 		if op == 'sign':
 		if op == 'sign':
 			return t
 			return t
 
 
 		if op in ('sweep', 'sweep_all'):
 		if op in ('sweep', 'sweep_all'):
 			desc = 'address' if re.match(r'.*:\d+$', arg2) else 'account'
 			desc = 'address' if re.match(r'.*:\d+$', arg2) else 'account'
-			t.expect(
-				rf'Create new {desc} .* \(y/N\): ',
-				('y','n')[use_existing],
-				regex=True )
+			t.expect(rf'Create new {desc} .* \(y/N\): ', ('y', 'n')[use_existing], regex=True)
 			if use_existing:
 			if use_existing:
 				t.expect(rf'to last existing {desc} .* \(y/N\): ', 'y', regex=True)
 				t.expect(rf'to last existing {desc} .* \(y/N\): ', 'y', regex=True)
 
 
 		dtype = 'unsigned' if data.autosign else 'signed'
 		dtype = 'unsigned' if data.autosign else 'signed'
-		t.expect(f'Save {dtype} transaction? (y/N): ','y')
+		t.expect(f'Save {dtype} transaction? (y/N): ', 'y')
 		t.written_to_file(f'{dtype.capitalize()} transaction')
 		t.written_to_file(f'{dtype.capitalize()} transaction')
 
 
 		if not no_relay:
 		if not no_relay:
-			t.expect(f'Relay {op} transaction? (y/N): ','y')
-			get_file_with_ext(self.users[user].udir,'sigtx',delete_all=True)
+			t.expect(f'Relay {op} transaction? (y/N): ', 'y')
+			get_file_with_ext(self.users[user].udir, 'sigtx', delete_all=True)
 
 
 		t.read()
 		t.read()
 
 
@@ -616,22 +614,22 @@ class CmdTestXMRWallet(CmdTestBase):
 	async def transfer_to_miner_proxy(self):
 	async def transfer_to_miner_proxy(self):
 		addr = read_from_file(self.users['miner'].addrfile_fs.format(2))
 		addr = read_from_file(self.users['miner'].addrfile_fs.format(2))
 		amt = '0.135'
 		amt = '0.135'
-		self.do_op('transfer','alice',f'2:1:{addr},{amt}',self.tx_relay_daemon_proxy_parm)
+		self.do_op('transfer', 'alice', f'2:1:{addr},{amt}', self.tx_relay_daemon_proxy_parm)
 		await self.stop_wallet_user('miner')
 		await self.stop_wallet_user('miner')
-		await self.open_wallet_user('miner',2)
-		await self.mine_chk('miner',2,0,lambda x: str(x.ub) == amt,f'unlocked balance == {amt}')
+		await self.open_wallet_user('miner', 2)
+		await self.mine_chk('miner', 2, 0, lambda x: str(x.ub) == amt, f'unlocked balance == {amt}')
 		ok()
 		ok()
-		return await self.mine_chk('alice',2,1,lambda x: x.ub > 0.9,'unlocked balance > 0.9')
+		return await self.mine_chk('alice', 2, 1, lambda x: x.ub > 0.9, 'unlocked balance > 0.9')
 
 
 	async def transfer_to_miner_noproxy(self):
 	async def transfer_to_miner_noproxy(self):
 		addr = read_from_file(self.users['miner'].addrfile_fs.format(2))
 		addr = read_from_file(self.users['miner'].addrfile_fs.format(2))
 		self.do_op('transfer', 'alice', f'2:1:{addr},0.0995', self.tx_relay_daemon_parm, add_opts=['--full-address'])
 		self.do_op('transfer', 'alice', f'2:1:{addr},0.0995', self.tx_relay_daemon_parm, add_opts=['--full-address'])
-		await self.mine_chk('miner',2,0,lambda x: str(x.ub) == '0.2345','unlocked balance == 0.2345')
+		await self.mine_chk('miner', 2, 0, lambda x: str(x.ub) == '0.2345', 'unlocked balance == 0.2345')
 		ok()
 		ok()
-		return await self.mine_chk('alice',2,1,lambda x: x.ub > 0.9,'unlocked balance > 0.9')
+		return await self.mine_chk('alice', 2, 1, lambda x: x.ub > 0.9, 'unlocked balance > 0.9')
 
 
-	def transfer_to_miner_create(self,amt):
-		get_file_with_ext(self.users['alice'].udir,'sigtx',delete_all=True)
+	def transfer_to_miner_create(self, amt):
+		get_file_with_ext(self.users['alice'].udir, 'sigtx', delete_all=True)
 		addr = read_from_file(self.users['miner'].addrfile_fs.format(2))
 		addr = read_from_file(self.users['miner'].addrfile_fs.format(2))
 		return self.do_op('transfer', 'alice', f'2:1:{addr},{amt}', no_relay=True, do_ret=True, add_opts=['-Ee'])
 		return self.do_op('transfer', 'alice', f'2:1:{addr},{amt}', no_relay=True, do_ret=True, add_opts=['-Ee'])
 
 
@@ -641,31 +639,31 @@ class CmdTestXMRWallet(CmdTestBase):
 	def transfer_to_miner_create2(self):
 	def transfer_to_miner_create2(self):
 		return self.transfer_to_miner_create('0.0012')
 		return self.transfer_to_miner_create('0.0012')
 
 
-	def relay_tx(self,relay_opt,add_desc=None):
+	def relay_tx(self, relay_opt, add_desc=None):
 		user = 'alice'
 		user = 'alice'
 		data = self.users[user]
 		data = self.users[user]
 		add_desc = (', ' + add_desc) if add_desc else ''
 		add_desc = (', ' + add_desc) if add_desc else ''
 		t = self.spawn(
 		t = self.spawn(
 			'mmgen-xmrwallet',
 			'mmgen-xmrwallet',
 			self.extra_opts
 			self.extra_opts
-			+ [ relay_opt, 'relay', get_file_with_ext(data.udir,'sigtx') ],
-			extra_desc = f'(relaying TX, {capfirst(user)}{add_desc})' )
-		t.expect('Relay transaction? ','y')
+			+ [relay_opt, 'relay', get_file_with_ext(data.udir, 'sigtx')],
+			extra_desc = f'(relaying TX, {capfirst(user)}{add_desc})')
+		t.expect('Relay transaction? ', 'y')
 		t.read()
 		t.read()
 		t.ok()
 		t.ok()
 		return t
 		return t
 
 
 	async def transfer_to_miner_send1(self):
 	async def transfer_to_miner_send1(self):
-		self.relay_tx(f'--tx-relay-daemon={self.tx_relay_daemon_proxy_parm}',add_desc='via proxy')
-		await self.mine_chk('miner',2,0,lambda x: str(x.ub) == '0.2456','unlocked balance == 0.2456')
+		self.relay_tx(f'--tx-relay-daemon={self.tx_relay_daemon_proxy_parm}', add_desc='via proxy')
+		await self.mine_chk('miner', 2, 0, lambda x: str(x.ub) == '0.2456', 'unlocked balance == 0.2456')
 		ok()
 		ok()
-		return await self.mine_chk('alice',2,1,lambda x: x.ub > 0.9,'unlocked balance > 0.9')
+		return await self.mine_chk('alice', 2, 1, lambda x: x.ub > 0.9, 'unlocked balance > 0.9')
 
 
 	async def transfer_to_miner_send2(self):
 	async def transfer_to_miner_send2(self):
-		self.relay_tx(f'--tx-relay-daemon={self.tx_relay_daemon_parm}',add_desc='no proxy')
-		await self.mine_chk('miner',2,0,lambda x: str(x.ub) == '0.2468','unlocked balance == 0.2468')
+		self.relay_tx(f'--tx-relay-daemon={self.tx_relay_daemon_parm}', add_desc='no proxy')
+		await self.mine_chk('miner', 2, 0, lambda x: str(x.ub) == '0.2468', 'unlocked balance == 0.2468')
 		ok()
 		ok()
-		return await self.mine_chk('alice',2,1,lambda x: x.ub > 0.9,'unlocked balance > 0.9')
+		return await self.mine_chk('alice', 2, 1, lambda x: x.ub > 0.9, 'unlocked balance > 0.9')
 
 
 	async def sweep_create_and_send(self):
 	async def sweep_create_and_send(self):
 		get_file_with_ext(self.users['alice'].udir, 'sigtx', delete_all=True)
 		get_file_with_ext(self.users['alice'].udir, 'sigtx', delete_all=True)
@@ -680,7 +678,7 @@ class CmdTestXMRWallet(CmdTestBase):
 
 
 	# wallet methods
 	# wallet methods
 
 
-	async def open_wallet_user(self,user,wnum):
+	async def open_wallet_user(self, user, wnum):
 		data = self.users[user]
 		data = self.users[user]
 		if data.autosign:
 		if data.autosign:
 			self.insert_device_online()
 			self.insert_device_online()
@@ -691,7 +689,7 @@ class CmdTestXMRWallet(CmdTestBase):
 			proto    = self.proto,
 			proto    = self.proto,
 			addrfile = data.kafile,
 			addrfile = data.kafile,
 			skip_chksum_msg = True,
 			skip_chksum_msg = True,
-			key_address_validity_check = False )
+			key_address_validity_check = False)
 		end_silence()
 		end_silence()
 		if data.autosign:
 		if data.autosign:
 			self.do_umount_online()
 			self.do_umount_online()
@@ -700,9 +698,9 @@ class CmdTestXMRWallet(CmdTestBase):
 		return data.wd_rpc.call(
 		return data.wd_rpc.call(
 			'open_wallet',
 			'open_wallet',
 			filename = os.path.basename(data.walletfile_fs.format(wnum)),
 			filename = os.path.basename(data.walletfile_fs.format(wnum)),
-			password = kal.entry(wnum).wallet_passwd )
+			password = kal.entry(wnum).wallet_passwd)
 
 
-	async def stop_wallet_user(self,user):
+	async def stop_wallet_user(self, user):
 		await self.users[user].wd_rpc.stop_daemon(silent=not (cfg.exact_output or cfg.verbose))
 		await self.users[user].wd_rpc.stop_daemon(silent=not (cfg.exact_output or cfg.verbose))
 		return 'ok'
 		return 'ok'
 
 
@@ -725,7 +723,7 @@ class CmdTestXMRWallet(CmdTestBase):
 					await self.start_mining()
 					await self.start_mining()
 				else:
 				else:
 					raise
 					raise
-		die(2,'Restart attempt limit exceeded')
+		die(2, 'Restart attempt limit exceeded')
 
 
 	async def mine10(self):
 	async def mine10(self):
 		return await self.mine(10)
 		return await self.mine(10)
@@ -736,7 +734,7 @@ class CmdTestXMRWallet(CmdTestBase):
 	async def mine100(self):
 	async def mine100(self):
 		return await self.mine(100)
 		return await self.mine(100)
 
 
-	async def mine(self,nblks):
+	async def mine(self, nblks):
 		start_height = height = await self._get_height()
 		start_height = height = await self._get_height()
 		imsg(f'Height: {height}')
 		imsg(f'Height: {height}')
 		imsg_r(f'Mining {nblks} blocks...')
 		imsg_r(f'Mining {nblks} blocks...')
@@ -761,7 +759,7 @@ class CmdTestXMRWallet(CmdTestBase):
 				do_background_mining = False, # run mining in background or foreground
 				do_background_mining = False, # run mining in background or foreground
 				ignore_battery       = True,  # ignore battery state (on laptop)
 				ignore_battery       = True,  # ignore battery state (on laptop)
 				miner_address        = addr,  # account address to mine to
 				miner_address        = addr,  # account address to mine to
-				threads_count        = 1 )    # number of mining threads to run
+				threads_count        = 1)    # number of mining threads to run
 			status = self.get_status(ret)
 			status = self.get_status(ret)
 			if status == 'OK':
 			if status == 'OK':
 				return True
 				return True
@@ -769,8 +767,8 @@ class CmdTestXMRWallet(CmdTestBase):
 				await asyncio.sleep(5)
 				await asyncio.sleep(5)
 				omsg('Daemon busy.  Attempting to start mining...')
 				omsg('Daemon busy.  Attempting to start mining...')
 			else:
 			else:
-				die(2,f'Monerod returned status {status}')
-		die(2,'Max retries exceeded')
+				die(2, f'Monerod returned status {status}')
+		die(2, 'Max retries exceeded')
 
 
 	async def stop_mining(self):
 	async def stop_mining(self):
 		ret = self.users['miner'].md_rpc.call_raw('stop_mining')
 		ret = self.users['miner'].md_rpc.call_raw('stop_mining')
@@ -786,7 +784,7 @@ class CmdTestXMRWallet(CmdTestBase):
 			test2      = None,
 			test2      = None,
 			test2_desc = None,
 			test2_desc = None,
 			random_txs = None,
 			random_txs = None,
-			return_bal = False ):
+			return_bal = False):
 
 
 		"""
 		"""
 		- open destination wallet
 		- open destination wallet
@@ -800,7 +798,7 @@ class CmdTestXMRWallet(CmdTestBase):
 		async def send_random_txs():
 		async def send_random_txs():
 			from mmgen.tool.api import tool_api
 			from mmgen.tool.api import tool_api
 			t = tool_api(cfg)
 			t = tool_api(cfg)
-			t.init_coin('XMR','mainnet')
+			t.init_coin('XMR', 'mainnet')
 			t.usr_randchars = 0
 			t.usr_randchars = 0
 			imsg_r('Sending random transactions: ')
 			imsg_r('Sending random transactions: ')
 			for i in range(random_txs):
 			for i in range(random_txs):
@@ -814,7 +812,7 @@ class CmdTestXMRWallet(CmdTestBase):
 				await asyncio.sleep(0.5)
 				await asyncio.sleep(0.5)
 			imsg('')
 			imsg('')
 
 
-		def print_balance(dest,bal_info):
+		def print_balance(dest, bal_info):
 			imsg('Total balances in {}’s wallet {}, account #{}: {} (total), {} (unlocked)'.format(
 			imsg('Total balances in {}’s wallet {}, account #{}: {} (total), {} (unlocked)'.format(
 				capfirst(dest.user),
 				capfirst(dest.user),
 				dest.wnum,
 				dest.wnum,
@@ -823,32 +821,31 @@ class CmdTestXMRWallet(CmdTestBase):
 				bal_info.ub.hl(),
 				bal_info.ub.hl(),
 			))
 			))
 
 
-		async def get_balance(dest,count):
+		async def get_balance(dest, count):
 			data = self.users[dest.user]
 			data = self.users[dest.user]
 			data.wd_rpc.call('refresh')
 			data.wd_rpc.call('refresh')
 			if count and not count % 20:
 			if count and not count % 20:
 				data.wd_rpc.call('rescan_blockchain')
 				data.wd_rpc.call('rescan_blockchain')
 			ret = data.wd_rpc.call('get_accounts')['subaddress_accounts'][dest.account]
 			ret = data.wd_rpc.call('get_accounts')['subaddress_accounts'][dest.account]
-			d_tup = namedtuple('bal_info',['b','ub'])
+			d_tup = namedtuple('bal_info', ['b', 'ub'])
 			return d_tup(
 			return d_tup(
-				b  = XMRAmt(ret['balance'],from_unit='atomic'),
-				ub = XMRAmt(ret['unlocked_balance'],from_unit='atomic')
-			)
+				b  = XMRAmt(ret['balance'], from_unit='atomic'),
+				ub = XMRAmt(ret['unlocked_balance'], from_unit='atomic'))
 
 
 		# start execution:
 		# start execution:
 
 
 		self.do_msg(extra_desc =
 		self.do_msg(extra_desc =
 			(f'sending {random_txs} random TXs, ' if random_txs else '') +
 			(f'sending {random_txs} random TXs, ' if random_txs else '') +
-			f'mining, checking wallet {user}:{wnum}:{account}' )
+			f'mining, checking wallet {user}:{wnum}:{account}')
 
 
 		dest = namedtuple(
 		dest = namedtuple(
-			'dest_info',['user','wnum','account','test','test_desc','test2','test2_desc'])(
-				user,wnum,account,test,test_desc,test2,test2_desc)
+			'dest_info', ['user', 'wnum', 'account', 'test', 'test_desc', 'test2', 'test2_desc'])(
+				user, wnum, account, test, test_desc, test2, test2_desc)
 
 
 		if dest.user != 'miner':
 		if dest.user != 'miner':
-			await self.open_wallet_user(dest.user,dest.wnum)
+			await self.open_wallet_user(dest.user, dest.wnum)
 
 
-		bal_info_start = await get_balance(dest,0)
+		bal_info_start = await get_balance(dest, 0)
 		chk_bal_chg = dest.test(bal_info_start) == 'chk_bal_chg'
 		chk_bal_chg = dest.test(bal_info_start) == 'chk_bal_chg'
 
 
 		if random_txs:
 		if random_txs:
@@ -859,16 +856,16 @@ class CmdTestXMRWallet(CmdTestBase):
 		h = await self._get_height()
 		h = await self._get_height()
 		imsg_r(f'Chain height: {h} ')
 		imsg_r(f'Chain height: {h} ')
 
 
-		max_iterations,min_height = (300,64) if sys.platform == 'win32' else (50,300)
+		max_iterations, min_height = (300, 64) if sys.platform == 'win32' else (50, 300)
 		verbose = False
 		verbose = False
 
 
 		for count in range(max_iterations):
 		for count in range(max_iterations):
-			bal_info = await get_balance(dest,count)
+			bal_info = await get_balance(dest, count)
 			if h > min_height:
 			if h > min_height:
 				if dest.test(bal_info) is True or (chk_bal_chg and bal_info.ub != bal_info_start.ub):
 				if dest.test(bal_info) is True or (chk_bal_chg and bal_info.ub != bal_info_start.ub):
 					imsg('')
 					imsg('')
 					oqmsg_r('+')
 					oqmsg_r('+')
-					print_balance(dest,bal_info)
+					print_balance(dest, bal_info)
 					if dest.test2:
 					if dest.test2:
 						assert dest.test2(bal_info) is True, f'test failed: {dest.test2_desc} ({bal_info})'
 						assert dest.test2(bal_info) is True, f'test failed: {dest.test2_desc} ({bal_info})'
 					break
 					break
@@ -878,13 +875,13 @@ class CmdTestXMRWallet(CmdTestBase):
 				if not verbose:
 				if not verbose:
 					imsg('')
 					imsg('')
 				imsg_r(f'Height: {h}, ')
 				imsg_r(f'Height: {h}, ')
-				print_balance(dest,bal_info)
+				print_balance(dest, bal_info)
 				verbose = True
 				verbose = True
 			else:
 			else:
 				imsg_r(f'{h} ')
 				imsg_r(f'{h} ')
 				oqmsg_r('+')
 				oqmsg_r('+')
 		else:
 		else:
-			die(2,f'Timeout exceeded, balance {bal_info.ub!r}')
+			die(2, f'Timeout exceeded, balance {bal_info.ub!r}')
 
 
 		await self.stop_mining()
 		await self.stop_mining()
 
 
@@ -895,26 +892,26 @@ class CmdTestXMRWallet(CmdTestBase):
 
 
 	# util methods
 	# util methods
 
 
-	def get_status(self,ret):
+	def get_status(self, ret):
 		if ret['status'] != 'OK':
 		if ret['status'] != 'OK':
-			imsg( 'RPC status: {}'.format( ret['status'] ))
+			imsg('RPC status: {}'.format(ret['status']))
 		return ret['status']
 		return ret['status']
 
 
-	def do_msg(self,extra_desc=None):
+	def do_msg(self, extra_desc=None):
 		self.spawn(
 		self.spawn(
 			'',
 			'',
 			msg_only = True,
 			msg_only = True,
 			extra_desc = f'({extra_desc})' if extra_desc else None
 			extra_desc = f'({extra_desc})' if extra_desc else None
 		)
 		)
 
 
-	async def transfer(self,user,amt,addr):
-		return self.users[user].wd_rpc.call('transfer',destinations=[{'amount':amt,'address':addr}])
+	async def transfer(self, user, amt, addr):
+		return self.users[user].wd_rpc.call('transfer', destinations=[{'amount':amt, 'address':addr}])
 
 
 	# daemon start/stop methods
 	# daemon start/stop methods
 
 
 	def start_daemons(self):
 	def start_daemons(self):
 		for v in self.users.values():
 		for v in self.users.values():
-			run(['mkdir','-p',v.datadir])
+			run(['mkdir', '-p', v.datadir])
 			v.md.start()
 			v.md.start()
 
 
 	def stop_daemons(self):
 	def stop_daemons(self):

+ 12 - 12
test/cmdtest_py_d/input.py

@@ -14,13 +14,13 @@ import time
 from .common import randbool
 from .common import randbool
 from ..include.common import getrand
 from ..include.common import getrand
 
 
-def stealth_mnemonic_entry(t,mne,mn,entry_mode,pad_entry=False):
+def stealth_mnemonic_entry(t, mne, mn, entry_mode, pad_entry=False):
 
 
-	def pad_mnemonic(mn,ss_len):
+	def pad_mnemonic(mn, ss_len):
 		def get_pad_chars(n):
 		def get_pad_chars(n):
 			ret = ''
 			ret = ''
 			for _ in range(n):
 			for _ in range(n):
-				m = int.from_bytes(getrand(1),'big') % 32
+				m = int.from_bytes(getrand(1), 'big') % 32
 				ret += r'123579!@#$%^&*()_+-=[]{}"?/,.<>|'[m]
 				ret += r'123579!@#$%^&*()_+-=[]{}"?/,.<>|'[m]
 			return ret
 			return ret
 		ret = []
 		ret = []
@@ -36,13 +36,13 @@ def stealth_mnemonic_entry(t,mne,mn,entry_mode,pad_entry=False):
 						w += '\n'
 						w += '\n'
 				else:
 				else:
 					w = get_pad_chars(1) + w[0] + get_pad_chars(1) + w[1:]
 					w = get_pad_chars(1) + w[0] + get_pad_chars(1) + w[1:]
-			elif len(w) > (3,5)[ss_len==12]:
+			elif len(w) > (3, 5)[ss_len==12]:
 				w = w + '\n'
 				w = w + '\n'
 			else:
 			else:
 				w = (
 				w = (
 					get_pad_chars(2 if randbool() and entry_mode != 'short' else 0)
 					get_pad_chars(2 if randbool() and entry_mode != 'short' else 0)
 					+ w[0] + get_pad_chars(2) + w[1:]
 					+ w[0] + get_pad_chars(2) + w[1:]
-					+ get_pad_chars(9) )
+					+ get_pad_chars(9))
 				w = w[:ss_len+1]
 				w = w[:ss_len+1]
 			ret.append(w)
 			ret.append(w)
 		return ret
 		return ret
@@ -57,22 +57,22 @@ def stealth_mnemonic_entry(t,mne,mn,entry_mode,pad_entry=False):
 				else:
 				else:
 					yield w[0] + 'z\b' + '#' * (ssl-len(w)) + w[1:]
 					yield w[0] + 'z\b' + '#' * (ssl-len(w)) + w[1:]
 		mn = list(gen_mn())
 		mn = list(gen_mn())
-	elif entry_mode in ('full','short'):
-		mn = ['fzr'] + mn[:5] + ['grd','grdbxm'] + mn[5:]
-		mn = pad_mnemonic(mn,mne.em.ss_len)
+	elif entry_mode in ('full', 'short'):
+		mn = ['fzr'] + mn[:5] + ['grd', 'grdbxm'] + mn[5:]
+		mn = pad_mnemonic(mn, mne.em.ss_len)
 		mn[10] = '@#$%*##' + mn[10]
 		mn[10] = '@#$%*##' + mn[10]
 
 
 	wnum = 1
 	wnum = 1
-	p_ok,p_err = mne.word_prompt
+	p_ok, p_err = mne.word_prompt
 	for w in mn:
 	for w in mn:
-		ret = t.expect((p_ok.format(wnum),p_err.format(wnum-1)))
+		ret = t.expect((p_ok.format(wnum), p_err.format(wnum-1)))
 		if ret == 0:
 		if ret == 0:
 			wnum += 1
 			wnum += 1
 		for char in w:
 		for char in w:
 			t.send(char)
 			t.send(char)
 			time.sleep(0.005)
 			time.sleep(0.005)
 
 
-def user_dieroll_entry(t,data):
+def user_dieroll_entry(t, data):
 	for s in data:
 	for s in data:
-		t.expect(r'Enter die roll #.+: ',s,regex=True)
+		t.expect(r'Enter die roll #.+: ', s, regex=True)
 		time.sleep(0.005)
 		time.sleep(0.005)

Some files were not shown because too many files changed in this diff