From 89ad0fd29b4fcdb186ce4ad10c57f6c58bdbdbb3 Mon Sep 17 00:00:00 2001 From: The MMGen Project Date: Sat, 15 Mar 2025 18:24:52 +0000 Subject: [PATCH] keyword-only parameters throughout --- mmgen/addr.py | 6 +++--- mmgen/addrfile.py | 7 ++++--- mmgen/addrlist.py | 1 + mmgen/altcoin/params.py | 4 ++-- mmgen/amt.py | 10 +++++----- mmgen/autosign.py | 18 +++++++++--------- mmgen/baseconv.py | 12 ++++++------ mmgen/bip39.py | 8 ++++---- mmgen/bip_hd/__init__.py | 16 +++++++++------- mmgen/cfg.py | 5 +++-- mmgen/crypto.py | 6 ++++-- mmgen/daemon.py | 10 ++++++---- mmgen/devtools.py | 2 +- mmgen/filename.py | 16 ++++++++-------- mmgen/fileutil.py | 17 ++++++++++------- mmgen/help/help_notes.py | 2 +- mmgen/help/txsign.py | 2 +- mmgen/keygen.py | 4 ++-- mmgen/led.py | 2 +- mmgen/main_addrgen.py | 4 ++-- mmgen/main_addrimport.py | 4 ++-- mmgen/main_passgen.py | 4 ++-- mmgen/main_seedjoin.py | 2 +- mmgen/main_tool.py | 11 +++++++---- mmgen/main_wallet.py | 4 ++-- mmgen/mn_entry.py | 2 +- mmgen/msg.py | 2 +- mmgen/obj.py | 10 +++++----- mmgen/objmethods.py | 17 +++++++++-------- mmgen/passwdlist.py | 1 + mmgen/platform/darwin/util.py | 4 ++-- mmgen/proto/btc/regtest.py | 12 ++++++------ mmgen/proto/btc/rpc.py | 6 ++++-- mmgen/proto/btc/tw/ctl.py | 2 +- mmgen/proto/btc/tx/base.py | 4 ++-- mmgen/proto/btc/tx/info.py | 2 +- mmgen/proto/btc/tx/online.py | 2 +- mmgen/proto/btc/tx/op_return_data.py | 2 +- mmgen/proto/eth/contract.py | 2 +- mmgen/proto/eth/daemon.py | 6 +++--- mmgen/proto/eth/misc.py | 2 +- mmgen/proto/eth/tw/ctl.py | 10 +++++----- mmgen/proto/eth/tw/json.py | 2 +- mmgen/proto/eth/tw/unspent.py | 2 +- mmgen/proto/eth/tx/online.py | 2 +- mmgen/proto/secp256k1/keygen.py | 4 ++-- mmgen/proto/xmr/daemon.py | 1 + mmgen/proto/xmr/rpc.py | 9 +++++---- mmgen/protocol.py | 5 +++-- mmgen/rpc.py | 13 +++++++------ mmgen/seedsplit.py | 10 +++++----- mmgen/sha2.py | 2 +- mmgen/subseed.py | 4 ++-- mmgen/term.py | 16 ++++++++-------- mmgen/tool/coin.py | 2 +- mmgen/tool/file.py | 2 +- mmgen/tool/filecrypt.py | 8 ++++---- mmgen/tool/fileutil.py | 9 +++++---- mmgen/tool/mnemonic.py | 6 ++++-- mmgen/tool/rpc.py | 13 +++++++------ mmgen/tool/util.py | 11 +++++++---- mmgen/tool/wallet.py | 14 ++++++++------ mmgen/tw/addresses.py | 2 +- mmgen/tw/ctl.py | 14 ++++++++------ mmgen/tw/json.py | 7 +++++-- mmgen/tw/view.py | 7 ++++--- mmgen/tx/base.py | 3 ++- mmgen/tx/file.py | 8 ++++---- mmgen/tx/info.py | 6 +++--- mmgen/tx/new.py | 8 ++++---- mmgen/tx/sign.py | 8 ++++---- mmgen/ui.py | 5 +++-- mmgen/util.py | 17 +++++++++-------- mmgen/util2.py | 9 +++++---- mmgen/wallet/__init__.py | 3 +++ mmgen/wallet/base.py | 2 +- mmgen/wallet/incog_base.py | 4 ++-- mmgen/wallet/mnemonic.py | 8 ++++---- mmgen/xmrseed.py | 2 +- mmgen/xmrwallet/file/__init__.py | 2 +- mmgen/xmrwallet/file/outputs.py | 6 +++--- mmgen/xmrwallet/file/tx.py | 2 +- mmgen/xmrwallet/ops/import.py | 2 +- mmgen/xmrwallet/ops/relay.py | 2 +- mmgen/xmrwallet/ops/sign.py | 2 +- mmgen/xmrwallet/ops/wallet.py | 2 +- mmgen/xmrwallet/rpc.py | 6 +++--- test/cmdtest_d/ct_ethdev.py | 2 +- test/cmdtest_d/ct_main.py | 10 +++++----- test/cmdtest_d/ct_regtest.py | 4 ++-- test/cmdtest_d/ct_shared.py | 2 +- test/cmdtest_d/ct_xmr_autosign.py | 2 +- test/daemontest_d/ut_exec.py | 4 ++-- test/daemontest_d/ut_rpc.py | 6 +++--- test/daemontest_d/ut_tx.py | 2 +- test/gentest.py | 6 +++--- test/include/common.py | 2 +- test/modtest_d/ut_bip_hd.py | 2 +- test/modtest_d/ut_gen.py | 2 +- test/modtest_d/ut_misc.py | 2 +- test/modtest_d/ut_seedsplit.py | 2 +- 101 files changed, 314 insertions(+), 269 deletions(-) diff --git a/mmgen/addr.py b/mmgen/addr.py index 6a94f594..c5bb2b68 100755 --- a/mmgen/addr.py +++ b/mmgen/addr.py @@ -182,14 +182,14 @@ class CoinAddr(HiliteStr, InitErrors, MMGenObject): # reimplement some HiliteStr methods: @classmethod - def fmtc(cls, s, width, color=False): + def fmtc(cls, s, width, *, color=False): return super().fmtc(s=s[:width-2]+'..' if len(s) > width else s, width=width, color=color) - def fmt(self, view_pref, width, color=False): + def fmt(self, view_pref, width, *, color=False): s = self.views[view_pref] return super().fmtc(f'{s[:width-2]}..' if len(s) > width else s, width=width, color=color) - def hl(self, view_pref, color=True): + def hl(self, view_pref, *, color=True): return getattr(color_mod, self.color)(self.views[view_pref]) if color else self.views[view_pref] def is_coin_addr(proto, s): diff --git a/mmgen/addrfile.py b/mmgen/addrfile.py index b2e1f4b6..e32b1677 100755 --- a/mmgen/addrfile.py +++ b/mmgen/addrfile.py @@ -66,6 +66,7 @@ class AddrFile(MMGenObject): def write( self, fn = None, + *, binary = False, desc = None, ask_overwrite = True, @@ -92,7 +93,7 @@ class AddrFile(MMGenObject): ) return self.parent.al_id.sid + (' ' if lbl_p2 else '') + lbl_p2 - def format(self, add_comments=False): + def format(self, *, add_comments=False): p = self.parent if p.gen_passwds and p.pw_fmt in ('bip39', 'xmrseed'): desc_pfx = f'{p.pw_fmt.upper()} ' @@ -200,7 +201,7 @@ class AddrFile(MMGenObject): return ret - def parse_file(self, fn, buf=[], exit_on_error=True): + def parse_file(self, fn, *, buf=[], exit_on_error=True): def parse_addrfile_label(lbl): """ @@ -249,7 +250,7 @@ class AddrFile(MMGenObject): p = self.parent from .fileutil import get_lines_from_file - lines = get_lines_from_file(p.cfg, fn, p.desc+' data', trim_comments=True) + lines = get_lines_from_file(p.cfg, fn, desc=f'{p.desc} data', trim_comments=True) try: assert len(lines) >= 3, f'Too few lines in address file ({len(lines)})' diff --git a/mmgen/addrlist.py b/mmgen/addrlist.py index c8846a99..1a43ec3e 100755 --- a/mmgen/addrlist.py +++ b/mmgen/addrlist.py @@ -159,6 +159,7 @@ class AddrList(MMGenObject): # Address info for a single seed ID self, cfg, proto, + *, infile = '', al_id = '', adata = [], diff --git a/mmgen/altcoin/params.py b/mmgen/altcoin/params.py index 4214c9a9..357398bb 100755 --- a/mmgen/altcoin/params.py +++ b/mmgen/altcoin/params.py @@ -267,7 +267,7 @@ class CoinInfo: return None return cls.coin_constants[network][idx] -def make_proto(e, testnet=False): +def make_proto(e, *, testnet=False): proto = ('X_' if e.name[0] in '0123456789' else '') + e.name + ('Testnet' if testnet else '') @@ -297,7 +297,7 @@ def make_proto(e, testnet=False): ) ) -def init_genonly_altcoins(usr_coin=None, testnet=False): +def init_genonly_altcoins(usr_coin=None, *, testnet=False): """ Initialize altcoin protocol class or classes for current network. If usr_coin is a core coin, initialization is skipped. diff --git a/mmgen/amt.py b/mmgen/amt.py index 0e91f3ad..e9db6eeb 100755 --- a/mmgen/amt.py +++ b/mmgen/amt.py @@ -40,7 +40,7 @@ class CoinAmt(Decimal, Hilite, InitErrors): # abstract class max_amt = None # coin supply if known, otherwise None units = () # defined unit names, e.g. ('satoshi',...) - def __new__(cls, num, from_unit=None, from_decimal=False): + def __new__(cls, num, *, from_unit=None, from_decimal=False): if isinstance(num, CoinAmt): raise TypeError(f'CoinAmt: {num} is instance of {cls.__name__}') @@ -71,7 +71,7 @@ class CoinAmt(Decimal, Hilite, InitErrors): # abstract class def fmtc(cls, *args, **kwargs): cls.method_not_implemented() - def fmt(self, color=False, iwidth=1, prec=None): # iwidth: width of the integer part + def fmt(self, *, color=False, iwidth=1, prec=None): # iwidth: width of the integer part prec = prec or self.max_prec if '.' in (s := str(self)): a, b = s.split('.', 1) @@ -83,11 +83,11 @@ class CoinAmt(Decimal, Hilite, InitErrors): # abstract class s.rjust(iwidth).ljust(iwidth+prec+1), color = color) - def hl(self, color=True): + def hl(self, *, color=True): return self.colorize(str(self), color=color) # fancy highlighting with coin unit, enclosure, formatting - def hl2(self, color=True, unit=False, fs='{}', encl=''): + def hl2(self, *, color=True, unit=False, fs='{}', encl=''): res = fs.format(self) return ( encl[:-1] @@ -156,7 +156,7 @@ class CoinAmt(Decimal, Hilite, InitErrors): # abstract class def __mod__(self, *args, **kwargs): self.method_not_implemented() -def is_coin_amt(proto, num, from_unit=None, from_decimal=False): +def is_coin_amt(proto, num, *, from_unit=None, from_decimal=False): assert proto.coin_amt, 'proto.coin_amt is None! Did you call init_proto() with ‘need_amt’?' return get_obj(proto.coin_amt, num=num, from_unit=from_unit, from_decimal=from_decimal, silent=True, return_bool=True) diff --git a/mmgen/autosign.py b/mmgen/autosign.py index bde70e2a..2a941a1e 100755 --- a/mmgen/autosign.py +++ b/mmgen/autosign.py @@ -33,12 +33,12 @@ def SwapMgr(*args, **kwargs): class SwapMgrBase: - def __init__(self, cfg, ignore_zram=False): + def __init__(self, cfg, *, ignore_zram=False): self.cfg = cfg self.ignore_zram = ignore_zram self.desc = 'disk swap' if ignore_zram else 'swap' - def enable(self, quiet=False): + def enable(self, *, quiet=False): ret = self.do_enable() if not quiet: self.cfg._util.qmsg( @@ -47,7 +47,7 @@ class SwapMgrBase: f'Could not enable {self.desc}') return ret - def disable(self, quiet=False): + def disable(self, *, quiet=False): self.cfg._util.qmsg_r(f'Attempting to disable {self.desc}...') ret = self.do_disable() self.cfg._util.qmsg('success') @@ -189,7 +189,7 @@ class Signable: b = ' {}\n'.format('\n '.join(self.gen_bad_list(sorted(bad_files, key=lambda f: f.name)))) )) - def die_wrong_num_txs(self, tx_type, msg=None, desc=None, show_dir=False): + def die_wrong_num_txs(self, tx_type, *, msg=None, desc=None, show_dir=False): num_txs = len(getattr(self, tx_type)) die('AutosignTXError', "{m}{a} {b} transaction{c} {d} {e}!".format( m = msg + '\n' if msg else '', @@ -581,7 +581,7 @@ class Autosign: return self._wallet_files - def do_mount(self, silent=False, verbose=False): + def do_mount(self, *, silent=False, verbose=False): def check_or_create(dirname): path = getattr(self, dirname) @@ -615,7 +615,7 @@ class Autosign: for dirname in self.dirs: check_or_create(dirname) - def do_umount(self, silent=False, verbose=False): + def do_umount(self, *, silent=False, verbose=False): if self.mountpoint.is_mount(): run(['sync'], check=True) if not silent: @@ -630,7 +630,7 @@ class Autosign: fails = 0 for wf in self.wallet_files: try: - Wallet(self.cfg, wf, ignore_in_fmt=True, passwd_file=str(self.keyfile)) + Wallet(self.cfg, fn=wf, ignore_in_fmt=True, passwd_file=str(self.keyfile)) except SystemExit as e: if e.code != 0: fails += 1 @@ -710,7 +710,7 @@ class Autosign: die(2, 'Unable to write ' + desc) msg('Wrote ' + desc) - def gen_key(self, no_unmount=False): + def gen_key(self, *, no_unmount=False): if not self.device_inserted: die(1, 'Removable device not present!') self.do_mount() @@ -776,7 +776,7 @@ class Autosign: cfg = self.cfg, prompt = f"Default wallet '{wf}' found.\nUse default wallet for autosigning?", default_yes = True): - ss_in = Wallet(Config(), wf) + ss_in = Wallet(Config(), fn=wf) else: ss_in = Wallet(self.cfg, in_fmt=self.mn_fmts[self.cfg.mnemonic_fmt or self.dfl_mn_fmt]) ss_out = Wallet(self.cfg, ss=ss_in, passwd_file=str(self.keyfile)) diff --git a/mmgen/baseconv.py b/mmgen/baseconv.py index a53d196b..949e1bd3 100755 --- a/mmgen/baseconv.py +++ b/mmgen/baseconv.py @@ -129,11 +129,11 @@ class baseconv: else: die('BaseConversionPadError', f"{pad!r}: illegal value for 'pad' (must be None, 'seed' or int)") - def tohex(self, words_arg, pad=None): + def tohex(self, words_arg, *, pad=None): "convert string or list data of instance base to a hexadecimal string" - return self.tobytes(words_arg, pad//2 if type(pad) is int else pad).hex() + return self.tobytes(words_arg, pad=pad//2 if type(pad) is int else pad).hex() - def tobytes(self, words_arg, pad=None): + def tobytes(self, words_arg, *, pad=None): "convert string or list data of instance base to byte string" words = words_arg if isinstance(words_arg, (list, tuple)) else tuple(words_arg.strip()) @@ -163,7 +163,7 @@ class baseconv: bl = ret.bit_length() return ret.to_bytes(max(pad_val, bl//8+bool(bl%8)), 'big') - def fromhex(self, hexstr, pad=None, tostr=False): + def fromhex(self, hexstr, *, pad=None, tostr=False): "convert a hexadecimal string to a list or string data of instance base" from .util import is_hex_str @@ -172,9 +172,9 @@ class baseconv: ('seed data' if pad == 'seed' else f'{hexstr!r}:') + ' not a hexadecimal string') - return self.frombytes(bytes.fromhex(hexstr), pad, tostr) + return self.frombytes(bytes.fromhex(hexstr), pad=pad, tostr=tostr) - def frombytes(self, bytestr, pad=None, tostr=False): + def frombytes(self, bytestr, *, pad=None, tostr=False): "convert byte string to list or string data of instance base" if not bytestr: diff --git a/mmgen/bip39.py b/mmgen/bip39.py index d093fac8..26927051 100755 --- a/mmgen/bip39.py +++ b/mmgen/bip39.py @@ -54,14 +54,14 @@ class bip39(baseconv): self.wl_id = 'bip39' @classmethod - def nwords2seedlen(cls, nwords, in_bytes=False, in_hex=False): + def nwords2seedlen(cls, nwords, *, in_bytes=False, in_hex=False): for k, v in cls.constants.items(): if v.mn_len == nwords: return k//8 if in_bytes else k//4 if in_hex else k die('MnemonicError', f'{nwords!r}: invalid word length for BIP39 mnemonic') @classmethod - def seedlen2nwords(cls, seed_len, in_bytes=False, in_hex=False): + def seedlen2nwords(cls, seed_len, *, in_bytes=False, in_hex=False): seed_bits = seed_len * 8 if in_bytes else seed_len * 4 if in_hex else seed_len try: return cls.constants[seed_bits].mn_len @@ -105,11 +105,11 @@ class bip39(baseconv): return seed_bytes - def fromhex(self, hexstr, pad=None, tostr=False): + def fromhex(self, hexstr, *, pad=None, tostr=False): assert is_hex_str(hexstr), 'seed data not a hexadecimal string' return self.frombytes(bytes.fromhex(hexstr), pad=pad, tostr=tostr) - def frombytes(self, seed_bytes, pad=None, tostr=False): + def frombytes(self, seed_bytes, *, pad=None, tostr=False): assert tostr is False, "'tostr' must be False for 'bip39'" assert pad in (None, 'seed'), f"{pad}: invalid 'pad' argument (must be None or 'seed')" diff --git a/mmgen/bip_hd/__init__.py b/mmgen/bip_hd/__init__.py index 2e7e06de..a76222ea 100644 --- a/mmgen/bip_hd/__init__.py +++ b/mmgen/bip_hd/__init__.py @@ -185,6 +185,7 @@ class MasterNode(Lockable): def init_cfg( self, coin = None, + *, network = None, addr_type = None, from_path = False, @@ -204,11 +205,11 @@ class MasterNode(Lockable): new._lock() return new - def to_coin_type(self, coin=None, network=None, addr_type=None): - return self.init_cfg(coin, network, addr_type).to_coin_type() + def to_coin_type(self, *, coin=None, network=None, addr_type=None): + return self.init_cfg(coin, network=network, addr_type=addr_type).to_coin_type() - def to_chain(self, idx, coin=None, network=None, addr_type=None, hardened=False, public=False): - return self.init_cfg(coin, network, addr_type).to_chain( + def to_chain(self, idx, *, coin=None, network=None, addr_type=None, hardened=False, public=False): + return self.init_cfg(coin, network=network, addr_type=addr_type).to_chain( idx = idx, hardened = hardened, public = public) @@ -294,7 +295,7 @@ class BipHDNode(Lockable): def xprv(self): return self.key_extended(public=False, as_str=True) - def key_extended(self, public, as_str=False): + def key_extended(self, public, *, as_str=False): if self.public and not public: raise ValueError('cannot create extended private key for public node!') ret = b58chk_encode( @@ -363,6 +364,7 @@ class BipHDNode(Lockable): base_cfg, seed, path_str, + *, coin = None, addr_type = None, no_path_checks = False): @@ -441,7 +443,7 @@ class BipHDNodeMaster(BipHDNode): # purpose coin_type return self.derive_private().derive_private() - def to_chain(self, idx, hardened=False, public=False): + def to_chain(self, idx, *, hardened=False, public=False): # purpose coin_type account #0 chain return self.derive_private().derive_private().derive_private(idx=0).derive( idx = idx, @@ -475,7 +477,7 @@ class BipHDNodeCoinType(BipHDNode): f'chain index {chain_idx} for coin {cfg.base_cfg.coin!r}') return (chain_idx, type(self).hardened) - def to_chain(self, idx, hardened=False, public=False): + def to_chain(self, idx, *, hardened=False, public=False): # account #0 chain return self.derive_private(idx=0).derive( idx = idx, diff --git a/mmgen/cfg.py b/mmgen/cfg.py index f9a692bb..e1111819 100755 --- a/mmgen/cfg.py +++ b/mmgen/cfg.py @@ -438,6 +438,7 @@ class Config(Lockable): def __init__( self, cfg = None, + *, opts_data = None, init_opts = None, parse_only = False, @@ -845,7 +846,7 @@ def check_opts(cfg): # Raises exception if any check fails if hasattr(cfg, key2): val2 = getattr(cfg, key2) from .wallet import get_wallet_data - wd = get_wallet_data('incog_hidden') + wd = get_wallet_data(wtype='incog_hidden') if val2 and val2 not in wd.fmt_codes: die('UserOptError', f'Option conflict:\n {fmt_opt(name)}, with\n {fmt_opt(key2)}={val2}') @@ -929,7 +930,7 @@ def opt_postproc_debug(cfg): Msg(' {}\n'.format('\n '.join(none_opts))) Msg('\n=== end opts.py debug ===\n') -def conv_type(name, val, refval, src, invert_bool=False): +def conv_type(name, val, refval, *, src, invert_bool=False): def do_fail(): desc = { diff --git a/mmgen/crypto.py b/mmgen/crypto.py index 81c6b793..cdd3924c 100755 --- a/mmgen/crypto.py +++ b/mmgen/crypto.py @@ -90,7 +90,7 @@ class Crypto: return self.sha256_rounds(step1) def encrypt_seed(self, data, key, desc='seed'): - return self.encrypt_data(data, key, desc=desc) + return self.encrypt_data(data, key=key, desc=desc) def decrypt_seed(self, enc_seed, key, seed_id, key_id): self.util.vmsg_r('Checking key...') @@ -121,6 +121,7 @@ class Crypto: def encrypt_data( self, data, + *, key, iv = aesctr_dfl_iv, desc = 'data', @@ -214,6 +215,7 @@ class Crypto: passwd, salt, hash_preset, + *, desc = 'encryption key', from_what = 'passphrase', verbose = False): @@ -407,7 +409,7 @@ class Crypto: passwd_file = self.cfg.passwd_file) key = self.make_key(passwd, salt, hp) from hashlib import sha256 - enc_d = self.encrypt_data(sha256(nonce+data).digest() + nonce + data, key, iv, desc=desc) + enc_d = self.encrypt_data(sha256(nonce+data).digest() + nonce + data, key=key, iv=iv, desc=desc) return salt+iv+enc_d def mmgen_decrypt(self, data, desc='data', hash_preset=None): diff --git a/mmgen/daemon.py b/mmgen/daemon.py index 81a7e5d3..4c0e493e 100755 --- a/mmgen/daemon.py +++ b/mmgen/daemon.py @@ -91,7 +91,7 @@ class Daemon(Lockable): print(cp) return cp - def run_cmd(self, cmd, silent=False, is_daemon=False, check_retcode=False): + def run_cmd(self, cmd, *, silent=False, is_daemon=False, check_retcode=False): if self.debug: msg('\n\n') @@ -181,7 +181,7 @@ class Daemon(Lockable): def pre_start(self): pass - def start(self, quiet=False, silent=False): + def start(self, *, quiet=False, silent=False): if self.state == 'ready': if not (quiet or silent): msg(self.state_msg(extra_text='already')) @@ -200,7 +200,7 @@ class Daemon(Lockable): return ret - def stop(self, quiet=False, silent=False): + def stop(self, *, quiet=False, silent=False): if self.state == 'ready': if not silent: msg(f'Stopping {self.desc} on port {self.bind_port}') @@ -221,7 +221,7 @@ class Daemon(Lockable): msg(f'{self.desc} on port {self.bind_port} not running') return True - def restart(self, silent=False): + def restart(self, *, silent=False): self.stop(silent=silent) return self.start(silent=silent) @@ -339,6 +339,7 @@ class CoinDaemon(Daemon): def __new__(cls, cfg, + *, network_id = None, proto = None, opts = None, @@ -384,6 +385,7 @@ class CoinDaemon(Daemon): def __init__(self, cfg, + *, network_id = None, proto = None, opts = None, diff --git a/mmgen/devtools.py b/mmgen/devtools.py index cc7d66ab..de64b50a 100755 --- a/mmgen/devtools.py +++ b/mmgen/devtools.py @@ -131,7 +131,7 @@ class MMGenObjectMethods: # mixin class for MMGenObject def isScalar(obj): return isinstance(obj, scalars) - def do_list(out, e, lvl=0, is_dict=False): + def do_list(out, e, *, lvl=0, is_dict=False): out.append('\n') for i in e: el = i if not is_dict else e[i] diff --git a/mmgen/filename.py b/mmgen/filename.py index 5c703aa7..1a87269d 100755 --- a/mmgen/filename.py +++ b/mmgen/filename.py @@ -25,7 +25,7 @@ from .util import die, get_extension class File: - def __init__(self, fn, write=False): + def __init__(self, fn, *, write=False): self.name = fn self.dirname = os.path.dirname(fn) @@ -66,21 +66,21 @@ class File: class FileList(list): - def __init__(self, fns, write=False): + def __init__(self, fns, *, write=False): list.__init__( self, - [File(fn, write) for fn in fns]) + [File(fn, write=write) for fn in fns]) def names(self): return [f.name for f in self] - def sort_by_age(self, key='mtime', reverse=False): + def sort_by_age(self, *, key='mtime', reverse=False): assert key in ('atime', 'ctime', 'mtime'), f'{key!r}: invalid sort key' self.sort(key=lambda a: getattr(a, key), reverse=reverse) class MMGenFile(File): - def __init__(self, fn, base_class=None, subclass=None, proto=None, write=False): + def __init__(self, fn, *, base_class=None, subclass=None, proto=None, write=False): """ 'base_class' - a base class with an 'ext_to_cls' method 'subclass' - a subclass with an 'ext' attribute @@ -91,7 +91,7 @@ class MMGenFile(File): attribute to True. """ - super().__init__(fn, write) + super().__init__(fn, write=write) assert (subclass or base_class) and not (subclass and base_class), 'MMGenFile chk1' @@ -107,12 +107,12 @@ class MMGenFile(File): class MMGenFileList(FileList): - def __init__(self, fns, base_class, proto=None, write=False): + def __init__(self, fns, base_class, *, proto=None, write=False): list.__init__( self, [MMGenFile(fn, base_class=base_class, proto=proto, write=write) for fn in fns]) -def find_files_in_dir(subclass, fdir, no_dups=False): +def find_files_in_dir(subclass, fdir, *, no_dups=False): assert isinstance(subclass, type), f'{subclass}: not a class' diff --git a/mmgen/fileutil.py b/mmgen/fileutil.py index 25a71757..e10a4589 100755 --- a/mmgen/fileutil.py +++ b/mmgen/fileutil.py @@ -57,7 +57,7 @@ def check_binary(args): die(2, f'{args[0]!r} binary missing, not in path, or not executable') set_vt100() -def shred_file(fn, verbose=False): +def shred_file(fn, *, verbose=False): check_binary(['shred', '--version']) from subprocess import run run( @@ -67,7 +67,7 @@ def shred_file(fn, verbose=False): check=True) set_vt100() -def _check_file_type_and_access(fname, ftype, blkdev_ok=False): +def _check_file_type_and_access(fname, ftype, *, blkdev_ok=False): import stat @@ -103,16 +103,16 @@ def _check_file_type_and_access(fname, ftype, blkdev_ok=False): return True -def check_infile(f, blkdev_ok=False): +def check_infile(f, *, blkdev_ok=False): return _check_file_type_and_access(f, 'input file', blkdev_ok=blkdev_ok) -def check_outfile(f, blkdev_ok=False): +def check_outfile(f, *, blkdev_ok=False): return _check_file_type_and_access(f, 'output file', blkdev_ok=blkdev_ok) def check_outdir(f): return _check_file_type_and_access(f, 'output directory') -def get_seed_file(cfg, nargs, wallets=None, invoked_as=None): +def get_seed_file(cfg, *, nargs, wallets=None, invoked_as=None): wallets = wallets or cfg._args @@ -137,7 +137,7 @@ def get_seed_file(cfg, nargs, wallets=None, invoked_as=None): return str(wallets[0]) if wallets else (wf, None)[wd_from_opt] # could be a Path instance -def _open_or_die(filename, mode, silent=False): +def _open_or_die(filename, mode, *, silent=False): try: return open(filename, mode) except: @@ -152,6 +152,7 @@ def write_data_to_file( cfg, outfile, data, + *, desc = 'data', ask_write = False, ask_write_prompt = '', @@ -279,7 +280,7 @@ def write_data_to_file( else: do_file(outfile, ask_write_prompt) -def get_words_from_file(cfg, infile, desc, quiet=False): +def get_words_from_file(cfg, infile, *, desc, quiet=False): if not quiet: cfg._util.qmsg(f'Getting {desc} from file ‘{infile}’') @@ -299,6 +300,7 @@ def get_words_from_file(cfg, infile, desc, quiet=False): def get_data_from_file( cfg, infile, + *, desc = 'data', dash = False, silent = False, @@ -326,6 +328,7 @@ def get_data_from_file( def get_lines_from_file( cfg, fn, + *, desc = 'data', trim_comments = False, quiet = False, diff --git a/mmgen/help/help_notes.py b/mmgen/help/help_notes.py index 234d9c04..338a6586 100755 --- a/mmgen/help/help_notes.py +++ b/mmgen/help/help_notes.py @@ -30,7 +30,7 @@ class help_notes: def account_info_desc(self): return 'unspent outputs' if self.proto.base_proto == 'Bitcoin' else 'account info' - def fee_spec_letters(self, use_quotes=False): + def fee_spec_letters(self, *, use_quotes=False): cu = self.proto.coin_amt.units sep, conj = ((',', ' or '), ("','", "' or '"))[use_quotes] return sep.join(u[0] for u in cu[:-1]) + ('', conj)[len(cu)>1] + cu[-1][0] diff --git a/mmgen/help/txsign.py b/mmgen/help/txsign.py index 5cb17b8d..db719958 100755 --- a/mmgen/help/txsign.py +++ b/mmgen/help/txsign.py @@ -19,7 +19,7 @@ from ..daemon import CoinDaemon def help(proto, cfg): def coind_exec(): - return CoinDaemon(cfg, proto.coin).exec_fn if proto.coin in CoinDaemon.coins else 'bitcoind' + return CoinDaemon(cfg, network_id=proto.coin).exec_fn if proto.coin in CoinDaemon.coins else 'bitcoind' return """ Transactions may contain both {pnm} or non-{pnm} input addresses. diff --git a/mmgen/keygen.py b/mmgen/keygen.py index 515d76f9..a91cf88f 100755 --- a/mmgen/keygen.py +++ b/mmgen/keygen.py @@ -51,7 +51,7 @@ class keygen_base: return None @classmethod - def get_clsname(cls, cfg, silent=False): + def get_clsname(cls, cfg, *, silent=False): return cls.__name__ backend_data = { @@ -104,7 +104,7 @@ def check_backend(cfg, proto, backend, addr_type): return _check_backend(cfg, backend, pubkey_type, desc='--keygen-backend parameter') -def KeyGenerator(cfg, proto, pubkey_type, backend=None, silent=False): +def KeyGenerator(cfg, proto, pubkey_type, *, backend=None, silent=False): """ factory function returning a key generator backend for the specified pubkey type """ diff --git a/mmgen/led.py b/mmgen/led.py index 40da46d2..75a127de 100755 --- a/mmgen/led.py +++ b/mmgen/led.py @@ -71,7 +71,7 @@ class LEDControl: trigger = '/tmp/led_trigger'), } - def __init__(self, enabled, simulate=False, debug=False): + def __init__(self, *, enabled, simulate=False, debug=False): self.enabled = enabled self.debug = debug or simulate diff --git a/mmgen/main_addrgen.py b/mmgen/main_addrgen.py index 585eacdc..b714b7b9 100755 --- a/mmgen/main_addrgen.py +++ b/mmgen/main_addrgen.py @@ -141,12 +141,12 @@ if cfg.keygen_backend: idxs = addrlist.AddrIdxList(fmt_str=cfg._args.pop()) from .fileutil import get_seed_file -sf = get_seed_file(cfg, 1) +sf = get_seed_file(cfg, nargs=1) from .ui import do_license_msg do_license_msg(cfg) -ss = Wallet(cfg, sf) +ss = Wallet(cfg, fn=sf) ss_seed = ss.seed if cfg.subwallet is None else ss.seed.subseed(cfg.subwallet, print_msg=True) diff --git a/mmgen/main_addrimport.py b/mmgen/main_addrimport.py index 973a24b9..cb6b7acb 100755 --- a/mmgen/main_addrimport.py +++ b/mmgen/main_addrimport.py @@ -84,7 +84,7 @@ addrimport_msgs = { def parse_cmd_args(rpc, cmd_args): def import_mmgen_list(infile): - return (AddrList, KeyAddrList)[bool(cfg.keyaddr_file)](cfg, proto, infile) + return (AddrList, KeyAddrList)[bool(cfg.keyaddr_file)](cfg, proto, infile=infile) if len(cmd_args) == 1: infile = cmd_args[0] @@ -97,7 +97,7 @@ def parse_cmd_args(rpc, cmd_args): addrlist = get_lines_from_file( cfg, infile, - f'non-{gc.proj_name} addresses', + desc = f'non-{gc.proj_name} addresses', trim_comments = True)) else: al = import_mmgen_list(infile) diff --git a/mmgen/main_passgen.py b/mmgen/main_passgen.py index 6ec5da3d..53c5a4a9 100755 --- a/mmgen/main_passgen.py +++ b/mmgen/main_passgen.py @@ -146,7 +146,7 @@ pw_idxs = AddrIdxList(fmt_str=cfg._args.pop()) pw_id_str = cfg._args.pop() from .fileutil import get_seed_file -sf = get_seed_file(cfg, 1) +sf = get_seed_file(cfg, nargs=1) pw_fmt = cfg.passwd_fmt or PasswordList.dfl_pw_fmt pw_len = pwi[pw_fmt].dfl_len // 2 if cfg.passwd_len in ('h', 'H') else cfg.passwd_len @@ -165,7 +165,7 @@ PasswordList( from .ui import do_license_msg do_license_msg(cfg) -ss = Wallet(cfg, sf) +ss = Wallet(cfg, fn=sf) al = PasswordList( cfg = cfg, diff --git a/mmgen/main_seedjoin.py b/mmgen/main_seedjoin.py index a1062563..e78f455d 100755 --- a/mmgen/main_seedjoin.py +++ b/mmgen/main_seedjoin.py @@ -131,7 +131,7 @@ do_license_msg(cfg) cfg._util.qmsg('Input files:\n {}\n'.format('\n '.join(cfg._args))) shares = [Wallet(cfg).seed] if cfg.hidden_incog_input_params else [] -shares += [Wallet(cfg,fn).seed for fn in cfg._args] +shares += [Wallet(cfg, fn=fn).seed for fn in cfg._args] if cfg.master_share: share1 = SeedShareMasterJoining(cfg, master_idx, shares[0], id_str, len(shares)).derived_seed diff --git a/mmgen/main_tool.py b/mmgen/main_tool.py index 595fb1e7..81bafad6 100755 --- a/mmgen/main_tool.py +++ b/mmgen/main_tool.py @@ -179,7 +179,7 @@ mods = { def get_cmds(): return [cmd for mod, cmds in mods.items() if mod != 'help' for cmd in cmds] -def create_call_sig(cmd, cls, as_string=False): +def create_call_sig(cmd, cls, *, as_string=False): m = getattr(cls, cmd) @@ -189,8 +189,11 @@ def create_call_sig(cmd, cls, as_string=False): args, dfls, ann = va['args'], va['dfls'], va['annots'] else: flag = None - args = m.__code__.co_varnames[1:m.__code__.co_argcount] - dfls = m.__defaults__ or () + c = m.__code__ + args = c.co_varnames[1:c.co_argcount + c.co_posonlyargcount + c.co_kwonlyargcount] + dfls = ( + (m.__defaults__ or ()) + + tuple(m.__kwdefaults__[k] for k in args if k in (m.__kwdefaults__ or ()))) ann = m.__annotations__ nargs = len(args) - len(dfls) @@ -295,7 +298,7 @@ def process_args(cmd, cmd_args, cls): return (args, kwargs) -def process_result(ret, pager=False, print_result=False): +def process_result(ret, *, pager=False, print_result=False): """ Convert result to something suitable for output to screen and return it. If result is bytes and not convertible to utf8, output as binary using os.write(). diff --git a/mmgen/main_wallet.py b/mmgen/main_wallet.py index d9599d14..5a4e41a4 100755 --- a/mmgen/main_wallet.py +++ b/mmgen/main_wallet.py @@ -179,7 +179,7 @@ if cmd_args: cfg._usage() check_infile(cmd_args[0]) -sf = get_seed_file(cfg, nargs, invoked_as=invoked_as) +sf = get_seed_file(cfg, nargs=nargs, invoked_as=invoked_as) if invoked_as != 'chk': from .ui import do_license_msg @@ -212,7 +212,7 @@ if invoked_as == 'subgen': cfg = cfg, seed_bin = ss_in.seed.subseed(ss_idx, print_msg=True).data) elif invoked_as == 'seedsplit': - shares = ss_in.seed.split(sss.count, sss.id, master_share) + shares = ss_in.seed.split(sss.count, id_str=sss.id, master_idx=master_share) seed_out = shares.get_share_by_idx(sss.idx, base_seed=True) msg(seed_out.get_desc(ui=True)) ss_out = Wallet( diff --git a/mmgen/mn_entry.py b/mmgen/mn_entry.py index ca62ef62..c51cbb94 100755 --- a/mmgen/mn_entry.py +++ b/mmgen/mn_entry.py @@ -323,7 +323,7 @@ class MnemonicEntry: time.sleep(self.cfg.err_disp_timeout) msg_r(erase) - def get_mnemonic_from_user(self, mn_len, validate=True): + def get_mnemonic_from_user(self, mn_len, *, validate=True): mll = list(self.bconv.seedlen_map_rev) assert mn_len in mll, f'{mn_len}: invalid mnemonic length (must be one of {mll})' diff --git a/mmgen/msg.py b/mmgen/msg.py index e752c02c..d5528433 100755 --- a/mmgen/msg.py +++ b/mmgen/msg.py @@ -91,7 +91,7 @@ class coin_msg: coin, network = network_id.split('_') return init_proto(cfg=cfg, coin=coin, network=network) - def write_to_file(self, outdir=None, ask_overwrite=False): + def write_to_file(self, *, outdir=None, ask_overwrite=False): data = { 'id': f'{gc.proj_name} {self.desc}', 'metadata': self.data, diff --git a/mmgen/obj.py b/mmgen/obj.py index bbb85091..08627d6b 100755 --- a/mmgen/obj.py +++ b/mmgen/obj.py @@ -102,7 +102,7 @@ class ImmutableAttr: # Descriptor """ ok_dtypes = (type, type(None), type(lambda:0)) - def __init__(self, dtype, typeconv=True, set_none_ok=False, include_proto=False): + def __init__(self, dtype, *, typeconv=True, set_none_ok=False, include_proto=False): self.set_none_ok = set_none_ok self.typeconv = typeconv @@ -154,7 +154,7 @@ class ListItemAttr(ImmutableAttr): For attributes that might not be present in the data instance Reassignment or deletion allowed if specified """ - def __init__(self, dtype, typeconv=True, include_proto=False, reassign_ok=False, delete_ok=False): + def __init__(self, dtype, *, typeconv=True, include_proto=False, reassign_ok=False, delete_ok=False): self.reassign_ok = reassign_ok self.delete_ok = delete_ok ImmutableAttr.__init__(self, dtype, typeconv=typeconv, include_proto=include_proto) @@ -280,10 +280,10 @@ class Int(int, Hilite, InitErrors): return cls.init_fail(e, n) @classmethod - def fmtc(cls, s, width, color=False): + def fmtc(cls, s, width, *, color=False): return super().fmtc(str(s), width=width, color=color) - def fmt(self, width, color=False): + def fmt(self, width, *, color=False): return super().fmtc(str(self), width=width, color=color) def hl(self, **kwargs): @@ -324,7 +324,7 @@ class HexStr(HiliteStr, InitErrors): except Exception as e: return cls.init_fail(e, s) - def truncate(self, width, color=True): + def truncate(self, width, *, color=True): return self.colorize( self if width >= self.width else self[:width-2] + '..', color = color) diff --git a/mmgen/objmethods.py b/mmgen/objmethods.py index e4e0cd35..35ccf13a 100755 --- a/mmgen/objmethods.py +++ b/mmgen/objmethods.py @@ -49,7 +49,7 @@ class Hilite: # class method equivalent of fmt() @classmethod - def fmtc(cls, s, width, color=False): + def fmtc(cls, s, width, *, color=False): if len(s) > width: assert cls.trunc_ok, "If 'trunc_ok' is false, 'width' must be >= width of string" return cls.colorize(s[:width].ljust(width), color=color) @@ -57,21 +57,21 @@ class Hilite: return cls.colorize(s.ljust(width), color=color) @classmethod - def hlc(cls, s, color=True): + def hlc(cls, s, *, color=True): return getattr(color_mod, cls.color)(s) if color else s @classmethod - def colorize(cls, s, color=True): + def colorize(cls, s, *, color=True): return getattr(color_mod, cls.color)(s) if color else s @classmethod - def colorize2(cls, s, color=True, color_override=''): + def colorize2(cls, s, *, color=True, color_override=''): return getattr(color_mod, color_override or cls.color)(s) if color else s class HiliteStr(str, Hilite): # supports single-width characters only - def fmt(self, width, color=False): + def fmt(self, width, *, color=False): if len(self) > width: assert self.trunc_ok, "If 'trunc_ok' is false, 'width' must be >= width of string" return self.colorize(self[:width].ljust(width), color=color) @@ -82,6 +82,7 @@ class HiliteStr(str, Hilite): def fmt2( self, width, # screen width - must be at least 2 (one wide char) + *, color = False, encl = '', # if set, must be exactly 2 single-width chars nullrepl = '', @@ -112,12 +113,12 @@ class HiliteStr(str, Hilite): else: return self.colorize2(s.ljust(width-s_wide_count), color=color, color_override=color_override) - def hl(self, color=True): + def hl(self, *, color=True): return getattr(color_mod, self.color)(self) if color else self # an alternative to hl(), with enclosure and color override # can be called as an unbound method with class as first argument - def hl2(self, s=None, color=True, encl='', color_override=''): + def hl2(self, s=None, *, color=True, encl='', color_override=''): if encl: return self.colorize2(encl[0]+(s or self)+encl[1], color=color, color_override=color_override) else: @@ -126,7 +127,7 @@ class HiliteStr(str, Hilite): class InitErrors: @classmethod - def init_fail(cls, e, m, e2=None, m2=None, objname=None, preformat=False): + def init_fail(cls, e, m, *, e2=None, m2=None, objname=None, preformat=False): def get_errmsg(): ret = m if preformat else ( diff --git a/mmgen/passwdlist.py b/mmgen/passwdlist.py index 4662488e..793e3b93 100755 --- a/mmgen/passwdlist.py +++ b/mmgen/passwdlist.py @@ -69,6 +69,7 @@ class PasswordList(AddrList): self, cfg, proto, + *, infile = None, seed = None, pw_idxs = None, diff --git a/mmgen/platform/darwin/util.py b/mmgen/platform/darwin/util.py index 88f36a73..f88e21c8 100755 --- a/mmgen/platform/darwin/util.py +++ b/mmgen/platform/darwin/util.py @@ -59,7 +59,7 @@ class MacOSRamDisk: def get_diskutil_size(self): return get_device_size(self.label) // (2**20) - def create(self, quiet=False): + def create(self, *, quiet=False): redir = DEVNULL if quiet else None if self.exists(): diskutil_size = self.get_diskutil_size() @@ -81,7 +81,7 @@ class MacOSRamDisk: self.path.mkdir(parents=True, exist_ok=True) run(['diskutil', 'mount', '-mountPoint', str(self.path.absolute()), self.label], stdout=redir, check=True) - def destroy(self, quiet=False): + def destroy(self, *, quiet=False): if not self.exists(): self.cfg._util.qmsg(f'{self.desc.capitalize()} {self.label.hl()} at path {self.path} not found') return diff --git a/mmgen/proto/btc/regtest.py b/mmgen/proto/btc/regtest.py index 73b203fa..aa12bd00 100755 --- a/mmgen/proto/btc/regtest.py +++ b/mmgen/proto/btc/regtest.py @@ -73,7 +73,7 @@ class MMGenRegtest(MMGenObject): 'bch': 'n2fxhNx27GhHAWQhyuZ5REcBNrJqCJsJ12', } - def __init__(self, cfg, coin, bdb_wallet=False): + def __init__(self, cfg, coin, *, bdb_wallet=False): self.cfg = cfg self.coin = coin.lower() self.bdb_wallet = bdb_wallet @@ -83,7 +83,7 @@ class MMGenRegtest(MMGenObject): self.proto = init_proto(cfg, self.coin, regtest=True, need_amt=True) self.d = CoinDaemon( cfg, - self.coin + '_rt', + network_id = self.coin + '_rt', test_suite = cfg.test_suite, opts = ['bdb_wallet'] if bdb_wallet else None) @@ -116,7 +116,7 @@ class MMGenRegtest(MMGenObject): t.addrtype = 'compressed' if self.proto.coin == 'BCH' else 'bech32' return t.hex2wif(self.bdb_hdseed) - async def generate(self, blocks=1, silent=False): + async def generate(self, blocks=1, *, silent=False): blocks = int(blocks) @@ -194,11 +194,11 @@ class MMGenRegtest(MMGenObject): msg('Stopping regtest daemon') await self.rpc_call('stop') - def init_daemon(self, reindex=False): + def init_daemon(self, *, reindex=False): if reindex: self.d.usr_coind_args.append('--reindex') - async def start_daemon(self, reindex=False, silent=True): + async def start_daemon(self, *, reindex=False, silent=True): self.init_daemon(reindex=reindex) self.d.start(silent=silent) for user in ('miner', 'bob', 'alice'): @@ -260,7 +260,7 @@ class MMGenRegtest(MMGenObject): async def fork(self, coin): # currently disabled - proto = init_proto(self.cfg, coin, False) + proto = init_proto(self.cfg, coin, testnet=False) if not [f for f in proto.forks if f[2] == proto.coin.lower() and f[3] is True]: die(1, f'Coin {proto.coin} is not a replayable fork of coin {coin}') diff --git a/mmgen/proto/btc/rpc.py b/mmgen/proto/btc/rpc.py index 8c0a4c13..bd635cd1 100755 --- a/mmgen/proto/btc/rpc.py +++ b/mmgen/proto/btc/rpc.py @@ -54,6 +54,7 @@ class CallSigs: def createwallet( self, wallet_name, + *, no_keys = True, blank = True, passphrase = '', @@ -86,6 +87,7 @@ class CallSigs: def createwallet( self, wallet_name, + *, no_keys = True, blank = True, passphrase = '', @@ -269,7 +271,7 @@ class BitcoinRPCClient(RPCClient, metaclass=AsyncInit): fn = self.get_daemon_cfg_fn() try: lines = get_lines_from_file( - self.cfg, fn, 'daemon config file', silent=not self.cfg.verbose) + self.cfg, fn, desc='daemon config file', silent=not self.cfg.verbose) except: self.cfg._util.vmsg(f'Warning: {fn!r} does not exist or is unreadable') return dict((k, None) for k in req_keys) @@ -289,7 +291,7 @@ class BitcoinRPCClient(RPCClient, metaclass=AsyncInit): def get_daemon_auth_cookie(self): fn = self.daemon.auth_cookie_fn return get_lines_from_file( - self.cfg, fn, 'cookie', quiet=True)[0] if os.access(fn, os.R_OK) else '' + self.cfg, fn, desc='cookie', quiet=True)[0] if os.access(fn, os.R_OK) else '' def info(self, info_id): diff --git a/mmgen/proto/btc/tw/ctl.py b/mmgen/proto/btc/tw/ctl.py index 17ef9c2d..a302649c 100755 --- a/mmgen/proto/btc/tw/ctl.py +++ b/mmgen/proto/btc/tw/ctl.py @@ -27,7 +27,7 @@ class BitcoinTwCtl(TwCtl): raise NotImplementedError('not implemented') @write_mode - async def import_address(self, addr, label, rescan=False): + async def import_address(self, addr, *, label, rescan=False): if (await self.rpc.walletinfo).get('descriptors'): return await self.batch_import_address([(addr, label, rescan)]) else: diff --git a/mmgen/proto/btc/tx/base.py b/mmgen/proto/btc/tx/base.py index a15b393e..e7c128c4 100755 --- a/mmgen/proto/btc/tx/base.py +++ b/mmgen/proto/btc/tx/base.py @@ -75,7 +75,7 @@ def DeserializeTX(proto, txhex): def bytes2coin_amt(bytes_le): return proto.coin_amt(bytes2int(bytes_le), from_unit='satoshi') - def bshift(n, skip=False, sub_null=False): + def bshift(n, *, skip=False, sub_null=False): nonlocal idx, raw_tx ret = tx[idx:idx+n] idx += n @@ -87,7 +87,7 @@ def DeserializeTX(proto, txhex): # https://bitcoin.org/en/developer-reference#compactsize-unsigned-integers # For example, the number 515 is encoded as 0xfd0302. - def readVInt(skip=False): + def readVInt(*, skip=False): nonlocal idx, raw_tx s = tx[idx] idx += 1 diff --git a/mmgen/proto/btc/tx/info.py b/mmgen/proto/btc/tx/info.py index 253e8c12..9cc6cf66 100755 --- a/mmgen/proto/btc/tx/info.py +++ b/mmgen/proto/btc/tx/info.py @@ -145,7 +145,7 @@ class TxInfo(TxInfo): + ''.join(format_io('inputs')) + ''.join(format_io('outputs'))) - def strfmt_locktime(self, locktime=None, terse=False): + def strfmt_locktime(self, locktime=None, *, terse=False): # Locktime itself is an unsigned 4-byte integer which can be parsed two ways: # # If less than 500 million, locktime is parsed as a block height. The transaction can be diff --git a/mmgen/proto/btc/tx/online.py b/mmgen/proto/btc/tx/online.py index 387f04da..4e551fd8 100755 --- a/mmgen/proto/btc/tx/online.py +++ b/mmgen/proto/btc/tx/online.py @@ -19,7 +19,7 @@ from .signed import Signed class OnlineSigned(Signed, TxBase.OnlineSigned): - async def send(self, prompt_user=True): + async def send(self, *, prompt_user=True): self.check_correct_chain() diff --git a/mmgen/proto/btc/tx/op_return_data.py b/mmgen/proto/btc/tx/op_return_data.py index d5747a2d..7061b30d 100755 --- a/mmgen/proto/btc/tx/op_return_data.py +++ b/mmgen/proto/btc/tx/op_return_data.py @@ -61,7 +61,7 @@ class OpReturnData(bytes, InitErrors): self.display_hex = False return ret - def hl(self, add_label=False): + def hl(self, *, add_label=False): 'colorize and optionally label the result of str()' from ....color import blue, pink ret = str(self) diff --git a/mmgen/proto/eth/contract.py b/mmgen/proto/eth/contract.py index 14f5118b..aee852cb 100755 --- a/mmgen/proto/eth/contract.py +++ b/mmgen/proto/eth/contract.py @@ -45,7 +45,7 @@ class TokenCommon(MMGenObject): int(parse_abi(data)[-1], 16) * self.base_unit, from_decimal = True) - async def do_call(self, method_sig, method_args='', toUnit=False): + async def do_call(self, method_sig, method_args='', *, toUnit=False): data = self.create_method_id(method_sig) + method_args if self.cfg.debug: msg('ETH_CALL {}: {}'.format( diff --git a/mmgen/proto/eth/daemon.py b/mmgen/proto/eth/daemon.py index 4e926036..a8e7370a 100755 --- a/mmgen/proto/eth/daemon.py +++ b/mmgen/proto/eth/daemon.py @@ -174,12 +174,12 @@ class erigon_daemon(geth_daemon): test_suite = self.test_suite, datadir = self.datadir) - def start(self, quiet=False, silent=False): + def start(self, *, quiet=False, silent=False): super().start(quiet=quiet, silent=silent) self.rpc_d.debug = self.debug return self.rpc_d.start(quiet=quiet, silent=silent) - def stop(self, quiet=False, silent=False): + def stop(self, *, quiet=False, silent=False): self.rpc_d.debug = self.debug self.rpc_d.stop(quiet=quiet, silent=silent) return super().stop(quiet=quiet, silent=silent) @@ -196,7 +196,7 @@ class erigon_rpcdaemon(RPCDaemon): use_pidfile = False use_threads = True - def __init__(self, cfg, proto, rpc_port, private_port, test_suite, datadir): + def __init__(self, cfg, proto, *, rpc_port, private_port, test_suite, datadir): self.proto = proto self.test_suite = test_suite diff --git a/mmgen/proto/eth/misc.py b/mmgen/proto/eth/misc.py index 48aefa03..130a84cd 100755 --- a/mmgen/proto/eth/misc.py +++ b/mmgen/proto/eth/misc.py @@ -14,7 +14,7 @@ proto.eth.misc: miscellaneous utilities for Ethereum base protocol from ...util2 import get_keccak -def decrypt_geth_keystore(cfg, wallet_fn, passwd, check_addr=True): +def decrypt_geth_keystore(cfg, wallet_fn, passwd, *, check_addr=True): """ Decrypt the encrypted private key in a Geth keystore wallet, returning the decrypted key """ diff --git a/mmgen/proto/eth/tw/ctl.py b/mmgen/proto/eth/tw/ctl.py index fcc648f1..c2af7592 100755 --- a/mmgen/proto/eth/tw/ctl.py +++ b/mmgen/proto/eth/tw/ctl.py @@ -88,13 +88,13 @@ class EthereumTwCtl(TwCtl): @write_mode async def batch_import_address(self, args_list): - return [await self.import_address(*a) for a in args_list] + return [await self.import_address(a, label=b, rescan=c) for a, b, c in args_list] async def rescan_addresses(self, coin_addrs): pass @write_mode - async def import_address(self, addr, label, rescan=False): + async def import_address(self, addr, *, label, rescan=False): r = self.data_root if addr in r: if not r[addr]['mmid'] and label.mmid: @@ -174,7 +174,7 @@ class EthereumTokenTwCtl(EthereumTwCtl): symbol = None cur_eth_balances = {} - async def __init__(self, cfg, proto, mode='r', token_addr=None, no_rpc=False): + async def __init__(self, cfg, proto, *, mode='r', token_addr=None, no_rpc=False): await super().__init__(cfg, proto, mode=mode, no_rpc=no_rpc) @@ -215,13 +215,13 @@ class EthereumTokenTwCtl(EthereumTwCtl): async def rpc_get_balance(self, addr): return await Token(self.cfg, self.proto, self.token, self.decimals, self.rpc).get_balance(addr) - async def get_eth_balance(self, addr, force_rpc=False): + async def get_eth_balance(self, addr, *, force_rpc=False): cache = self.cur_eth_balances r = self.data['accounts'] ret = None if force_rpc else self.get_cached_balance(addr, cache, r) if ret is None: ret = await super().rpc_get_balance(addr) - self.cache_balance(addr, ret, cache, r) + self.cache_balance(addr, ret, session_cache=cache, data_root=r) return ret def get_param(self, param): diff --git a/mmgen/proto/eth/tw/json.py b/mmgen/proto/eth/tw/json.py index 6bd035c6..e04f2bdc 100755 --- a/mmgen/proto/eth/tw/json.py +++ b/mmgen/proto/eth/tw/json.py @@ -109,7 +109,7 @@ class EthereumTwJSON(TwJSON): class Export(TwJSON.Export, Base): - async def get_entries(self, include_amts=True): + async def get_entries(self, *, include_amts=True): def gen_data(data): for k, v in data.items(): diff --git a/mmgen/proto/eth/tw/unspent.py b/mmgen/proto/eth/tw/unspent.py index f0bb78e0..eb96124a 100755 --- a/mmgen/proto/eth/tw/unspent.py +++ b/mmgen/proto/eth/tw/unspent.py @@ -95,7 +95,7 @@ class EthereumTwUnspentOutputs(EthereumTwView, TwUnspentOutputs): interactive = interactive, ) - def do_sort(self, key=None, reverse=False): + def do_sort(self, key=None, *, reverse=False): if key == 'txid': return super().do_sort(key=key, reverse=reverse) diff --git a/mmgen/proto/eth/tx/online.py b/mmgen/proto/eth/tx/online.py index 79e83764..f8c7e94d 100755 --- a/mmgen/proto/eth/tx/online.py +++ b/mmgen/proto/eth/tx/online.py @@ -20,7 +20,7 @@ from .signed import Signed, TokenSigned class OnlineSigned(Signed, TxBase.OnlineSigned): - async def send(self, prompt_user=True): + async def send(self, *, prompt_user=True): self.check_correct_chain() diff --git a/mmgen/proto/secp256k1/keygen.py b/mmgen/proto/secp256k1/keygen.py index ad3f9875..63f4a48c 100755 --- a/mmgen/proto/secp256k1/keygen.py +++ b/mmgen/proto/secp256k1/keygen.py @@ -37,7 +37,7 @@ class backend: compressed = privkey.compressed) @classmethod - def get_clsname(cls, cfg, silent=False): + def get_clsname(cls, cfg, *, silent=False): try: from .secp256k1 import pubkey_gen if not pubkey_gen(bytes.fromhex('deadbeef'*8), 1): @@ -67,7 +67,7 @@ class backend: Uncompressed public keys start with 0x04; compressed public keys begin with 0x03 or 0x02 depending on whether they're greater or less than the midpoint of the curve. """ - def privnum2pubkey(numpriv, compressed=False): + def privnum2pubkey(numpriv, *, compressed=False): pk = self.ecdsa.SigningKey.from_secret_exponent(numpriv, curve=self.ecdsa.SECP256k1) # vk_bytes = x (32 bytes) + y (32 bytes) (unsigned big-endian) return pubkey_format(pk.verifying_key.to_string(), compressed) diff --git a/mmgen/proto/xmr/daemon.py b/mmgen/proto/xmr/daemon.py index ca83fdeb..1483705a 100755 --- a/mmgen/proto/xmr/daemon.py +++ b/mmgen/proto/xmr/daemon.py @@ -104,6 +104,7 @@ class MoneroWalletDaemon(RPCDaemon): self, cfg, proto, + *, wallet_dir = None, test_suite = False, user = None, diff --git a/mmgen/proto/xmr/rpc.py b/mmgen/proto/xmr/rpc.py index 76b9e672..b606d689 100755 --- a/mmgen/proto/xmr/rpc.py +++ b/mmgen/proto/xmr/rpc.py @@ -25,6 +25,7 @@ class MoneroRPCClient(RPCClient): self, cfg, proto, + *, host, port, user, @@ -42,7 +43,7 @@ class MoneroRPCClient(RPCClient): if host.endswith('.onion'): self.network_proto = 'http' - super().__init__(cfg, host, port, test_connection) + super().__init__(cfg, host, port, test_connection=test_connection) if self.auth_type: self.auth = auth_data(user, passwd) @@ -90,7 +91,7 @@ class MoneroRPCClient(RPCClient): host_path = f'/{method}' ), json_rpc=False) - async def do_stop_daemon(self, silent=False): + async def do_stop_daemon(self, *, silent=False): return self.call_raw('stop_daemon') # unreliable on macOS (daemon stops, but closes connection) rpcmethods = ('get_info',) @@ -100,7 +101,7 @@ class MoneroWalletRPCClient(MoneroRPCClient): auth_type = 'digest' - def __init__(self, cfg, daemon, test_connection=True): + def __init__(self, cfg, daemon, *, test_connection=True): RPCClient.__init__( self = self, @@ -128,7 +129,7 @@ class MoneroWalletRPCClient(MoneroRPCClient): def call_raw(self, *args, **kwargs): raise NotImplementedError('call_raw() not implemented for class MoneroWalletRPCClient') - async def do_stop_daemon(self, silent=False): + async def do_stop_daemon(self, *, silent=False): """ NB: the 'stop_wallet' RPC call closes the open wallet before shutting down the daemon, returning an error if no wallet is open diff --git a/mmgen/protocol.py b/mmgen/protocol.py index eb4ef251..067badd9 100755 --- a/mmgen/protocol.py +++ b/mmgen/protocol.py @@ -59,7 +59,7 @@ class CoinProtocol(MMGenObject): decimal_prec = 28 _set_ok = ('tokensym',) - def __init__(self, cfg, coin, name, network, tokensym=None, need_amt=False): + def __init__(self, cfg, coin, *, name, network, tokensym=None, need_amt=False): self.cfg = cfg self.coin = coin.upper() self.coin_id = self.coin @@ -180,7 +180,7 @@ class CoinProtocol(MMGenObject): def viewkey(self, viewkey_str): raise NotImplementedError(f'{self.name} protocol does not support view keys') - def base_proto_subclass(self, cls, modname, sub_clsname=None, is_token=False): + def base_proto_subclass(self, cls, modname, *, sub_clsname=None, is_token=False): """ magic module loading and class selection """ @@ -281,6 +281,7 @@ class CoinProtocol(MMGenObject): def init_proto( cfg, coin = None, + *, testnet = False, regtest = False, network = None, diff --git a/mmgen/rpc.py b/mmgen/rpc.py index 28abc4eb..fe2bbd2c 100755 --- a/mmgen/rpc.py +++ b/mmgen/rpc.py @@ -30,7 +30,7 @@ from .objmethods import HiliteStr, InitErrors, MMGenObject auth_data = namedtuple('rpc_auth_data', ['user', 'passwd']) -def dmsg_rpc(fs, data=None, is_json=False): +def dmsg_rpc(fs, data=None, *, is_json=False): msg( fs if data is None else fs.format(pp_fmt(json.loads(data) if is_json else data)) @@ -255,7 +255,7 @@ class RPCClient(MMGenObject): network_proto = 'http' proxy = None - def __init__(self, cfg, host, port, test_connection=True): + def __init__(self, cfg, host, port, *, test_connection=True): self.cfg = cfg self.name = type(self).__name__ @@ -376,7 +376,7 @@ class RPCClient(MMGenObject): timeout = timeout, wallet = wallet) - def process_http_resp(self, run_ret, batch=False, json_rpc=True): + def process_http_resp(self, run_ret, *, batch=False, json_rpc=True): def float_parser(n): return n @@ -424,7 +424,7 @@ class RPCClient(MMGenObject): m = text die('RPCFailure', f'{s.value} {s.name}: {m}') - async def stop_daemon(self, quiet=False, silent=False): + async def stop_daemon(self, *, quiet=False, silent=False): if self.daemon.state == 'ready': if not (quiet or silent): msg(f'Stopping {self.daemon.desc} on port {self.daemon.bind_port}') @@ -437,10 +437,10 @@ class RPCClient(MMGenObject): msg(f'{self.daemon.desc} on port {self.daemon.bind_port} not running') return True - def start_daemon(self, silent=False): + def start_daemon(self, *, silent=False): return self.daemon.start(silent=silent) - async def restart_daemon(self, quiet=False, silent=False): + async def restart_daemon(self, *, quiet=False, silent=False): await self.stop_daemon(quiet=quiet, silent=silent) return self.daemon.start(silent=silent) @@ -467,6 +467,7 @@ class RPCClient(MMGenObject): async def rpc_init( cfg, proto = None, + *, backend = None, daemon = None, ignore_daemon_version = False, diff --git a/mmgen/seedsplit.py b/mmgen/seedsplit.py index 3add5f8e..5c84e11b 100755 --- a/mmgen/seedsplit.py +++ b/mmgen/seedsplit.py @@ -68,7 +68,7 @@ class SeedShareList(SubSeedList): count = ImmutableAttr(SeedShareCount) id_str = ImmutableAttr(SeedSplitIDString) - def __init__(self, parent_seed, count, id_str=None, master_idx=None, debug_last_share=False): + def __init__(self, parent_seed, count, *, id_str=None, master_idx=None, debug_last_share=False): self.member_type = SeedShare self.parent_seed = parent_seed self.id_str = id_str or 'default' @@ -118,7 +118,7 @@ class SeedShareList(SubSeedList): B = self.join().data assert A == B, f'Data mismatch!\noriginal seed: {A!r}\nrejoined seed: {B!r}' - def get_share_by_idx(self, idx, base_seed=False): + def get_share_by_idx(self, idx, *, base_seed=False): if idx < 1 or idx > self.count: die('RangeError', f'{idx}: share index out of range') elif idx == self.count: @@ -129,7 +129,7 @@ class SeedShareList(SubSeedList): ss_idx = SubSeedIdx(str(idx) + 'L') return self.get_subseed_by_ss_idx(ss_idx) - def get_share_by_seed_id(self, sid, base_seed=False): + def get_share_by_seed_id(self, sid, *, base_seed=False): if sid == self.data['long'].key(self.count-1): return self.last_share elif self.master_share and sid == self.data['long'].key(0): @@ -181,7 +181,7 @@ class SeedShareBase(MMGenObject): def desc(self): return self.get_desc() - def get_desc(self, ui=False): + def get_desc(self, *, ui=False): pl = self.parent_list mss = f', with master share #{pl.master_share.idx}' if pl.master_share else '' if ui: @@ -274,7 +274,7 @@ class SeedShareMaster(SeedBase, SeedShareBase): scramble_key = id_str.encode() + b':' + count.to_bytes(2, 'big') return Crypto(self.cfg).scramble_seed(self.data, scramble_key)[:self.byte_len] - def get_desc(self, ui=False): + def get_desc(self, *, ui=False): psid = self.parent_list.parent_seed.sid mss = f'master share #{self.idx} of ' return yellow('(' + mss) + psid.hl() + yellow(')') if ui else mss + psid diff --git a/mmgen/sha2.py b/mmgen/sha2.py index 5f8f8aae..c91261be 100755 --- a/mmgen/sha2.py +++ b/mmgen/sha2.py @@ -68,7 +68,7 @@ class Sha2: # First wordBits bits of the fractional parts of the cube roots of the first nRounds primes cls.K = tuple(getFractionalBits(cbrt(n)) for n in primes) - def __init__(self, message, preprocess=True): + def __init__(self, message, *, preprocess=True): 'Use preprocess=False for Sha256Compress' assert isinstance(message, (bytes, bytearray, list)), 'message must be of type bytes, bytearray or list' if not self.K: diff --git a/mmgen/subseed.py b/mmgen/subseed.py index 4bd2a222..282e5f9a 100755 --- a/mmgen/subseed.py +++ b/mmgen/subseed.py @@ -95,7 +95,7 @@ class SubSeedList(MMGenObject): def __len__(self): return len(self.data['long']) - def get_subseed_by_ss_idx(self, ss_idx_in, print_msg=False): + def get_subseed_by_ss_idx(self, ss_idx_in, *, print_msg=False): ss_idx = SubSeedIdx(ss_idx_in) if print_msg: msg_r('{} {} of {}...'.format( @@ -122,7 +122,7 @@ class SubSeedList(MMGenObject): assert seed.sid == sid, f'{seed.sid} != {sid}: Seed ID mismatch!' return seed - def get_subseed_by_seed_id(self, sid, last_idx=None, print_msg=False): + def get_subseed_by_seed_id(self, sid, *, last_idx=None, print_msg=False): def get_existing_subseed_by_seed_id(sid): for k in ('long', 'short') if self.have_short else ('long',): diff --git a/mmgen/term.py b/mmgen/term.py index 7b474061..543e5494 100755 --- a/mmgen/term.py +++ b/mmgen/term.py @@ -50,7 +50,7 @@ class MMGenTerm: pass @classmethod - def init(cls, noecho=False): + def init(cls, *, noecho=False): pass @classmethod @@ -93,7 +93,7 @@ class MMGenTermLinux(MMGenTerm): cls.cur_term = termios.tcgetattr(cls.stdin_fd) @classmethod - def init(cls, noecho=False): + def init(cls, *, noecho=False): cls.stdin_fd = sys.stdin.fileno() cls.cur_term = termios.tcgetattr(cls.stdin_fd) if not hasattr(cls, 'orig_term'): @@ -128,7 +128,7 @@ class MMGenTermLinux(MMGenTerm): break @classmethod - def get_char(cls, prompt='', immed_chars='', prehold_protect=True, num_bytes=5): + def get_char(cls, prompt='', *, immed_chars='', prehold_protect=True, num_bytes=5): """ Use os.read(), not file.read(), to get a variable number of bytes without blocking. Request 5 bytes to cover escape sequences generated by F1, F2, .. Fn keys (5 bytes) @@ -169,7 +169,7 @@ class MMGenTermLinuxStub(MMGenTermLinux): pass @classmethod - def init(cls, noecho=False): + def init(cls, *, noecho=False): cls.stdin_fd = sys.stdin.fileno() @classmethod @@ -181,7 +181,7 @@ class MMGenTermLinuxStub(MMGenTermLinux): pass @classmethod - def get_char(cls, prompt='', immed_chars='', prehold_protect=None, num_bytes=5): + def get_char(cls, prompt='', *, immed_chars='', prehold_protect=None, num_bytes=5): msg_r(prompt) return os.read(0, num_bytes).decode() @@ -230,7 +230,7 @@ class MMGenTermMSWin(MMGenTerm): return @classmethod - def get_char(cls, prompt='', immed_chars='', prehold_protect=True, num_bytes=None): + def get_char(cls, prompt='', *, immed_chars='', prehold_protect=True, num_bytes=None): """ always return a single character, ignore num_bytes first character of 2-character sequence returned by F1-F12 keys is discarded @@ -268,7 +268,7 @@ class MMGenTermMSWin(MMGenTerm): class MMGenTermMSWinStub(MMGenTermMSWin): @classmethod - def get_char(cls, prompt='', immed_chars='', prehold_protect=None, num_bytes=None): + def get_char(cls, prompt='', *, immed_chars='', prehold_protect=None, num_bytes=None): """ Use stdin to allow UTF-8 and emulate the one-character behavior of MMGenTermMSWin """ @@ -289,7 +289,7 @@ def get_term(): 'win32': (MMGenTermMSWin if sys.stdin.isatty() else MMGenTermMSWinStub), }[sys.platform] -def init_term(cfg, noecho=False): +def init_term(cfg, *, noecho=False): term = get_term() diff --git a/mmgen/tool/coin.py b/mmgen/tool/coin.py index 39187b14..397dc709 100755 --- a/mmgen/tool/coin.py +++ b/mmgen/tool/coin.py @@ -113,7 +113,7 @@ class tool_cmd(tool_cmd_base): gd.ag.to_segwit_redeem_script(data), gd.ag.to_addr(data)) - def _privhex2out(self, privhex: 'sstr', output_pubhex=False): + def _privhex2out(self, privhex: 'sstr', *, output_pubhex=False): gd = self._init_generators() pk = PrivKey( self.proto, diff --git a/mmgen/tool/file.py b/mmgen/tool/file.py index 7e8d95dd..6dcaa608 100755 --- a/mmgen/tool/file.py +++ b/mmgen/tool/file.py @@ -36,7 +36,7 @@ class tool_cmd(tool_cmd_base): kwargs = {'skip_chksum_msg':True} if not obj.__name__ == 'PasswordList': kwargs.update({'key_address_validity_check':False}) - ret = obj(self.cfg, self.proto, mmgen_addrfile, **kwargs) + ret = obj(self.cfg, self.proto, infile=mmgen_addrfile, **kwargs) if self.cfg.verbose: from ..util import msg, capfirst if ret.al_id.mmtype.name == 'password': diff --git a/mmgen/tool/filecrypt.py b/mmgen/tool/filecrypt.py index 9554c69a..e6274d85 100755 --- a/mmgen/tool/filecrypt.py +++ b/mmgen/tool/filecrypt.py @@ -37,16 +37,16 @@ class tool_cmd(tool_cmd_base): """ def encrypt(self, infile: str, outfile='', hash_preset=''): "encrypt a file" - data = get_data_from_file(self.cfg, infile, 'data for encryption', binary=True) + data = get_data_from_file(self.cfg, infile, desc='data for encryption', binary=True) enc_d = Crypto(self.cfg).mmgen_encrypt(data, 'data', hash_preset) if not outfile: outfile = f'{os.path.basename(infile)}.{Crypto.mmenc_ext}' - write_data_to_file(self.cfg, outfile, enc_d, 'encrypted data', binary=True) + write_data_to_file(self.cfg, outfile, enc_d, desc='encrypted data', binary=True) return True def decrypt(self, infile: str, outfile='', hash_preset=''): "decrypt a file" - enc_d = get_data_from_file(self.cfg, infile, 'encrypted data', binary=True) + enc_d = get_data_from_file(self.cfg, infile, desc='encrypted data', binary=True) while True: dec_d = Crypto(self.cfg).mmgen_decrypt(enc_d, 'data', hash_preset) if dec_d: @@ -59,5 +59,5 @@ class tool_cmd(tool_cmd_base): outfile = remove_extension(o, Crypto.mmenc_ext) if outfile == o: outfile += '.dec' - write_data_to_file(self.cfg, outfile, dec_d, 'decrypted data', binary=True) + write_data_to_file(self.cfg, outfile, dec_d, desc='decrypted data', binary=True) return True diff --git a/mmgen/tool/fileutil.py b/mmgen/tool/fileutil.py index 920fb38a..5502153c 100755 --- a/mmgen/tool/fileutil.py +++ b/mmgen/tool/fileutil.py @@ -32,6 +32,7 @@ class tool_cmd(tool_cmd_base): def find_incog_data(self, filename: str, incog_id: str, + *, keep_searching: 'continue search after finding data (ID collisions can yield false positives)' = False): "Use an Incog ID to find hidden incognito wallet data" @@ -65,7 +66,7 @@ class tool_cmd(tool_cmd_base): os.close(f) return True - def rand2file(self, outfile: str, nbytes: str, threads=4, silent=False): + def rand2file(self, outfile: str, nbytes: str, *, threads=4, silent=False): """ write ‘nbytes’ bytes of random data to specified file (dd-style byte specifiers supported) @@ -148,7 +149,7 @@ class tool_cmd(tool_cmd_base): return True - def decrypt_keystore(self, wallet_file: str, output_hex=False): + def decrypt_keystore(self, wallet_file: str, *, output_hex=False): "decrypt the data in a keystore wallet, returning the decrypted data in binary format" from ..ui import line_input passwd = line_input(self.cfg, 'Enter passphrase: ', echo=self.cfg.echo_passphrase).strip().encode() @@ -159,9 +160,9 @@ class tool_cmd(tool_cmd_base): ret = decrypt_keystore(data[0]['keystore'], passwd) return ret.hex() if output_hex else ret - def decrypt_geth_keystore(self, wallet_file: str, check_addr=True): + def decrypt_geth_keystore(self, wallet_file: str, *, check_addr=True): "decrypt the private key in a Geth keystore wallet, returning the decrypted key in hex format" from ..ui import line_input passwd = line_input(self.cfg, 'Enter passphrase: ', echo=self.cfg.echo_passphrase).strip().encode() from ..proto.eth.misc import decrypt_geth_keystore - return decrypt_geth_keystore(self.cfg, wallet_file, passwd, check_addr).hex() + return decrypt_geth_keystore(self.cfg, wallet_file, passwd, check_addr=check_addr).hex() diff --git a/mmgen/tool/mnemonic.py b/mmgen/tool/mnemonic.py index cd201c23..81ef6e8b 100755 --- a/mmgen/tool/mnemonic.py +++ b/mmgen/tool/mnemonic.py @@ -98,14 +98,15 @@ class tool_cmd(tool_cmd_base): if fmt == 'xmrseed': hexstr = self._xmr_reduce(bytes.fromhex(hexstr)).hex() f = mnemonic_fmts[fmt] - return ' '.join(f.conv_cls(fmt).fromhex(hexstr, f.pad)) + return ' '.join(f.conv_cls(fmt).fromhex(hexstr, pad=f.pad)) def mn2hex(self, seed_mnemonic: 'sstr', fmt:mn_opts_disp = dfl_mnemonic_fmt): "convert a mnemonic seed phrase to a hexadecimal string" f = mnemonic_fmts[fmt] - return f.conv_cls(fmt).tohex(seed_mnemonic.split(), f.pad) + return f.conv_cls(fmt).tohex(seed_mnemonic.split(), pad=f.pad) def mn2hex_interactive(self, + *, fmt: mn_opts_disp = dfl_mnemonic_fmt, mn_len: 'length of seed phrase in words' = 24, print_mn: 'print the seed phrase after entry' = False): @@ -122,6 +123,7 @@ class tool_cmd(tool_cmd_base): return mnemonic_fmts[fmt].conv_cls(fmt).check_wordlist(self.cfg) def mn_printlist(self, + *, fmt: mn_opts_disp = dfl_mnemonic_fmt, enum: 'enumerate the list' = False, pager: 'send output to pager' = False): diff --git a/mmgen/tool/rpc.py b/mmgen/tool/rpc.py index 6d95a672..52f7016a 100755 --- a/mmgen/tool/rpc.py +++ b/mmgen/tool/rpc.py @@ -50,7 +50,7 @@ class tool_cmd(tool_cmd_base): r = await rpc_init(self.cfg, self.proto, ignore_daemon_version=True, ignore_wallet=True) return f'{d.coind_name} version {r.daemon_version} ({r.daemon_version_str})' - async def getbalance(self, + async def getbalance(self, *, minconf: 'minimum number of confirmations' = 1, quiet: 'produce quieter output' = False, pager: 'send output to pager' = False): @@ -81,7 +81,7 @@ class tool_cmd(tool_cmd_base): return ret - async def twview(self, + async def twview(self, *, pager: 'send output to pager' = False, reverse: 'reverse order of unspent outputs' = False, wide: 'display data in wide tabular format' = False, @@ -98,7 +98,7 @@ class tool_cmd(tool_cmd_base): obj, pager, reverse, wide, sort, age_fmt, interactive, show_mmid = show_mmid) - async def txhist(self, + async def txhist(self, *, pager: 'send output to pager' = False, reverse: 'reverse order of transactions' = False, detail: 'produce detailed, non-tabular output' = False, @@ -114,6 +114,7 @@ class tool_cmd(tool_cmd_base): async def listaddress(self, mmgen_addr: str, + *, wide: 'display data in wide tabular format' = False, minconf: 'minimum number of confirmations' = 1, showcoinaddr: 'display coin address in addition to MMGen ID' = True, @@ -127,7 +128,7 @@ class tool_cmd(tool_cmd_base): showcoinaddrs = showcoinaddr, age_fmt = age_fmt) - async def listaddresses(self, + async def listaddresses(self, *, pager: 'send output to pager' = False, reverse: 'reverse order of unspent outputs' = False, wide: 'display data in wide tabular format' = False, @@ -204,7 +205,7 @@ class tool_cmd(tool_cmd_base): await (await TwCtl(self.cfg, self.proto, mode='w')).rescan_blockchain(start_block, stop_block) return True - async def twexport(self, + async def twexport(self, *, include_amts = True, pretty = False, prune = False, @@ -242,7 +243,7 @@ class tool_cmd(tool_cmd_base): force_overwrite = force) return True - async def twimport(self, filename: str, ignore_checksum=False, batch=False): + async def twimport(self, filename: str, *, ignore_checksum=False, batch=False): """ restore a tracking wallet from a JSON dump created by ‘twexport’ diff --git a/mmgen/tool/util.py b/mmgen/tool/util.py index 95333bde..8dd4d1bf 100755 --- a/mmgen/tool/util.py +++ b/mmgen/tool/util.py @@ -57,6 +57,7 @@ class tool_cmd(tool_cmd_base): def to_bytespec(self, n: int, dd_style_byte_specifier: str, + *, fmt: 'width and precision of output' = '0.2', print_sym: 'print the specifier after the numerical value' = True, strip: 'strip trailing zeroes' = False, @@ -139,6 +140,7 @@ class tool_cmd(tool_cmd_base): # TODO: handle stdin def hash256(self, data: str, + *, file_input: 'first arg is the name of a file containing the data' = False, hex_input: 'first arg is a hexadecimal string' = False): "compute sha256(sha256(data)) (double sha256)" @@ -215,25 +217,26 @@ class tool_cmd(tool_cmd_base): def hextob32(self, hexstr: 'sstr', pad: 'pad output to this width' = 0): "convert a hexadecimal string to an MMGen-flavor base 32 string" from ..baseconv import baseconv - return baseconv('b32').fromhex(hexstr, pad, tostr=True) + return baseconv('b32').fromhex(hexstr, pad=pad, tostr=True) def b32tohex(self, b32_str: 'sstr', pad: 'pad output to this width' = 0): "convert an MMGen-flavor base 32 string to hexadecimal" from ..baseconv import baseconv - return baseconv('b32').tohex(b32_str.upper(), pad) + return baseconv('b32').tohex(b32_str.upper(), pad=pad) def hextob6d(self, hexstr: 'sstr', + *, pad: 'pad output to this width' = 0, add_spaces: 'add a space after every 5th character' = True): "convert a hexadecimal string to die roll base6 (base6d)" from ..baseconv import baseconv from ..util2 import block_format - ret = baseconv('b6d').fromhex(hexstr, pad, tostr=True) + ret = baseconv('b6d').fromhex(hexstr, pad=pad, tostr=True) return block_format(ret, gw=5, cols=None).strip() if add_spaces else ret def b6dtohex(self, b6d_str: 'sstr', pad: 'pad output to this width' = 0): "convert a die roll base6 (base6d) string to hexadecimal" from ..baseconv import baseconv from ..util import remove_whitespace - return baseconv('b6d').tohex(remove_whitespace(b6d_str), pad) + return baseconv('b6d').tohex(remove_whitespace(b6d_str), pad=pad) diff --git a/mmgen/tool/wallet.py b/mmgen/tool/wallet.py index c4bf8278..2afc2588 100755 --- a/mmgen/tool/wallet.py +++ b/mmgen/tool/wallet.py @@ -43,19 +43,21 @@ class tool_cmd(tool_cmd_base): def get_subseed(self, subseed_idx: str, wallet=''): "get the Seed ID of a single subseed by Subseed Index for default or specified wallet" self.cfg._set_quiet(True) - return Wallet(self.cfg, self._get_seed_file(wallet)).seed.subseed(subseed_idx).sid + return Wallet(self.cfg, fn=self._get_seed_file(wallet)).seed.subseed(subseed_idx).sid def get_subseed_by_seed_id(self, seed_id: str, wallet='', last_idx=SubSeedList.dfl_len): "get the Subseed Index of a single subseed by Seed ID for default or specified wallet" self.cfg._set_quiet(True) - ret = Wallet(self.cfg, self._get_seed_file(wallet)).seed.subseed_by_seed_id(seed_id, last_idx) + ret = Wallet( + self.cfg, + fn = self._get_seed_file(wallet)).seed.subseed_by_seed_id(seed_id, last_idx=last_idx) return ret.ss_idx if ret else None def list_subseeds(self, subseed_idx_range: str, wallet=''): "list a range of subseed Seed IDs for default or specified wallet" self.cfg._set_quiet(True) from ..subseed import SubSeedIdxRange - return Wallet(self.cfg, self._get_seed_file(wallet)).seed.subseeds.format( + return Wallet(self.cfg, fn=self._get_seed_file(wallet)).seed.subseeds.format( *SubSeedIdxRange(subseed_idx_range)) def list_shares(self, @@ -65,8 +67,8 @@ class tool_cmd(tool_cmd_base): wallet = ''): "list the Seed IDs of the shares resulting from a split of default or specified wallet" self.cfg._set_quiet(True) - return Wallet(self.cfg, self._get_seed_file(wallet)).seed.split( - share_count, id_str, master_share).format() + return Wallet(self.cfg, fn=self._get_seed_file(wallet)).seed.split( + share_count, id_str=id_str, master_idx=master_share).format() def gen_key(self, mmgen_addr: str, wallet=''): "generate a single WIF key for specified MMGen address from default or specified wallet" @@ -82,7 +84,7 @@ class tool_cmd(tool_cmd_base): addr = MMGenID(self.proto, mmgen_addr) self.cfg._set_quiet(True) - ss = Wallet(self.cfg, self._get_seed_file(wallet)) + ss = Wallet(self.cfg, fn=self._get_seed_file(wallet)) if ss.seed.sid != addr.sid: from ..util import die diff --git a/mmgen/tw/addresses.py b/mmgen/tw/addresses.py index 8ea225be..65d329de 100755 --- a/mmgen/tw/addresses.py +++ b/mmgen/tw/addresses.py @@ -68,7 +68,7 @@ class TwAddresses(TwView): def coinaddr_list(self): return [d.addr for d in self.data] - async def __init__(self, cfg, proto, minconf=1, mmgen_addrs='', get_data=False): + async def __init__(self, cfg, proto, *, minconf=1, mmgen_addrs='', get_data=False): await super().__init__(cfg, proto) diff --git a/mmgen/tw/ctl.py b/mmgen/tw/ctl.py index 3b17a9b0..94c313d1 100755 --- a/mmgen/tw/ctl.py +++ b/mmgen/tw/ctl.py @@ -63,6 +63,7 @@ class TwCtl(MMGenObject, metaclass=AsyncInit): self, cfg, proto, + *, mode = 'r', token_addr = None, no_rpc = False, @@ -167,7 +168,7 @@ class TwCtl(MMGenObject, metaclass=AsyncInit): def data_root_desc(self): return self.data_key - def cache_balance(self, addr, bal, session_cache, data_root, force=False): + def cache_balance(self, addr, bal, *, session_cache, data_root, force=False): if force or addr not in session_cache: session_cache[addr] = str(bal) if addr in data_root: @@ -183,11 +184,11 @@ class TwCtl(MMGenObject, metaclass=AsyncInit): if addr in data_root and 'balance' in data_root[addr]: return self.proto.coin_amt(data_root[addr]['balance']) - async def get_balance(self, addr, force_rpc=False): + async def get_balance(self, addr, *, force_rpc=False): ret = None if force_rpc else self.get_cached_balance(addr, self.cur_balances, self.data_root) if ret is None: ret = await self.rpc_get_balance(addr) - self.cache_balance(addr, ret, self.cur_balances, self.data_root) + self.cache_balance(addr, ret, session_cache=self.cur_balances, data_root=self.data_root) return ret def force_write(self): @@ -212,7 +213,7 @@ class TwCtl(MMGenObject, metaclass=AsyncInit): self.orig_data = data - def write(self, quiet=True): + def write(self, *, quiet=True): if not self.use_tw_file: self.cfg._util.dmsg("'use_tw_file' is False, doing nothing") return @@ -256,6 +257,7 @@ class TwCtl(MMGenObject, metaclass=AsyncInit): self, addrspec, comment = '', + *, trusted_pair = None, silent = False): @@ -296,11 +298,11 @@ class TwCtl(MMGenObject, metaclass=AsyncInit): async def remove_comment(self, mmaddr): await self.set_comment(mmaddr, '') - async def import_address_common(self, data, batch=False, gather=False): + async def import_address_common(self, data, *, batch=False, gather=False): async def do_import(address, comment, message): try: - res = await self.import_address(address, comment) + res = await self.import_address(address, label=comment) self.cfg._util.qmsg(message) return res except Exception as e: diff --git a/mmgen/tw/json.py b/mmgen/tw/json.py index 01259b9a..b7608f7d 100755 --- a/mmgen/tw/json.py +++ b/mmgen/tw/json.py @@ -30,7 +30,8 @@ class TwJSON: fn_pfx = 'mmgen-tracking-wallet-dump' def __new__(cls, cfg, proto, *args, **kwargs): - return MMGenObject.__new__(proto.base_proto_subclass(TwJSON, 'tw.json', cls.__name__)) + return MMGenObject.__new__( + proto.base_proto_subclass(TwJSON, 'tw.json', sub_clsname=cls.__name__)) def __init__(self, cfg, proto): self.cfg = cfg @@ -62,7 +63,7 @@ class TwJSON: return fn - def json_dump(self, data, pretty=False): + def json_dump(self, data, *, pretty=False): return json.dumps( data, cls = json_encoder, @@ -90,6 +91,7 @@ class TwJSON: cfg, proto, filename, + *, ignore_checksum = False, batch = False): @@ -163,6 +165,7 @@ class TwJSON: self, cfg, proto, + *, include_amts = True, pretty = False, prune = False, diff --git a/mmgen/tw/view.py b/mmgen/tw/view.py index c38b1d60..42d0db00 100755 --- a/mmgen/tw/view.py +++ b/mmgen/tw/view.py @@ -250,14 +250,14 @@ class TwView(MMGenObject, metaclass=AsyncInit): 'twmmid': lambda i: '{} {:010} {:024.12f}'.format(i.twmmid.sort_key, 0xffffffff - abs(i.confs), i.amt) } - def sort_info(self, include_group=True): + def sort_info(self, *, include_group=True): ret = ([], ['Reverse'])[self.reverse] ret.append(self.sort_disp[self.sort_key]) if include_group and self.group and (self.sort_key in ('addr', 'txid', 'twmmid')): ret.append('Grouped') return ret - def do_sort(self, key=None, reverse=False): + def do_sort(self, key=None, *, reverse=False): key = key or self.sort_key if key not in self.sort_funcs: die(1, f'{key!r}: invalid sort key. Valid options: {" ".join(self.sort_funcs)}') @@ -268,7 +268,7 @@ class TwView(MMGenObject, metaclass=AsyncInit): if self.data != save: self.pos = 0 - async def get_data(self, sort_key=None, reverse_sort=False): + async def get_data(self, *, sort_key=None, reverse_sort=False): rpc_data = await self.get_rpc_data() @@ -390,6 +390,7 @@ class TwView(MMGenObject, metaclass=AsyncInit): async def format( self, display_type, + *, color = True, interactive = False, line_processing = None, diff --git a/mmgen/tx/base.py b/mmgen/tx/base.py index b0f309ad..f880c3e8 100755 --- a/mmgen/tx/base.py +++ b/mmgen/tx/base.py @@ -181,7 +181,8 @@ class Base(MMGenObject): def add_comment(self, infile=None): if infile: from ..fileutil import get_data_from_file - self.comment = MMGenTxComment(get_data_from_file(self.cfg, infile, 'transaction comment')) + self.comment = MMGenTxComment( + get_data_from_file(self.cfg, infile, desc='transaction comment')) else: from ..ui import keypress_confirm, line_input if keypress_confirm( diff --git a/mmgen/tx/file.py b/mmgen/tx/file.py index 4a105a6f..a4181197 100755 --- a/mmgen/tx/file.py +++ b/mmgen/tx/file.py @@ -80,10 +80,10 @@ class MMGenTxFile(MMGenObject): self.fmt_data = None self.filename = None - def parse(self, infile, metadata_only=False, quiet_open=False): + def parse(self, infile, *, metadata_only=False, quiet_open=False): tx = self.tx from ..fileutil import get_data_from_file - data = get_data_from_file(tx.cfg, infile, f'{tx.desc} data', quiet=quiet_open) + data = get_data_from_file(tx.cfg, infile, desc=f'{tx.desc} data', quiet=quiet_open) if len(data) > tx.cfg.max_tx_file_size: die('MaxFileSizeExceeded', f'Transaction file size exceeds limit ({tx.cfg.max_tx_file_size} bytes)') @@ -286,7 +286,7 @@ class MMGenTxFile(MMGenObject): return fmt_data - def write(self, + def write(self, *, add_desc = '', outdir = None, ask_write = True, @@ -316,7 +316,7 @@ class MMGenTxFile(MMGenObject): ignore_opt_outdir = outdir) @classmethod - def get_proto(cls, cfg, filename, quiet_open=False): + def get_proto(cls, cfg, filename, *, quiet_open=False): from . import BaseTX tmp_tx = BaseTX(cfg=cfg) cls(tmp_tx).parse(filename, metadata_only=True, quiet_open=quiet_open) diff --git a/mmgen/tx/info.py b/mmgen/tx/info.py index 0ba44627..91faf417 100755 --- a/mmgen/tx/info.py +++ b/mmgen/tx/info.py @@ -25,7 +25,7 @@ class TxInfo: self.cfg = cfg self.tx = tx - def format(self, terse=False, sort='addr'): + def format(self, *, terse=False, sort='addr'): tx = self.tx @@ -115,7 +115,7 @@ class TxInfo: return ''.join(gen_view()) - def view_with_prompt(self, prompt, pause=True): + def view_with_prompt(self, prompt, *, pause=True): prompt += ' (y)es, (N)o, pager (v)iew, (t)erse view: ' from ..term import get_char while True: @@ -131,7 +131,7 @@ class TxInfo: break msg('Invalid reply') - def view(self, pager=False, pause=True, terse=False): + def view(self, *, pager=False, pause=True, terse=False): o = self.format(terse=terse) if pager: from ..ui import do_pager diff --git a/mmgen/tx/new.py b/mmgen/tx/new.py index 53acffed..903d9918 100755 --- a/mmgen/tx/new.py +++ b/mmgen/tx/new.py @@ -164,7 +164,7 @@ class New(Base): return False return True - def add_output(self, coinaddr, amt, is_chg=False, is_vault=False, data=None): + def add_output(self, coinaddr, amt, *, is_chg=False, is_vault=False, data=None): self.outputs.append( self.Output(self.proto, addr=coinaddr, amt=amt, is_chg=is_chg, is_vault=is_vault, data=data)) @@ -197,7 +197,7 @@ class New(Base): return _pa(arg, mmid, coin_addr, amt, None, is_vault) - async def get_autochg_addr(self, proto, arg, exclude, desc, all_addrtypes=False): + async def get_autochg_addr(self, proto, arg, *, exclude, desc, all_addrtypes=False): from ..tw.addresses import TwAddresses al = await TwAddresses(self.cfg, proto, get_data=True) @@ -287,7 +287,7 @@ class New(Base): for addrfile in addrfiles: check_infile(addrfile) try: - ad_f.add(AddrList(self.cfg, proto, addrfile)) + ad_f.add(AddrList(self.cfg, proto, infile=addrfile)) except Exception as e: msg(f'{type(e).__name__}: {e}') return ad_f @@ -419,7 +419,7 @@ class New(Base): else: self.warn_insufficient_funds(funds.amt, self.coin) - async def create(self, cmd_args, locktime=None, do_info=False, caller='txcreate'): + async def create(self, cmd_args, *, locktime=None, do_info=False, caller='txcreate'): assert isinstance(locktime, (int, type(None))), 'locktime must be of type int' diff --git a/mmgen/tx/sign.py b/mmgen/tx/sign.py index 5da919eb..408178f2 100755 --- a/mmgen/tx/sign.py +++ b/mmgen/tx/sign.py @@ -37,7 +37,7 @@ def get_seed_for_seed_id(sid, infiles, saved_seeds): subseeds_checked = False while True: if infiles: - seed = Wallet(cfg, infiles.pop(0), ignore_in_fmt=True, passwd_file=global_passwd_file).seed + seed = Wallet(cfg, fn=infiles.pop(0), ignore_in_fmt=True, passwd_file=global_passwd_file).seed elif subseeds_checked is False: seed = saved_seeds[list(saved_seeds)[0]].subseed_by_seed_id(sid, print_msg=True) subseeds_checked = True @@ -128,7 +128,7 @@ def get_tx_files(cfg, args): die(1, 'You must specify a raw transaction file!') return ret -def get_seed_files(cfg, args, ignore_dfl_wallet=False, empty_ok=False): +def get_seed_files(cfg, args, *, ignore_dfl_wallet=False, empty_ok=False): # favor unencrypted seed sources first, as they don't require passwords ret = _pop_matching_fns(args, get_wallet_extensions('unenc')) from ..filename import find_file_in_dir @@ -142,13 +142,13 @@ def get_seed_files(cfg, args, ignore_dfl_wallet=False, empty_ok=False): def get_keyaddrlist(cfg, proto): if cfg.mmgen_keys_from_file: - return KeyAddrList(cfg, proto, cfg.mmgen_keys_from_file) + return KeyAddrList(cfg, proto, infile=cfg.mmgen_keys_from_file) return None def get_keylist(cfg): if cfg.keys_from_file: from ..fileutil import get_lines_from_file - return get_lines_from_file(cfg, cfg.keys_from_file, 'key-address data', trim_comments=True) + return get_lines_from_file(cfg, cfg.keys_from_file, desc='key-address data', trim_comments=True) return None async def txsign(cfg_parm, tx, seed_files, kl, kal, tx_num_str='', passwd_file=None): diff --git a/mmgen/ui.py b/mmgen/ui.py index 3a5f48a4..4a714226 100755 --- a/mmgen/ui.py +++ b/mmgen/ui.py @@ -38,7 +38,7 @@ def get_data_from_user(cfg, desc='data'): # user input MUST be UTF-8 msg(f'User input: [{data}]') return data -def line_input(cfg, prompt, echo=True, insert_txt='', hold_protect=True): +def line_input(cfg, prompt, *, echo=True, insert_txt='', hold_protect=True): """ multi-line prompts OK one-line prompts must begin at beginning of line @@ -83,6 +83,7 @@ def line_input(cfg, prompt, echo=True, insert_txt='', hold_protect=True): def keypress_confirm( cfg, prompt, + *, default_yes = False, verbose = False, no_nl = False, @@ -133,7 +134,7 @@ def do_pager(text): Msg(text+end_msg) set_vt100() -def do_license_msg(cfg, immed=False): +def do_license_msg(cfg, *, immed=False): if cfg.quiet or cfg.no_license or cfg.yes or not cfg.stdin_tty: return diff --git a/mmgen/util.py b/mmgen/util.py index ede3ae6e..b52bd270 100755 --- a/mmgen/util.py +++ b/mmgen/util.py @@ -69,6 +69,7 @@ class Util: desc1, chk2, desc2, + *, hdr = '', die_on_fail = False, verbose = False): @@ -156,7 +157,7 @@ def mdie(*args): mmsg(*args) sys.exit(0) -def die(ev, s='', stdout=False): +def die(ev, s='', *, stdout=False): if isinstance(ev, int): from .exception import MMGenSystemExit, MMGenError if ev <= 2: @@ -242,7 +243,7 @@ def list_gen(*data): yield d[idx] return list(gen()) -def remove_dups(iterable, edesc='element', desc='list', quiet=False, hide=False): +def remove_dups(iterable, *, edesc='element', desc='list', quiet=False, hide=False): """ Remove duplicate occurrences of iterable elements, preserving first occurrence If iterable is a generator, return a list, else type(iterable) @@ -292,7 +293,7 @@ def remove_extension(fn, ext): a, b = os.path.splitext(fn) return a if b[1:] == ext else fn -def make_chksum_N(s, nchars, sep=False, rounds=2, upper=True): +def make_chksum_N(s, nchars, *, sep=False, rounds=2, upper=True): if isinstance(s, str): s = s.encode() from hashlib import sha256 @@ -306,7 +307,7 @@ def make_chksum_N(s, nchars, sep=False, rounds=2, upper=True): assert 4 <= nchars <= 64, 'illegal ‘nchars’ value' return ret.upper() if upper else ret -def make_chksum_8(s, sep=False): +def make_chksum_8(s, *, sep=False): from .obj import HexStr from hashlib import sha256 s = HexStr(sha256(sha256(s).digest()).hexdigest()[:8].upper(), case='upper') @@ -396,7 +397,7 @@ class oneshot_warning: color = 'nocolor' - def __init__(self, div=None, fmt_args=[], reverse=False): + def __init__(self, *, div=None, fmt_args=[], reverse=False): self.do(type(self), div, fmt_args, reverse) def do(self, wcls, div, fmt_args, reverse): @@ -422,10 +423,10 @@ class oneshot_warning: class oneshot_warning_group(oneshot_warning): - def __init__(self, wcls, div=None, fmt_args=[], reverse=False): + def __init__(self, wcls, *, div=None, fmt_args=[], reverse=False): self.do(getattr(self, wcls), div, fmt_args, reverse) -def get_subclasses(cls, names=False): +def get_subclasses(cls, *, names=False): def gen(cls): for i in cls.__subclasses__(): yield i @@ -456,7 +457,7 @@ def exit_if_mswin(feature): if sys.platform == 'win32': die(2, capfirst(feature) + ' not supported on the MSWin / MSYS2 platform') -def have_sudo(silent=False): +def have_sudo(*, silent=False): from subprocess import run, DEVNULL redir = DEVNULL if silent else None try: diff --git a/mmgen/util2.py b/mmgen/util2.py index 364a110d..1910ad26 100755 --- a/mmgen/util2.py +++ b/mmgen/util2.py @@ -33,7 +33,7 @@ def die_pause(ev=0, s=''): def cffi_override_fixup(): from cffi import FFI class FFI_override: - def cdef(self, csource, override=False, packed=False, pack=None): + def cdef(self, csource, *, override=False, packed=False, pack=None): self._cdef(csource, override=True, packed=packed, pack=pack) FFI.cdef = FFI_override.cdef @@ -92,7 +92,7 @@ bytespec_map = ( ('E', 1152921504606846976), ) -def int2bytespec(n, spec, fmt, print_sym=True, strip=False, add_space=False): +def int2bytespec(n, spec, fmt, *, print_sym=True, strip=False, add_space=False): def spec2int(spec): for k, v in bytespec_map: @@ -137,6 +137,7 @@ def format_elapsed_days_hr(t, now=None, cached={}): def format_elapsed_hr( t, + *, now = None, cached = {}, rel_now = True, @@ -177,7 +178,7 @@ def pretty_format(s, width=80, pfx=''): s = s[i+1:] return pfx + ('\n'+pfx).join(out) -def block_format(data, gw=2, cols=8, line_nums=None, data_is_hex=False): +def block_format(data, *, gw=2, cols=8, line_nums=None, data_is_hex=False): assert line_nums in (None, 'hex', 'dec'), "'line_nums' must be one of None, 'hex' or 'dec'" ln_fs = '{:06x}: ' if line_nums == 'hex' else '{:06}: ' bytes_per_chunk = gw @@ -192,7 +193,7 @@ def block_format(data, gw=2, cols=8, line_nums=None, data_is_hex=False): ).rstrip() + '\n' def pretty_hexdump(data, gw=2, cols=8, line_nums=None): - return block_format(data.hex(), gw, cols, line_nums, data_is_hex=True) + return block_format(data.hex(), gw=gw, cols=cols, line_nums=line_nums, data_is_hex=True) def decode_pretty_hexdump(data): pat = re.compile(fr'^[{hexdigits}]+:\s+') diff --git a/mmgen/wallet/__init__.py b/mmgen/wallet/__init__.py index 8c41934c..37848a95 100755 --- a/mmgen/wallet/__init__.py +++ b/mmgen/wallet/__init__.py @@ -47,6 +47,7 @@ _wd('words', 'MMGenMnemonic', 'mmwords', 'mnemonic', False, ('mmwor } def get_wallet_data( + *, wtype = None, fmt_code = None, ext = None, @@ -73,6 +74,7 @@ def get_wallet_data( def get_wallet_cls( wtype = None, + *, fmt_code = None, ext = None, die_on_fail = False): @@ -111,6 +113,7 @@ def _get_me(modname): def Wallet( cfg, + *, fn = None, ss = None, seed_bin = None, diff --git a/mmgen/wallet/base.py b/mmgen/wallet/base.py index f4cd6cf7..3dc340ba 100755 --- a/mmgen/wallet/base.py +++ b/mmgen/wallet/base.py @@ -79,7 +79,7 @@ class wallet(MMGenObject, metaclass=WalletMeta): self.fmt_data = get_data_from_file( self.cfg, self.infile.name, - self.desc, + desc = self.desc, binary = self.file_mode=='binary') elif self.in_data: self.fmt_data = self.in_data diff --git a/mmgen/wallet/incog_base.py b/mmgen/wallet/incog_base.py index bd940c85..1f42e52d 100755 --- a/mmgen/wallet/incog_base.py +++ b/mmgen/wallet/incog_base.py @@ -142,9 +142,9 @@ class wallet(wallet): return False def _verify_seed_oldfmt(self, seed): - m = f'Seed ID: {make_chksum_8(seed)}. Is the Seed ID correct?' + prompt = f'Seed ID: {make_chksum_8(seed)}. Is the Seed ID correct?' from ..ui import keypress_confirm - if keypress_confirm(self.cfg, m, True): + if keypress_confirm(self.cfg, prompt, default_yes=True): return seed else: return False diff --git a/mmgen/wallet/mnemonic.py b/mmgen/wallet/mnemonic.py index 814f756a..26c39ea5 100755 --- a/mmgen/wallet/mnemonic.py +++ b/mmgen/wallet/mnemonic.py @@ -53,8 +53,8 @@ class wallet(wallet): seed = self.seed.data bc = self.conv_cls(self.wl_id) - mn = bc.frombytes(seed, 'seed') - rev = bc.tobytes(mn, 'seed') + mn = bc.frombytes(seed, pad='seed') + rev = bc.tobytes(mn, pad='seed') # Internal error, so just die on fail self.cfg._util.compare_or_die(rev, 'recomputed seed', seed, 'original seed', e='Internal error') @@ -78,8 +78,8 @@ class wallet(wallet): msg(f'Invalid mnemonic: word #{n} is not in the {self.wl_id.upper()} wordlist') return False - seed = bc.tobytes(mn, 'seed') - rev = bc.frombytes(seed, 'seed') + seed = bc.tobytes(mn, pad='seed') + rev = bc.frombytes(seed, pad='seed') if len(seed) * 8 not in Seed.lens: msg('Invalid mnemonic (produces too large a number)') diff --git a/mmgen/xmrseed.py b/mmgen/xmrseed.py index d8ca91a4..dcccf038 100755 --- a/mmgen/xmrseed.py +++ b/mmgen/xmrseed.py @@ -77,7 +77,7 @@ class xmrseed(baseconv): return b''.join(gen()) - def frombytes(self, bytestr, pad=None, tostr=False): + def frombytes(self, bytestr, *, pad=None, tostr=False): assert pad is None, f"{pad}: invalid 'pad' argument (must be None)" desc = self.desc.short diff --git a/mmgen/xmrwallet/file/__init__.py b/mmgen/xmrwallet/file/__init__.py index 863ab2be..3c0d6e0c 100755 --- a/mmgen/xmrwallet/file/__init__.py +++ b/mmgen/xmrwallet/file/__init__.py @@ -60,5 +60,5 @@ class MoneroMMGenFile: def extract_data_from_file(self, cfg, fn): return json.loads( - get_data_from_file(cfg, str(fn), self.desc, silent=self.silent_load) + get_data_from_file(cfg, str(fn), desc=self.desc, silent=self.silent_load) )[self.data_label] diff --git a/mmgen/xmrwallet/file/outputs.py b/mmgen/xmrwallet/file/outputs.py index b1644839..42f403b3 100755 --- a/mmgen/xmrwallet/file/outputs.py +++ b/mmgen/xmrwallet/file/outputs.py @@ -45,7 +45,7 @@ class MoneroWalletOutputsFile: self.name = type(self).__name__ self.cfg = cfg - def write(self, add_suf='', quiet=False): + def write(self, *, add_suf='', quiet=False): from ...fileutil import write_data_to_file write_data_to_file( cfg = self.cfg, @@ -81,7 +81,7 @@ class MoneroWalletOutputsFile: class New(Base): ext = 'raw' - def __init__(self, parent, wallet_fn, data, wallet_idx=None, sign=False): + def __init__(self, parent, wallet_fn, data, *, wallet_idx=None, sign=False): super().__init__(parent.cfg) self.wallet_fn = wallet_fn init_data = dict.fromkeys(self.data_tuple._fields) @@ -115,7 +115,7 @@ class MoneroWalletOutputsFile: self.check_checksums(d_wrap) @classmethod - def find_fn_from_wallet_fn(cls, cfg, wallet_fn, ret_on_no_match=False): + def find_fn_from_wallet_fn(cls, cfg, wallet_fn, *, ret_on_no_match=False): path = get_autosign_obj(cfg).xmr_outputs_dir or Path() pat = cls.fn_fs.format( a = wallet_fn.name, diff --git a/mmgen/xmrwallet/file/tx.py b/mmgen/xmrwallet/file/tx.py index 6ba5e1cd..aa469033 100755 --- a/mmgen/xmrwallet/file/tx.py +++ b/mmgen/xmrwallet/file/tx.py @@ -153,7 +153,7 @@ class MoneroMMGenTX: def file_id(self): return (self.base_chksum + ('-' + self.full_chksum if self.full_chksum else '')).upper() - def write(self, delete_metadata=False, ask_write=True, ask_overwrite=True): + def write(self, *, delete_metadata=False, ask_write=True, ask_overwrite=True): dict_data = self.data._asdict() if delete_metadata: dict_data['metadata'] = None diff --git a/mmgen/xmrwallet/ops/import.py b/mmgen/xmrwallet/ops/import.py index c85728fe..32eda45e 100755 --- a/mmgen/xmrwallet/ops/import.py +++ b/mmgen/xmrwallet/ops/import.py @@ -23,7 +23,7 @@ class OpImportOutputs(OpWallet): action = 'importing wallet outputs into' start_daemon = False - async def main(self, fn, wallet_idx, restart_daemon=True): + async def main(self, fn, wallet_idx, *, restart_daemon=True): if restart_daemon: await self.restart_wallet_daemon() h = MoneroWalletRPC(self, self.addr_data[0]) diff --git a/mmgen/xmrwallet/ops/relay.py b/mmgen/xmrwallet/ops/relay.py index 285c0f39..4fd9b9f4 100755 --- a/mmgen/xmrwallet/ops/relay.py +++ b/mmgen/xmrwallet/ops/relay.py @@ -41,7 +41,7 @@ class OpRelay(OpBase): md = None else: from ...daemon import CoinDaemon - md = CoinDaemon(self.cfg, 'xmr', test_suite=self.cfg.test_suite) + md = CoinDaemon(self.cfg, network_id='xmr', test_suite=self.cfg.test_suite) host, port = ('localhost', md.rpc_port) proxy = None diff --git a/mmgen/xmrwallet/ops/sign.py b/mmgen/xmrwallet/ops/sign.py index 2b41a7d3..26926953 100755 --- a/mmgen/xmrwallet/ops/sign.py +++ b/mmgen/xmrwallet/ops/sign.py @@ -21,7 +21,7 @@ class OpSign(OpWallet): action = 'signing transaction with' start_daemon = False - async def main(self, fn, restart_daemon=True): + async def main(self, fn, *, restart_daemon=True): if restart_daemon: await self.restart_wallet_daemon() tx = MoneroMMGenTX.Unsigned(self.cfg, fn) diff --git a/mmgen/xmrwallet/ops/wallet.py b/mmgen/xmrwallet/ops/wallet.py index 5e3241d0..98f81a9c 100755 --- a/mmgen/xmrwallet/ops/wallet.py +++ b/mmgen/xmrwallet/ops/wallet.py @@ -140,7 +140,7 @@ class OpWallet(OpBase): return MoneroRPCClient( cfg = self.cfg, proto = self.proto, - daemon = CoinDaemon(self.cfg, 'xmr'), + daemon = CoinDaemon(self.cfg, network_id='xmr'), host = host, port = int(port), user = None, diff --git a/mmgen/xmrwallet/rpc.py b/mmgen/xmrwallet/rpc.py index 91754a92..1724cc48 100755 --- a/mmgen/xmrwallet/rpc.py +++ b/mmgen/xmrwallet/rpc.py @@ -62,7 +62,7 @@ class MoneroWalletRPC: await self.c.stop_daemon(quiet=True) # closes wallet gmsg_r('done') - def gen_accts_info(self, accts_data, addrs_data, indent=' ', skip_empty_ok=False): + def gen_accts_info(self, accts_data, addrs_data, *, indent=' ', skip_empty_ok=False): from .ops import addr_width fs = indent + ' {I:<3} {A} {N} {B} {L}' yield indent + f'Accounts of wallet {self.fn.name}:' @@ -84,7 +84,7 @@ class MoneroWalletRPC: B = fmt_amt(e['unlocked_balance']), L = pink(e['label'])) - def get_wallet_data(self, print=True, skip_empty_ok=False): + def get_wallet_data(self, *, print=True, skip_empty_ok=False): accts_data = self.c.call('get_accounts') addrs_data = [ self.c.call('get_address', account_index=i) @@ -123,7 +123,7 @@ class MoneroWalletRPC: msg(cyan(ret['address'])) return ret['address'] - def get_last_addr(self, account, wallet_data, display=True): + def get_last_addr(self, account, wallet_data, *, display=True): if display: msg('\n Getting last address:') acct_addrs = wallet_data.addrs_data[account]['addresses'] diff --git a/test/cmdtest_d/ct_ethdev.py b/test/cmdtest_d/ct_ethdev.py index 868ad91c..47ba4dab 100755 --- a/test/cmdtest_d/ct_ethdev.py +++ b/test/cmdtest_d/ct_ethdev.py @@ -426,7 +426,7 @@ class CmdTestEthdev(CmdTestBase, CmdTestShared): self.proto = init_proto( cfg, cfg.coin, network='regtest', need_amt=True) from mmgen.daemon import CoinDaemon - self.daemon = CoinDaemon( cfg, self.proto.coin+'_rt', test_suite=True) + self.daemon = CoinDaemon( cfg, network_id=self.proto.coin+'_rt', test_suite=True) if self.daemon.id == 'reth': global dfl_devkey, dfl_devaddr diff --git a/test/cmdtest_d/ct_main.py b/test/cmdtest_d/ct_main.py index 98041657..d445f8d7 100755 --- a/test/cmdtest_d/ct_main.py +++ b/test/cmdtest_d/ct_main.py @@ -68,7 +68,7 @@ def make_brainwallet_file(fn): d = ''.join(rand_pairs).rstrip() + '\n' if cfg.verbose: msg_r(f'Brainwallet password:\n{cyan(d)}') - write_data_to_file(cfg, fn, d, 'brainwallet password', quiet=True, ignore_opt_outdir=True) + write_data_to_file(cfg, fn, d, desc='brainwallet password', quiet=True, ignore_opt_outdir=True) def verify_checksum_or_exit(checksum, chk): chk = strip_ansi_escapes(chk) @@ -397,7 +397,7 @@ class CmdTestMain(CmdTestBase, CmdTestShared): addrfile = self.get_file_with_ext('addrs') from mmgen.addrlist import AddrList silence() - chk = AddrList(cfg, self.proto, addrfile).chksum + chk = AddrList(cfg, self.proto, infile=addrfile).chksum end_silence() if cfg.verbose and display: msg(f'Checksum: {cyan(chk)}') @@ -537,7 +537,7 @@ class CmdTestMain(CmdTestBase, CmdTestShared): cfg, self.unspent_data_file, d, - 'Unspent outputs', + desc = 'Unspent outputs', quiet = True, ignore_opt_outdir = True) if cfg.verbose or cfg.exact_output: @@ -633,7 +633,7 @@ class CmdTestMain(CmdTestBase, CmdTestShared): tx_data, ad = {}, AddrData(self.proto) for s in sources: addrfile = get_file_with_ext(self.cfgs[s]['tmpdir'], 'addrs') - al = AddrList(cfg, self.proto, addrfile) + al = AddrList(cfg, self.proto, infile=addrfile) ad.add(al) aix = AddrIdxList(fmt_str=self.cfgs[s]['addr_idx_list']) if len(aix) != addrs_per_wallet: @@ -849,7 +849,7 @@ class CmdTestMain(CmdTestBase, CmdTestShared): wcls = get_wallet_cls(fmt_code=out_fmt) msg('==> {}: {}'.format( wcls.desc, - cyan(get_data_from_file(cfg, f, wcls.desc)) + cyan(get_data_from_file(cfg, f, desc=wcls.desc)) )) end_silence() return t diff --git a/test/cmdtest_d/ct_regtest.py b/test/cmdtest_d/ct_regtest.py index ec79e65c..9c081b2d 100755 --- a/test/cmdtest_d/ct_regtest.py +++ b/test/cmdtest_d/ct_regtest.py @@ -498,7 +498,7 @@ class CmdTestRegtest(CmdTestBase, CmdTestShared): def _add_comments_to_addr_file(self, proto, addrfile, outfile, use_comments=False): silence() gmsg(f'Adding comments to address file {addrfile!r}') - a = AddrList(cfg, proto, addrfile) + a = AddrList(cfg, proto, infile=addrfile) for n, idx in enumerate(a.idxs(), 1): if use_comments: a.set_comment(idx, get_comment()) @@ -1110,7 +1110,7 @@ class CmdTestRegtest(CmdTestBase, CmdTestShared): sid, self.get_altcoin_pfx(proto.coin), id_str, addr_range, x='-α' if cfg.debug_utf8 else '') addrfile = get_file_with_ext(self._user_dir(user), ext, no_dot=True) silence() - addr = AddrList(cfg, proto, addrfile).data[idx].addr + addr = AddrList(cfg, proto, infile=addrfile).data[idx].addr end_silence() return addr diff --git a/test/cmdtest_d/ct_shared.py b/test/cmdtest_d/ct_shared.py index e193accb..009ebc37 100755 --- a/test/cmdtest_d/ct_shared.py +++ b/test/cmdtest_d/ct_shared.py @@ -295,7 +295,7 @@ class CmdTestShared: fn = t.written_to_file('Password list' if passgen else 'Addresses') cls = PasswordList if passgen else AddrList silence() - al = cls(cfg, self.proto, fn, skip_chksum_msg=True) # read back the file we’ve written + al = cls(cfg, self.proto, infile=fn, skip_chksum_msg=True) # read back the file we’ve written end_silence() cmp_or_die(al.chksum, chksum, desc=f'{ftype}list data checksum from file') return t diff --git a/test/cmdtest_d/ct_xmr_autosign.py b/test/cmdtest_d/ct_xmr_autosign.py index 45a5dfe8..46cd2237 100755 --- a/test/cmdtest_d/ct_xmr_autosign.py +++ b/test/cmdtest_d/ct_xmr_autosign.py @@ -133,7 +133,7 @@ class CmdTestXMRAutosign(CmdTestXMRWallet, CmdTestAutosignThreaded): cfg = self.cfg, proto = self.proto, addr_idxs = '1-2', - seed = Wallet(cfg, data.mmwords).seed, + seed = Wallet(cfg, fn=data.mmwords).seed, skip_chksum_msg = True, key_address_validity_check = False) kal.file.write(ask_overwrite=False) diff --git a/test/daemontest_d/ut_exec.py b/test/daemontest_d/ut_exec.py index 6a0799c7..b1b3ed01 100755 --- a/test/daemontest_d/ut_exec.py +++ b/test/daemontest_d/ut_exec.py @@ -14,7 +14,7 @@ from mmgen.daemon import CoinDaemon from ..include.common import cfg, qmsg, qmsg_r, vmsg, msg def test_flags(coin): - d = CoinDaemon(cfg, coin) + d = CoinDaemon(cfg, network_id=coin) vmsg(f'Available opts: {fmt_list(d.avail_opts, fmt="bare")}') vmsg(f'Available flags: {fmt_list(d.avail_flags, fmt="bare")}') vals = namedtuple('vals', ['online', 'no_daemonize', 'keep_cfg_file']) @@ -26,7 +26,7 @@ def test_flags(coin): (['online'], ['keep_cfg_file'], vals(True, False, True)), (['online', 'no_daemonize'], ['keep_cfg_file'], vals(True, True, True)), ): - d = CoinDaemon(cfg, coin, opts=opts, flags=flags) + d = CoinDaemon(cfg, network_id=coin, opts=opts, flags=flags) assert d.flag.keep_cfg_file == val.keep_cfg_file assert d.opt.online == val.online assert d.opt.no_daemonize == val.no_daemonize diff --git a/test/daemontest_d/ut_rpc.py b/test/daemontest_d/ut_rpc.py index f32ddb58..06da34d4 100755 --- a/test/daemontest_d/ut_rpc.py +++ b/test/daemontest_d/ut_rpc.py @@ -91,7 +91,7 @@ class init_test: @staticmethod async def btc(cfg, daemon, backend, cfg_override): - rpc = await rpc_init(cfg, daemon.proto, backend, daemon) + rpc = await rpc_init(cfg, daemon.proto, backend=backend, daemon=daemon) do_msg(rpc, backend) wi = await rpc.walletinfo @@ -106,7 +106,7 @@ class init_test: @staticmethod async def bch(cfg, daemon, backend, cfg_override): - rpc = await rpc_init(cfg, daemon.proto, backend, daemon) + rpc = await rpc_init(cfg, daemon.proto, backend=backend, daemon=daemon) do_msg(rpc, backend) return rpc @@ -114,7 +114,7 @@ class init_test: @staticmethod async def eth(cfg, daemon, backend, cfg_override): - rpc = await rpc_init(cfg, daemon.proto, backend, daemon) + rpc = await rpc_init(cfg, daemon.proto, backend=backend, daemon=daemon) do_msg(rpc, backend) await rpc.call('eth_blockNumber', timeout=300) if rpc.proto.network == 'testnet': diff --git a/test/daemontest_d/ut_tx.py b/test/daemontest_d/ut_tx.py index d57abba8..c6af05df 100755 --- a/test/daemontest_d/ut_tx.py +++ b/test/daemontest_d/ut_tx.py @@ -110,7 +110,7 @@ class unit_tests: async def newtx(self, name, ut): qmsg(' Testing NewTX initializer') - d = CoinDaemon(cfg, 'btc', test_suite=True) + d = CoinDaemon(cfg, network_id='btc', test_suite=True) d.start() proto = init_proto(cfg, 'btc', need_amt=True) diff --git a/test/gentest.py b/test/gentest.py index 737e3579..67025b48 100755 --- a/test/gentest.py +++ b/test/gentest.py @@ -322,7 +322,7 @@ def do_ab_test(proto, scfg, addr_type, gen1, kg2, ag, tool, cache_data): for _ in range(scfg.rounds): yield getrand(32) - kg1 = KeyGenerator(cfg, proto, addr_type.pubkey_type, gen1) + kg1 = KeyGenerator(cfg, proto, addr_type.pubkey_type, backend=gen1) if type(kg1) == type(kg2): die(4, 'Key generators are the same!') @@ -378,7 +378,7 @@ def ab_test(proto, scfg): if scfg.gen2: assert scfg.gen1 != 'all', "'all' must be used only with external tool" - kg2 = KeyGenerator(cfg, proto, addr_type.pubkey_type, scfg.gen2) + kg2 = KeyGenerator(cfg, proto, addr_type.pubkey_type, backend=scfg.gen2) tool = None else: toolname = find_or_check_tool(proto, addr_type, scfg.tool) @@ -541,7 +541,7 @@ def main(): for p in protos: ab_test(p, scfg) else: - kg = KeyGenerator(cfg, proto, addr_type.pubkey_type, scfg.gen1) + kg = KeyGenerator(cfg, proto, addr_type.pubkey_type, backend=scfg.gen1) ag = AddrGenerator(cfg, proto, addr_type) if scfg.test == 'speed': speed_test(proto, kg, ag, scfg.rounds) diff --git a/test/include/common.py b/test/include/common.py index 6c664aeb..f04657fd 100755 --- a/test/include/common.py +++ b/test/include/common.py @@ -307,7 +307,7 @@ def test_daemons_ops(*network_ids, op, remove_datadir=False): silent = not (cfg.verbose or cfg.exact_output) ret = False for network_id in network_ids: - d = CoinDaemon(cfg, network_id, test_suite=True) + d = CoinDaemon(cfg, network_id=network_id, test_suite=True) if remove_datadir: d.wait = True d.stop(silent=True) diff --git a/test/modtest_d/ut_bip_hd.py b/test/modtest_d/ut_bip_hd.py index 4a6c7631..568e8497 100755 --- a/test/modtest_d/ut_bip_hd.py +++ b/test/modtest_d/ut_bip_hd.py @@ -197,7 +197,7 @@ class unit_tests: coin_type1 = purpose.derive_private() - coin_type2 = m.to_coin_type('btc', addr_type='bech32') + coin_type2 = m.to_coin_type(coin='btc', addr_type='bech32') assert coin_type1.address == coin_type2.address vmsg(f' {coin_type1.address=}') diff --git a/test/modtest_d/ut_gen.py b/test/modtest_d/ut_gen.py index f6514029..0053f345 100755 --- a/test/modtest_d/ut_gen.py +++ b/test/modtest_d/ut_gen.py @@ -62,7 +62,7 @@ def do_test(proto, wif, addr_chk, addr_type, internal_keccak): for n, backend in enumerate(get_backends(at.pubkey_type)): - kg = KeyGenerator( cfg, proto, at.pubkey_type, n+1) + kg = KeyGenerator(cfg, proto, at.pubkey_type, silent=n+1) qmsg(blue(f' Testing backend {backend!r} for addr type {addr_type!r}{add_msg}')) data = kg.gen_data(privkey) diff --git a/test/modtest_d/ut_misc.py b/test/modtest_d/ut_misc.py index 81c7e0ca..5d95f0d9 100755 --- a/test/modtest_d/ut_misc.py +++ b/test/modtest_d/ut_misc.py @@ -50,7 +50,7 @@ class unit_tests: vmsg(brown(' vectors:')) vmsg(fs.format('REL_NOW', 'SHOW_SECS', 'ELAPSED', 'OUTPUT')) for (t, now, rel_now, show_secs, out_chk) in vectors: - out = format_elapsed_hr(t, now, rel_now=rel_now, show_secs=show_secs) + out = format_elapsed_hr(t, now=now, rel_now=rel_now, show_secs=show_secs) assert out == out_chk, f'{out} != {out_chk}' vmsg(fs.format(repr(rel_now), repr(show_secs), now-t, out)) diff --git a/test/modtest_d/ut_seedsplit.py b/test/modtest_d/ut_seedsplit.py index d00b2a65..fe488544 100755 --- a/test/modtest_d/ut_seedsplit.py +++ b/test/modtest_d/ut_seedsplit.py @@ -73,7 +73,7 @@ class unit_test: (2, c, c, d, i), (5, e, f, h, p)): - shares = seed.split(share_count, id_str, master_idx) + shares = seed.split(share_count, id_str=id_str, master_idx=master_idx) A = len(shares) assert A == share_count, A