diff --git a/mmgen/addrdata.py b/mmgen/addrdata.py index 2692529a..b302b40e 100755 --- a/mmgen/addrdata.py +++ b/mmgen/addrdata.py @@ -74,7 +74,7 @@ class TwAddrData(AddrData,metaclass=AsyncInit): async def __init__(self,proto,twctl=None): from .rpc import rpc_init from .tw.shared import TwLabel - from .globalvars import g + from .globalvars import gc from .seed import SeedID self.proto = proto self.rpc = await rpc_init(proto) @@ -86,7 +86,7 @@ class TwAddrData(AddrData,metaclass=AsyncInit): if l and l.mmid.type == 'mmgen': obj = l.mmid.obj if len(addr_array) != 1: - message = self.msgs['multiple_acct_addrs'].strip().format( acct=acct, proj=g.proj_name ) + message = self.msgs['multiple_acct_addrs'].strip().format( acct=acct, proj=gc.proj_name ) die(3, fmt( message, indent=' ' )) al_id = AddrListID( sid = SeedID(sid=obj.sid), @@ -96,7 +96,7 @@ class TwAddrData(AddrData,metaclass=AsyncInit): out[al_id].append(AddrListEntry(self.proto,idx=obj.idx,addr=addr_array[0],comment=l.comment)) i += 1 - vmsg(f'{i} {g.proj_name} addresses found, {len(twd)} accounts total') + vmsg(f'{i} {gc.proj_name} addresses found, {len(twd)} accounts total') for al_id in out: self.add(AddrList( diff --git a/mmgen/addrfile.py b/mmgen/addrfile.py index 7ad0173f..83544ee9 100755 --- a/mmgen/addrfile.py +++ b/mmgen/addrfile.py @@ -87,8 +87,8 @@ class AddrFile(MMGenObject): self.file_header_mn.format(p.pw_fmt.upper()) if p.gen_passwds and p.pw_fmt in ('bip39','xmrseed') else self.file_header ).strip() - from .globalvars import g - out = [fh.format(pnm=g.proj_name,n=TwComment.max_screen_width) + '\n'] + from .globalvars import gc + out = [fh.format(pnm=gc.proj_name,n=TwComment.max_screen_width) + '\n'] if p.chksum: out.append(f'# {capfirst(p.desc)} data checksum for {p.id_str}: {p.chksum}') diff --git a/mmgen/altcoin.py b/mmgen/altcoin.py index 81c6cea5..b06828fd 100755 --- a/mmgen/altcoin.py +++ b/mmgen/altcoin.py @@ -36,6 +36,8 @@ altcoin.py - Coin constants for Bitcoin-derived altcoins # NBT: 150/191 c/u, 25/('B'), 26/('B') import sys + +from .globalvars import gc from .util import msg def test_equal(desc,a,b,*cdata): @@ -434,10 +436,9 @@ class CoinInfo(object): @classmethod def verify_core_coin_data(cls,quiet=False,verbose=False): from .protocol import CoinProtocol,init_proto - from .globalvars import g for network in ('mainnet','testnet'): - for coin in g.core_coins: + for coin in gc.core_coins: e = cls.get_entry(coin,network) if e: proto = init_proto(coin,testnet=network=='testnet') @@ -718,8 +719,7 @@ def init_genonly_altcoins(usr_coin=None,testnet=False): data[network] = CoinInfo.get_supported_coins(network) trust_level = 0 else: - from .globalvars import g - if usr_coin.lower() in g.core_coins: # core coin, so return immediately + if usr_coin.lower() in gc.core_coins: # core coin, so return immediately from .protocol import CoinProtocol return CoinProtocol.coins[usr_coin.lower()].trust_level for network in networks: diff --git a/mmgen/cfgfile.py b/mmgen/cfgfile.py index b1c5abeb..154fafdd 100755 --- a/mmgen/cfgfile.py +++ b/mmgen/cfgfile.py @@ -23,7 +23,7 @@ cfgfile: API for the MMGen runtime configuration file and related files import os,re from collections import namedtuple -from .globalvars import g +from .globalvars import g,gc from .util import msg,ymsg,suf,fmt,fmt_list,oneshot_warning,strip_comment,capfirst def mmgen_cfg_file(id_str): @@ -187,7 +187,7 @@ class CfgFileSampleSys(cfg_file_sample): else: # self.fn is used for error msgs only, so file need not exist on filesystem self.fn = os.path.join(os.path.dirname(__file__),'data',self.fn_base) - self.data = g.get_mmgen_data_file(self.fn_base).splitlines() + self.data = gc.get_mmgen_data_file(self.fn_base).splitlines() def make_metadata(self): return [f'# Version {self.cur_ver} {self.computed_chksum}'] diff --git a/mmgen/color.py b/mmgen/color.py index e95bcf11..92bc0b3e 100755 --- a/mmgen/color.py +++ b/mmgen/color.py @@ -47,8 +47,8 @@ def nocolor(s): def set_vt100(): 'hack to put term into VT100 mode under MSWin' - from .globalvars import g - if g.platform == 'win': + from .globalvars import gc + if gc.platform == 'win': from subprocess import run run([],shell=True) diff --git a/mmgen/crypto.py b/mmgen/crypto.py index 8087dd98..b9fef3f0 100755 --- a/mmgen/crypto.py +++ b/mmgen/crypto.py @@ -23,7 +23,7 @@ crypto: Random number, password hashing and symmetric encryption routines for th import os from collections import namedtuple -from .globalvars import g +from .globalvars import g,gc from .opts import opt from .util import ( msg, @@ -244,7 +244,7 @@ class Crypto: avg_prec = sum(len(t.split('.')[1]) for t in time_data) // len(time_data) - if avg_prec < g.min_time_precision: + if avg_prec < gc.min_time_precision: ymsg(f'WARNING: Avg. time precision of only {avg_prec} decimal points. User entropy quality is degraded!') ret = key_data + '\n' + '\n'.join(time_data) @@ -300,7 +300,7 @@ class Crypto: def get_hash_preset_from_user( self, - old_preset = g.dfl_hash_preset, + old_preset = gc.dfl_hash_preset, data_desc = 'data', prompt = None ): @@ -338,7 +338,7 @@ class Crypto: if opt.echo_passphrase: pw = ' '.join(get_words_from_user( f'Enter {pw_desc} for {data_desc}: ' )) else: - for i in range(g.passwd_max_tries): + for i in range(gc.passwd_max_tries): pw = ' '.join(get_words_from_user( f'Enter {pw_desc} for {data_desc}: ' )) pw_chk = ' '.join(get_words_from_user( f'Repeat {pw_desc}: ' )) dmsg(f'Passphrases: [{pw}] [{pw_chk}]') diff --git a/mmgen/daemon.py b/mmgen/daemon.py index d55b7996..999252d9 100755 --- a/mmgen/daemon.py +++ b/mmgen/daemon.py @@ -24,7 +24,7 @@ import os,time,importlib from subprocess import run,PIPE,CompletedProcess from collections import namedtuple -from .globalvars import g +from .globalvars import g,gc from .color import set_vt100 from .util import msg,Msg_r,ymsg,die,remove_dups,oneshot_warning from .flags import * @@ -51,7 +51,7 @@ class Daemon(Lockable): def __init__(self,opts=None,flags=None): - self.platform = g.platform + self.platform = gc.platform if self.platform == 'win': self.use_pidfile = False self.use_threads = True @@ -478,7 +478,7 @@ class CoinDaemon(Daemon): assert self.test_suite, 'datadir removal restricted to test suite' if self.state == 'stopped': run([ - ('rm' if g.platform == 'win' else '/bin/rm'), + ('rm' if gc.platform == 'win' else '/bin/rm'), '-rf', self.datadir ]) set_vt100() diff --git a/mmgen/filename.py b/mmgen/filename.py index 23bf7644..b4eff29c 100755 --- a/mmgen/filename.py +++ b/mmgen/filename.py @@ -43,8 +43,8 @@ class File: import stat if stat.S_ISBLK(st.st_mode): mode = (os.O_RDONLY,os.O_RDWR)[bool(write)] - from .globalvars import g - if g.platform == 'win': + from .globalvars import gc + if gc.platform == 'win': mode |= os.O_BINARY try: fd = os.open(fn, mode) diff --git a/mmgen/fileutil.py b/mmgen/fileutil.py index 856cfd67..9d277072 100755 --- a/mmgen/fileutil.py +++ b/mmgen/fileutil.py @@ -22,7 +22,7 @@ fileutil: Routines that read, write, execute or stat files import sys,os -from .globalvars import g +from .globalvars import g,gc from .color import set_vt100 from .util import ( msg, @@ -43,7 +43,7 @@ def check_or_create_dir(path): if os.getenv('MMGEN_TEST_SUITE'): from subprocess import run run([ - ('rm' if g.platform == 'win' else '/bin/rm'), + ('rm' if gc.platform == 'win' else '/bin/rm'), '-rf', path ]) set_vt100() @@ -205,7 +205,7 @@ def write_data_to_file( else: msg('Redirecting output to file') - if binary and g.platform == 'win': + if binary and gc.platform == 'win': import msvcrt msvcrt.setmode(sys.stdout.fileno(),os.O_BINARY) diff --git a/mmgen/globalvars.py b/mmgen/globalvars.py index 13d12a53..d719a432 100755 --- a/mmgen/globalvars.py +++ b/mmgen/globalvars.py @@ -29,6 +29,79 @@ def die(exit_val,s=''): sys.stderr.write(s+'\n') sys.exit(exit_val) +class GlobalConstants(Lockable): + """ + These values are non-configurable. They’re constant for a given machine, + user, executable and MMGen release. + """ + proj_name = 'MMGen' + proj_url = 'https://github.com/mmgen/mmgen' + author = 'The MMGen Project' + email = '' + Cdates = '2013-2023' + dfl_hash_preset = '3' + passwd_max_tries = 5 + min_screen_width = 80 + min_time_precision = 18 + + # must match CoinProtocol.coins + core_coins = ('btc','bch','ltc','eth','etc','zec','xmr') + + prog_name = os.path.basename(sys.argv[0]) + is_txprog = prog_name == 'mmgen-regtest' or prog_name.startswith('mmgen-tx') + + for k in ('linux','win','msys'): + if sys.platform.startswith(k): + platform = { 'linux':'linux', 'win':'win', 'msys':'win' }[k] + break + else: + die(1,f'{sys.platform!r}: platform not supported by {proj_name}') + + if os.getenv('HOME'): # Linux or MSYS2 + home_dir = os.getenv('HOME') + elif platform == 'win': # Windows without MSYS2 - not supported + die(1,f'$HOME not set! {proj_name} for Windows must be run in MSYS2 environment') + else: + die(2,'$HOME is not set! Unable to determine home directory') + + def get_mmgen_data_file(self,filename,package='mmgen'): + """ + this is an expensive import, so do only when required + """ + # Resource will be unpacked and then cleaned up if necessary, see: + # https://docs.python.org/3/library/importlib.html: + # Note: This module provides functionality similar to pkg_resources Basic + # Resource Access without the performance overhead of that package. + # https://importlib-resources.readthedocs.io/en/latest/migration.html + # https://setuptools.readthedocs.io/en/latest/pkg_resources.html + try: + from importlib.resources import files # Python 3.9 + except ImportError: + from importlib_resources import files + return files(package).joinpath('data',filename).read_text() + + @property + def version(self): + return self.get_mmgen_data_file( + filename = 'version', + package = 'mmgen_node_tools' if self.prog_name.startswith('mmnode-') else 'mmgen' + ).strip() + + @property + def release_date(self): + return self.get_mmgen_data_file(filename='release_date').strip() + +gc = GlobalConstants() + +class GlobalVars: + """ + These are used only by the test suite to redirect msg() and friends to /dev/null + """ + stdout = sys.stdout + stderr = sys.stderr + +gv = GlobalVars() + class GlobalConfig(Lockable): """ Set global vars to default values @@ -44,15 +117,6 @@ class GlobalConfig(Lockable): # Constants: - proj_name = 'MMGen' - proj_url = 'https://github.com/mmgen/mmgen' - prog_name = os.path.basename(sys.argv[0]) - author = 'The MMGen Project' - email = '' - Cdates = '2013-2023' - - is_txprog = prog_name == 'mmgen-regtest' or prog_name.startswith('mmgen-tx') - stdin_tty = sys.stdin.isatty() stdout = sys.stdout stderr = sys.stderr @@ -60,11 +124,9 @@ class GlobalConfig(Lockable): http_timeout = 60 err_disp_timeout = 0.7 short_disp_timeout = 0.3 - min_time_precision = 18 # Variables - these might be altered at runtime: - dfl_hash_preset = '3' usr_randchars = 30 fee_adjust = 1.0 @@ -134,27 +196,10 @@ class GlobalConfig(Lockable): os.getenv('MMGEN_FORCE_COLOR') ) - for k in ('linux','win','msys'): - if sys.platform.startswith(k): - platform = { 'linux':'linux', 'win':'win', 'msys':'win' }[k] - break - else: - die(1,f'{sys.platform!r}: platform not supported by {proj_name}') - - if os.getenv('HOME'): # Linux or MSYS2 - home_dir = os.getenv('HOME') - elif platform == 'win': # Windows without MSYS2 - not supported - die(1,f'$HOME not set! {proj_name} for Windows must be run in MSYS2 environment') - else: - die(2,'$HOME is not set! Unable to determine home directory') - daemon_data_dir = '' # set by user daemon_id = '' blacklisted_daemons = '' - # must match CoinProtocol.coins - core_coins = ('btc','bch','ltc','eth','etc','zec','xmr') - # global var sets user opt: global_sets_opt = ( 'autochg_ignore_labels', @@ -297,7 +342,7 @@ class GlobalConfig(Lockable): 'fee_estimate_mode': _ov('nocase_pfx', ['conservative','economical']), 'rpc_backend': _ov('nocase_pfx', ['auto','httplib','curl','aiohttp','requests']), } - if platform == 'win': + if gc.platform == 'win': _skip_type_check = ('stdout','stderr') auto_typeset_opts = { @@ -306,13 +351,10 @@ class GlobalConfig(Lockable): 'vsize_adj': float, } - min_screen_width = 80 minconf = 1 max_tx_file_size = 100000 max_input_size = 1024 * 1024 - passwd_max_tries = 5 - max_urandchars = 80 min_urandchars = 10 @@ -324,7 +366,7 @@ class GlobalConfig(Lockable): short_disp_timeout = 0.1 if os.getenv('MMGEN_TEST_SUITE_POPEN_SPAWN'): stdin_tty = True - if prog_name == 'unit_tests.py': + if gc.prog_name == 'unit_tests.py': _set_ok += ('debug_subseed',) _reset_ok += ('force_standalone_scrypt_module',) @@ -333,33 +375,6 @@ class GlobalConfig(Lockable): if name[:11] == 'MMGEN_DEBUG': os.environ[name] = '1' - def get_mmgen_data_file(self,filename,package='mmgen'): - """ - this is an expensive import, so do only when required - """ - # Resource will be unpacked and then cleaned up if necessary, see: - # https://docs.python.org/3/library/importlib.html: - # Note: This module provides functionality similar to pkg_resources Basic - # Resource Access without the performance overhead of that package. - # https://importlib-resources.readthedocs.io/en/latest/migration.html - # https://setuptools.readthedocs.io/en/latest/pkg_resources.html - try: - from importlib.resources import files # Python 3.9 - except ImportError: - from importlib_resources import files - return files(package).joinpath('data',filename).read_text() - - @property - def version(self): - return self.get_mmgen_data_file( - filename = 'version', - package = 'mmgen_node_tools' if self.prog_name.startswith('mmnode-') else 'mmgen' - ).strip() - - @property - def release_date(self): - return self.get_mmgen_data_file(filename='release_date').strip() - @property def data_dir_root(self): """ @@ -374,7 +389,7 @@ class GlobalConfig(Lockable): from test.include.common import get_test_data_dir self._data_dir_root = get_test_data_dir() else: - self._data_dir_root = os.path.join(self.home_dir,'.'+self.proj_name.lower()) + self._data_dir_root = os.path.join(gc.home_dir,'.'+gc.proj_name.lower()) return self._data_dir_root @property diff --git a/mmgen/help.py b/mmgen/help.py index 805cc2c7..95a8e2b8 100755 --- a/mmgen/help.py +++ b/mmgen/help.py @@ -20,7 +20,7 @@ help: help notes for MMGen suite commands """ -from .globalvars import g +from .globalvars import gc def help_notes_func(proto,opt,k): @@ -156,30 +156,30 @@ EXAMPLES: Send 0.123 {proto.coin} to an external {proto.name} address, returning the change to a specific MMGen address in the tracking wallet: - $ {g.prog_name} {sample_addr},0.123 01ABCDEF:{mmtype}:7 + $ {gc.prog_name} {sample_addr},0.123 01ABCDEF:{mmtype}:7 Same as above, but select the change address automatically: - $ {g.prog_name} {sample_addr},0.123 01ABCDEF:{mmtype} + $ {gc.prog_name} {sample_addr},0.123 01ABCDEF:{mmtype} Same as above, but select the change address automatically by address type: - $ {g.prog_name} {sample_addr},0.123 {mmtype} + $ {gc.prog_name} {sample_addr},0.123 {mmtype} Same as above, but reduce verbosity and specify fee of 20 satoshis per byte: - $ {g.prog_name} -q -f 20s {sample_addr},0.123 {mmtype} + $ {gc.prog_name} -q -f 20s {sample_addr},0.123 {mmtype} Send entire balance of selected inputs minus fee to an external {proto.name} address: - $ {g.prog_name} {sample_addr} + $ {gc.prog_name} {sample_addr} Send entire balance of selected inputs minus fee to first unused wallet address of specified type: - $ {g.prog_name} {mmtype} + $ {gc.prog_name} {mmtype} """ def txcreate(): @@ -235,9 +235,9 @@ must also be supplied on the command line if the data can't be found in the default wallet. """.format( wd = (f'{coind_exec()} wallet dump or ' if isinstance(proto,mainnet) else ''), - pnm = g.proj_name, + pnm = gc.proj_name, pnu = proto.name, - pnl = g.proj_name.lower() ) + pnl = gc.proj_name.lower() ) def seedsplit(): from .seedsplit import SeedShareIdx,SeedShareCount,MasterShareIdx diff --git a/mmgen/main.py b/mmgen/main.py index 22949d70..4465c0bb 100755 --- a/mmgen/main.py +++ b/mmgen/main.py @@ -29,9 +29,9 @@ def launch(mod,package='mmgen'): mod = 'addrgen' import sys,os - from .globalvars import g + from .globalvars import gc - if g.platform == 'linux' and sys.stdin.isatty(): + if gc.platform == 'linux' and sys.stdin.isatty(): import termios,atexit fd = sys.stdin.fileno() old = termios.tcgetattr(fd) diff --git a/mmgen/main_addrgen.py b/mmgen/main_addrgen.py index 0c274a73..a66bed7b 100755 --- a/mmgen/main_addrgen.py +++ b/mmgen/main_addrgen.py @@ -22,7 +22,7 @@ mmgen-addrgen: Generate a series or range of addresses from an MMGen """ import mmgen.opts as opts -from .globalvars import g +from .globalvars import g,gc from .opts import opt from .addr import MMGenAddrType from .addrfile import AddrFile @@ -30,7 +30,7 @@ from .wallet import Wallet import mmgen.addrlist -if g.prog_name == 'mmgen-keygen': +if gc.prog_name == 'mmgen-keygen': gen_what = 'keys' gen_clsname = 'KeyAddrList' gen_desc = 'secret keys' @@ -49,7 +49,7 @@ opts_data = { 'desc': """ Generate a range or list of {desc} from an {pnm} wallet, mnemonic, seed or brainwallet - """.format(desc=gen_desc,pnm=g.proj_name), + """.format(desc=gen_desc,pnm=gc.proj_name), 'usage':'[opts] [seed source] ', 'options': """ -h, --help Print this help message @@ -69,7 +69,7 @@ opts_data = { is required only for brainwallet and incognito inputs with non-standard (< {dsl}-bit) seed lengths. -p, --hash-preset= p Use the scrypt hash parameters defined by preset 'p' - for password hashing (default: '{g.dfl_hash_preset}') + for password hashing (default: '{gc.dfl_hash_preset}') -z, --show-hash-presets Show information on available hash presets -P, --passwd-file= f Get wallet passphrase from file 'f' -q, --quiet Produce quieter output; suppress some warnings @@ -111,9 +111,10 @@ FMT CODES: kgs=help_notes('keygen_backends'), coin_id=help_notes('coin_id'), dsl=help_notes('dfl_seed_len'), - pnm=g.proj_name, + pnm=gc.proj_name, what=gen_what, g=g, + gc=gc, ), 'notes': lambda help_notes,s: s.format( n_addrkey=note_addrkey, diff --git a/mmgen/main_addrimport.py b/mmgen/main_addrimport.py index f4c3367d..abda5c75 100755 --- a/mmgen/main_addrimport.py +++ b/mmgen/main_addrimport.py @@ -23,7 +23,7 @@ mmgen-addrimport: Import addresses into a MMGen coin daemon tracking wallet from collections import namedtuple import mmgen.opts as opts -from .globalvars import g +from .globalvars import gc from .opts import opt from .util import msg,qmsg,suf,die,fmt,async_run from .addrlist import AddrList,KeyAddrList @@ -31,7 +31,7 @@ from .tw.shared import TwLabel opts_data = { 'text': { - 'desc': f'Import addresses into an {g.proj_name} tracking wallet', + 'desc': f'Import addresses into an {gc.proj_name} tracking wallet', 'usage':'[opts] [MMGen address file]', 'options': """ -h, --help Print this help message @@ -78,8 +78,8 @@ addrimport_msgs = { by the number of addresses imported and typically takes just a few minutes. """, 'bad_args': f""" - You must specify either an {g.proj_name} address file, a single address with - the ‘--address’ option, or a flat list of non-{g.proj_name} addresses with + You must specify either an {gc.proj_name} address file, a single address with + the ‘--address’ option, or a flat list of non-{gc.proj_name} addresses with the ‘--addrlist’ option. """ } @@ -102,7 +102,7 @@ def parse_cmd_args(rpc,cmd_args): proto = proto, addrlist = get_lines_from_file( infile, - f'non-{g.proj_name} addresses', + 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 fc296270..b96a5626 100755 --- a/mmgen/main_passgen.py +++ b/mmgen/main_passgen.py @@ -22,7 +22,7 @@ mmgen-passgen: Generate a series or range of passwords from an MMGen """ import mmgen.opts as opts -from .globalvars import g +from .globalvars import g,gc from .opts import opt from .addrlist import AddrIdxList from .passwdlist import PasswordList @@ -35,7 +35,7 @@ opts_data = { 'sets': [('print_checksum',True,'quiet',True)], 'text': { 'desc': f""" - Generate a range or list of passwords from an {g.proj_name} wallet, + Generate a range or list of passwords from an {gc.proj_name} wallet, mnemonic, seed or brainwallet for the given ID string """, 'usage':'[opts] [seed source] ', @@ -57,7 +57,7 @@ opts_data = { is required only for brainwallet and incognito inputs with non-standard (< {dsl}-bit) seed lengths. -p, --hash-preset= p Use the scrypt hash parameters defined by preset 'p' - for password hashing (default: '{g.dfl_hash_preset}') + for password hashing (default: '{gc.dfl_hash_preset}') -z, --show-hash-presets Show information on available hash presets -P, --passwd-file= f Get wallet passphrase from file 'f' -q, --quiet Produce quieter output; suppress some warnings @@ -86,17 +86,17 @@ PASSWORD FORMATS: EXAMPLES: Generate ten base58 passwords of length {i58.dfl_len} for Alice's email account: - {g.prog_name} alice@nowhere.com 1-10 + {gc.prog_name} alice@nowhere.com 1-10 Generate ten base58 passwords of length 16 for Alice's email account: - {g.prog_name} --passwd-len=16 alice@nowhere.com 1-10 + {gc.prog_name} --passwd-len=16 alice@nowhere.com 1-10 Generate ten base32 passwords of length {i32.dfl_len} for Alice's email account: - {g.prog_name} --passwd-fmt=b32 alice@nowhere.com 1-10 + {gc.prog_name} --passwd-fmt=b32 alice@nowhere.com 1-10 Generate three BIP39 mnemonic seed phrases of length {i39.dfl_len} for Alice's Trezor device: - {g.prog_name} --passwd-fmt=bip39 mytrezor 1-3 + {gc.prog_name} --passwd-fmt=bip39 mytrezor 1-3 All passwords are cryptographically unlinkable with each other, including passwords with the same format but different length, so Alice needn't worry @@ -116,9 +116,10 @@ FMT CODES: }, 'code': { 'options': lambda help_notes,s: s.format( - g=g,pnm=g.proj_name, + g=g,pnm=gc.proj_name, dsl=help_notes('dfl_seed_len'), dpf=PasswordList.dfl_pw_fmt, + gc=gc, ), 'notes': lambda help_notes,s: s.format( o=opts,g=g,i58=pwi['b58'],i32=pwi['b32'],i39=pwi['bip39'], @@ -128,6 +129,7 @@ FMT CODES: n_bw=help_notes('brainwallet'), pfi=help_notes('password_formats'), n_fmt=help_notes('fmt_codes'), + gc=gc, ) } } @@ -178,7 +180,7 @@ if keypress_confirm('Encrypt password list?'): af.encrypt() af.write(binary=True,desc='encrypted password list') else: - if g.test_suite_popen_spawn and g.platform == 'win': + if g.test_suite_popen_spawn and gc.platform == 'win': import time time.sleep(0.1) af.write(desc='password list') diff --git a/mmgen/main_regtest.py b/mmgen/main_regtest.py index 8daef55b..9045ac0c 100755 --- a/mmgen/main_regtest.py +++ b/mmgen/main_regtest.py @@ -22,13 +22,13 @@ mmgen-regtest: Coin daemon regression test mode setup and operations for the MMG """ import mmgen.opts as opts -from .globalvars import g +from .globalvars import g,gc from .util import die,async_run opts_data = { 'sets': [('yes', True, 'quiet', True)], 'text': { - 'desc': f'Coin daemon regression test mode setup and operations for the {g.proj_name} suite', + 'desc': f'Coin daemon regression test mode setup and operations for the {gc.proj_name} suite', 'usage': '[opts] ', 'options': """ -h, --help Print this help message diff --git a/mmgen/main_seedjoin.py b/mmgen/main_seedjoin.py index cff399af..e618acbd 100755 --- a/mmgen/main_seedjoin.py +++ b/mmgen/main_seedjoin.py @@ -22,7 +22,7 @@ mmgen-seedjoin: Regenerate an MMGen deterministic wallet from seed shares """ import mmgen.opts as opts -from .globalvars import g +from .globalvars import g,gc from .opts import opt from .util import msg,msg_r,qmsg,die from .color import yellow @@ -53,7 +53,7 @@ opts_data = { -L, --label= l Specify a label 'l' for output wallet -M, --master-share=i Use a master share with index 'i' (min:{ms_min}, max:{ms_max}) -p, --hash-preset= p Use the scrypt hash parameters defined by preset 'p' - for password hashing (default: '{g.dfl_hash_preset}') + for password hashing (default: '{gc.dfl_hash_preset}') -z, --show-hash-presets Show information on available hash presets -P, --passwd-file= f Get wallet passphrase from file 'f' -q, --quiet Produce quieter output; suppress some warnings @@ -86,6 +86,7 @@ FMT CODES: ms_min=MasterShareIdx.min_val, ms_max=MasterShareIdx.max_val, g=g, + gc=gc, ), 'notes': lambda help_notes,s: s.format( f=help_notes('fmt_codes'), diff --git a/mmgen/main_split.py b/mmgen/main_split.py index 9ef72c36..5a17ecd6 100755 --- a/mmgen/main_split.py +++ b/mmgen/main_split.py @@ -30,7 +30,7 @@ from .common import * opts_data = { 'text': { 'desc': f""" - Split funds in an {g.proj_name} wallet after a chain fork using a + Split funds in an {gc.proj_name} wallet after a chain fork using a timelocked transaction """, 'usage':'[opts] [output addr1] [output addr2]', @@ -54,7 +54,7 @@ opts_data = { 'notes': f"""\n This command creates two transactions: one (with the timelock) to be broadcast on the long chain and one on the short chain after a replayable chain fork. -Only {g.proj_name} addresses may be spent to. +Only {gc.proj_name} addresses may be spent to. The command must be run on the longest chain. The user is reponsible for ensuring that the current chain is the longest. The other chain is specified @@ -99,7 +99,7 @@ if opt.other_coin.lower() not in [e[2] for e in proto.forks if e[3] == True]: die(1,f'{opt.other_coin!r}: not a replayable fork of {proto.coin} chain') if len(cmd_args) != 2: - die(1,f'This command requires exactly two {g.proj_name} addresses as arguments') + die(1,f'This command requires exactly two {gc.proj_name} addresses as arguments') from .addr import MMGenID try: diff --git a/mmgen/main_tool.py b/mmgen/main_tool.py index 67c8c32a..7e0d814e 100755 --- a/mmgen/main_tool.py +++ b/mmgen/main_tool.py @@ -23,13 +23,13 @@ mmgen-tool: Perform various MMGen- and cryptocoin-related operations. import sys,os,importlib import mmgen.opts as opts -from .globalvars import g +from .globalvars import g,gc from .opts import opt from .util import msg,Msg,die,capfirst,suf,async_run opts_data = { 'text': { - 'desc': f'Perform various {g.proj_name}- and cryptocoin-related operations', + 'desc': f'Perform various {gc.proj_name}- and cryptocoin-related operations', 'usage': '[opts] ', 'options': """ -d, --outdir= d Specify an alternate directory 'd' for output @@ -41,7 +41,7 @@ opts_data = { for {coin_id}: {kgs} -l, --list List available commands -p, --hash-preset= p Use the scrypt hash parameters defined by preset 'p' - for password hashing (default: '{g.dfl_hash_preset}') + for password hashing (default: '{gc.dfl_hash_preset}') -P, --passwd-file= f Get passphrase from file 'f'. -q, --quiet Produce quieter output -r, --usr-randchars=n Get 'n' characters of additional randomness from @@ -65,10 +65,11 @@ Type ‘{pn} help ’ for help on a particular command kgs=help_notes('keygen_backends'), coin_id=help_notes('coin_id'), g=g, + gc=gc, ), 'notes': lambda s, help_notes: s.format( ch=help_notes('tool_help'), - pn=g.prog_name) + pn=gc.prog_name) } } @@ -269,8 +270,7 @@ def process_args(cmd,cmd_args,cls): die(1,"'Binary input data must be supplied via STDIN") if have_stdin_input and arg_type == 'str' and isinstance(arg,bytes): - from .globalvars import g - NL = '\r\n' if g.platform == 'win' else '\n' + NL = '\r\n' if gc.platform == 'win' else '\n' arg = arg.decode() if arg[-len(NL):] == NL: # rstrip one newline arg = arg[:-len(NL)] @@ -346,7 +346,7 @@ def get_cmd_cls(cmd): def get_mod_cls(modname): return getattr(importlib.import_module(f'mmgen.tool.{modname}'),'tool_cmd') -if g.prog_name == 'mmgen-tool' and not opt._lock: +if gc.prog_name == 'mmgen-tool' and not opt._lock: po = opts.init( opts_data, parse_only=True ) diff --git a/mmgen/main_txbump.py b/mmgen/main_txbump.py index d879dccb..34562387 100755 --- a/mmgen/main_txbump.py +++ b/mmgen/main_txbump.py @@ -22,7 +22,7 @@ mmgen-txbump: Increase the fee on a replaceable (replace-by-fee) MMGen """ import mmgen.opts as opts -from .globalvars import g +from .globalvars import gc from .opts import opt from .util import msg,msg_r,qmsg,die,async_run from .color import green @@ -32,11 +32,11 @@ opts_data = { 'sets': [('yes', True, 'quiet', True)], 'text': { 'desc': f""" - Increase the fee on a replaceable (RBF) {g.proj_name} transaction, + Increase the fee on a replaceable (RBF) {gc.proj_name} transaction, creating a new transaction, and optionally sign and send the new transaction """, - 'usage': f'[opts] <{g.proj_name} TX file> [seed source] ...', + 'usage': f'[opts] <{gc.proj_name} TX file> [seed source] ...', 'options': """ -h, --help Print this help message --, --longhelp Print help message for long options (common options) @@ -66,7 +66,7 @@ opts_data = { for the transaction's change output, if present) -O, --old-incog-fmt Specify old-format incognito input -p, --hash-preset= p Use the scrypt hash parameters defined by preset 'p' - for password hashing (default: '{g.dfl_hash_preset}') + for password hashing (default: '{gc.dfl_hash_preset}') -P, --passwd-file= f Get {pnm} wallet passphrase from file 'f' -q, --quiet Suppress warnings; overwrite files without prompting -s, --send Sign and send the transaction (the default if seed @@ -87,9 +87,9 @@ FMT CODES: }, 'code': { 'options': lambda help_notes,proto,s: s.format( - g=g, - pnm=g.proj_name, - pnl=g.proj_name.lower(), + gc=gc, + pnm=gc.proj_name, + pnl=gc.proj_name.lower(), fu=help_notes('rel_fee_desc'), fl=help_notes('fee_spec_letters'), kgs=help_notes('keygen_backends'), diff --git a/mmgen/main_txcreate.py b/mmgen/main_txcreate.py index 7d664672..79e9573d 100755 --- a/mmgen/main_txcreate.py +++ b/mmgen/main_txcreate.py @@ -22,14 +22,14 @@ mmgen-txcreate: Create a cryptocoin transaction with MMGen- and/or non-MMGen """ import mmgen.opts as opts -from .globalvars import g +from .globalvars import g,gc from .opts import opt from .util import fmt_list,async_run opts_data = { 'sets': [('yes', True, 'quiet', True)], 'text': { - 'desc': f'Create a transaction with outputs to specified coin or {g.proj_name} addresses', + 'desc': f'Create a transaction with outputs to specified coin or {gc.proj_name} addresses', 'usage': '[opts] [ ...] [addr file ...]', 'options': """ -h, --help Print this help message diff --git a/mmgen/main_txdo.py b/mmgen/main_txdo.py index c4213b6a..20c3260d 100755 --- a/mmgen/main_txdo.py +++ b/mmgen/main_txdo.py @@ -21,7 +21,7 @@ mmgen-txdo: Create, sign and broadcast an online MMGen transaction """ import mmgen.opts as opts -from .globalvars import g +from .globalvars import g,gc from .opts import opt from .util import die,fmt_list,async_run from .wallet import Wallet @@ -30,7 +30,7 @@ from .subseed import SubSeedIdxRange opts_data = { 'sets': [('yes', True, 'quiet', True)], 'text': { - 'desc': f'Create, sign and send an {g.proj_name} transaction', + 'desc': f'Create, sign and send an {gc.proj_name} transaction', 'usage': '[opts] [ ...] [addr file ...] [seed source ...]', 'options': """ -h, --help Print this help message @@ -75,7 +75,7 @@ opts_data = { mappings, so the user should record its checksum. -O, --old-incog-fmt Specify old-format incognito input -p, --hash-preset= p Use the scrypt hash parameters defined by preset 'p' - for password hashing (default: '{g.dfl_hash_preset}') + for password hashing (default: '{gc.dfl_hash_preset}') -P, --passwd-file= f Get {pnm} wallet passphrase from file 'f' -r, --rbf Make transaction BIP 125 (replace-by-fee) replaceable -q, --quiet Suppress warnings; overwrite files without prompting @@ -104,7 +104,7 @@ FMT CODES: }, 'code': { 'options': lambda proto,help_notes,s: s.format( - g=g,pnm=g.proj_name,pnl=g.proj_name.lower(), + g=g,gc=gc,pnm=gc.proj_name,pnl=gc.proj_name.lower(), kgs=help_notes('keygen_backends'), coin_id=help_notes('coin_id'), fu=help_notes('rel_fee_desc'), diff --git a/mmgen/main_txsend.py b/mmgen/main_txsend.py index 0f7f9089..df941a25 100755 --- a/mmgen/main_txsend.py +++ b/mmgen/main_txsend.py @@ -23,14 +23,14 @@ mmgen-txsend: Broadcast a transaction signed by 'mmgen-txsign' to the network import sys import mmgen.opts as opts -from .globalvars import g +from .globalvars import gc from .opts import opt from .util import vmsg,qmsg,async_run opts_data = { 'sets': [('yes', True, 'quiet', True)], 'text': { - 'desc': f'Send a signed {g.proj_name} cryptocoin transaction', + 'desc': f'Send a signed {gc.proj_name} cryptocoin transaction', 'usage': '[opts] ', 'options': """ -h, --help Print this help message diff --git a/mmgen/main_txsign.py b/mmgen/main_txsign.py index 8ad1a47a..7fc77559 100755 --- a/mmgen/main_txsign.py +++ b/mmgen/main_txsign.py @@ -21,7 +21,7 @@ mmgen-txsign: Sign a transaction generated by 'mmgen-txcreate' """ import mmgen.opts as opts -from .globalvars import g +from .globalvars import gc from .opts import opt from .util import msg,ymsg,die,async_run from .subseed import SubSeedIdxRange @@ -32,7 +32,7 @@ from .color import orange opts_data = { 'sets': [('yes', True, 'quiet', True)], 'text': { - 'desc': f'Sign cryptocoin transactions generated by {g.proj_name.lower()}-txcreate', + 'desc': f'Sign cryptocoin transactions generated by {gc.proj_name.lower()}-txcreate', 'usage': '[opts] ... [seed source]...', 'options': """ -h, --help Print this help message @@ -51,7 +51,7 @@ opts_data = { is required only for brainwallet and incognito inputs with non-standard (< {dsl}-bit) seed lengths. -p, --hash-preset=p Use the scrypt hash parameters defined by preset 'p' - for password hashing (default: '{g.dfl_hash_preset}') + for password hashing (default: '{gc.dfl_hash_preset}') -z, --show-hash-presets Show information on available hash presets -k, --keys-from-file=f Provide additional keys for non-{pnm} addresses -K, --keygen-backend=n Use backend 'n' for public key generation. Options @@ -84,9 +84,9 @@ FMT CODES: }, 'code': { 'options': lambda proto,help_notes,s: s.format( - g=g, - pnm=g.proj_name, - pnl=g.proj_name.lower(), + gc=gc, + pnm=gc.proj_name, + pnl=gc.proj_name.lower(), kgs=help_notes('keygen_backends'), coin_id=help_notes('coin_id'), dsl=help_notes('dfl_seed_len'), diff --git a/mmgen/main_wallet.py b/mmgen/main_wallet.py index 7eda7ea9..4bb9544f 100755 --- a/mmgen/main_wallet.py +++ b/mmgen/main_wallet.py @@ -22,7 +22,7 @@ main_wallet: Entry point for MMGen wallet-related scripts import sys,os import mmgen.opts as opts -from .globalvars import g +from .globalvars import g,gc from .opts import opt from .color import green,yellow from .util import msg,qmsg,vmsg,gmsg_r,ymsg,bmsg,die,capfirst @@ -43,13 +43,13 @@ invoked_as = { 'mmgen-passchg': 'passchg', 'mmgen-subwalletgen': 'subgen', 'mmgen-seedsplit': 'seedsplit', -}[g.prog_name] +}[gc.prog_name] -dsw = f'the default or specified {g.proj_name} wallet' +dsw = f'the default or specified {gc.proj_name} wallet' # full: defhHiJkKlLmoOpPqrSvz- if invoked_as == 'gen': - desc = f'Generate an {g.proj_name} wallet from a random seed' + desc = f'Generate an {gc.proj_name} wallet from a random seed' opt_filter = 'ehdoJlLpPqrSvz-' usage = '[opts]' oaction = 'output' @@ -108,7 +108,7 @@ opts_data = { -m, --keep-label Reuse label of input wallet for output wallet -M, --master-share=i Use a master share with index 'i' (min:{ms_min}, max:{ms_max}) -p, --hash-preset= p Use the scrypt hash parameters defined by preset 'p' - for password hashing (default: '{g.dfl_hash_preset}') + for password hashing (default: '{gc.dfl_hash_preset}') -z, --show-hash-presets Show information on available hash presets -P, --passwd-file= f Get wallet passphrase from file 'f' -q, --quiet Produce quieter output; suppress some warnings @@ -134,6 +134,7 @@ FMT CODES: ms_max=help_notes('MasterShareIdx').max_val, dsl=help_notes('dfl_seed_len'), g=g, + gc=gc, ), 'notes': lambda help_notes,s: s.format( f=help_notes('fmt_codes'), diff --git a/mmgen/main_xmrwallet.py b/mmgen/main_xmrwallet.py index a7504517..68b478ae 100755 --- a/mmgen/main_xmrwallet.py +++ b/mmgen/main_xmrwallet.py @@ -51,7 +51,7 @@ opts_data = { {R} -k, --use-internal-keccak-module Force use of the internal keccak module -p, --hash-preset=P Use scrypt hash preset 'P' for password - hashing (default: '{g.dfl_hash_preset}') + hashing (default: '{gc.dfl_hash_preset}') -r, --restore-height=H Scan from height 'H' when creating wallets -R, --no-relay Save transaction to file instead of relaying -s, --no-start-wallet-daemon Don’t start the wallet daemon at startup @@ -216,6 +216,7 @@ $ mmgen-xmrwallet --pager txview *XMR*.sigtx D=xmrwallet_uarg_info['daemon'].annot, R=xmrwallet_uarg_info['tx_relay_daemon'].annot, g=g, + gc=gc, ), } } diff --git a/mmgen/msg.py b/mmgen/msg.py index 7ad1b8dd..ada61e1d 100755 --- a/mmgen/msg.py +++ b/mmgen/msg.py @@ -13,7 +13,7 @@ msg: base message signing classes """ import os,importlib,json -from .globalvars import g +from .globalvars import gc from .objmethods import MMGenObject,Hilite,InitErrors from .util import msg,die,suf,make_chksum_6,fmt_list,remove_dups from .color import red,orange,grnbg @@ -92,7 +92,7 @@ class coin_msg: def write_to_file(self,outdir=None,ask_overwrite=False): data = { - 'id': f'{g.proj_name} {self.desc}', + 'id': f'{gc.proj_name} {self.desc}', 'metadata': self.data, 'signatures': self.sigs, } diff --git a/mmgen/opts.py b/mmgen/opts.py index 2a424139..1dd87ca9 100755 --- a/mmgen/opts.py +++ b/mmgen/opts.py @@ -21,7 +21,7 @@ opts: MMGen-specific options processing after generic processing by share.Opts """ import sys,os -from .globalvars import g +from .globalvars import g,gc from .base_obj import Lockable import mmgen.share.Opts @@ -36,14 +36,14 @@ opt = UserOpts() def usage(): from .util import Die - Die(1,mmgen.share.Opts.make_usage_str(g.prog_name,'user',usage_data)) + Die(1,mmgen.share.Opts.make_usage_str(gc.prog_name,'user',usage_data)) def version(): from .util import Die,fmt Die(0,fmt(f""" - {g.prog_name.upper()} version {g.version} - Part of the {g.proj_name} suite, an online/offline cryptocurrency wallet for the - command line. Copyright (C){g.Cdates} {g.author} {g.email} + {gc.prog_name.upper()} version {gc.version} + Part of the {gc.proj_name} suite, an online/offline cryptocurrency wallet for the + command line. Copyright (C){gc.Cdates} {gc.author} {gc.email} """,indent=' ').rstrip()) def delete_data(opts_data): @@ -167,7 +167,7 @@ def override_globals_from_cfg_file( for d in ucfg.get_lines(): if d.name in g.cfg_file_opts: ns = d.name.split('_') - if ns[0] in g.core_coins: + if ns[0] in gc.core_coins: if not need_proto: continue nse,tn = ( @@ -267,7 +267,7 @@ common_opts_data = { --, --carol Specify user “Carol” in MMGen regtest mode """, 'code': lambda help_notes,proto,s: s.format( - pnm = g.proj_name, + pnm = gc.proj_name, cu_dfl = proto.coin, ) } @@ -369,7 +369,7 @@ def init( if val != None and hasattr(g,k): setattr(g,k,set_for_type(val,getattr(g,k),'--'+k)) - if g.regtest or g.bob or g.alice or g.carol or g.prog_name == 'mmgen-regtest': + if g.regtest or g.bob or g.alice or g.carol or gc.prog_name == 'mmgen-regtest': g.network = 'regtest' g.regtest_user = 'bob' if g.bob else 'alice' if g.alice else 'carol' if g.carol else None else: @@ -422,7 +422,7 @@ def init( if opt.verbose: opt.quiet = None - if g.debug and g.prog_name != 'test.py': + if g.debug and gc.prog_name != 'test.py': opt.verbose,opt.quiet = (True,None) if g.debug_opts: @@ -609,7 +609,7 @@ def check_usr_opts(usr_opts): # Raises an exception if any check fails # except: # die( 'UserOptError', # 'Regtest (Bob and Alice) mode not set up yet. ' + -# f"Run '{g.proj_name.lower()}-regtest setup' to initialize." ) +# f"Run '{gc.proj_name.lower()}-regtest setup' to initialize." ) # # chk_alice = chk_bob diff --git a/mmgen/proto/btc/daemon.py b/mmgen/proto/btc/daemon.py index 1107d2cb..08ddad18 100755 --- a/mmgen/proto/btc/daemon.py +++ b/mmgen/proto/btc/daemon.py @@ -14,7 +14,7 @@ proto.btc.daemon: Bitcoin base protocol daemon classes import os -from ...globalvars import g +from ...globalvars import g,gc from ...opts import opt from ...util import list_gen from ...daemon import CoinDaemon,_nw,_dd @@ -29,7 +29,7 @@ class bitcoin_core_daemon(CoinDaemon): rpc_ports = _nw(8332, 18332, 18443) cfg_file = 'bitcoin.conf' datadirs = { - 'linux': [g.home_dir,'.bitcoin'], + 'linux': [gc.home_dir,'.bitcoin'], 'win': [os.getenv('APPDATA'),'Bitcoin'] } nonstd_datadir = False @@ -133,7 +133,7 @@ class bitcoin_cash_node_daemon(bitcoin_core_daemon): cfg_file_hdr = '# Bitcoin Cash Node config file\n' nonstd_datadir = True datadirs = { - 'linux': [g.home_dir,'.bitcoin-bchn'], + 'linux': [gc.home_dir,'.bitcoin-bchn'], 'win': [os.getenv('APPDATA'),'Bitcoin_ABC'] } @@ -162,6 +162,6 @@ class litecoin_core_daemon(bitcoin_core_daemon): cfg_file = 'litecoin.conf' cfg_file_hdr = '# Litecoin Core config file\n' datadirs = { - 'linux': [g.home_dir,'.litecoin'], + 'linux': [gc.home_dir,'.litecoin'], 'win': [os.getenv('APPDATA'),'Litecoin'] } diff --git a/mmgen/proto/eth/daemon.py b/mmgen/proto/eth/daemon.py index 91e43679..65c13424 100755 --- a/mmgen/proto/eth/daemon.py +++ b/mmgen/proto/eth/daemon.py @@ -14,7 +14,7 @@ proto.eth.daemon: Ethereum base protocol daemon classes import os -from ...globalvars import g +from ...globalvars import gc from ...util import list_gen,get_subclasses from ...daemon import CoinDaemon,RPCDaemon,_nw,_dd @@ -60,7 +60,7 @@ class openethereum_daemon(ethereum_daemon): exec_fn = 'openethereum' cfg_file = 'parity.conf' datadirs = { - 'linux': [g.home_dir,'.local','share','io.parity.ethereum'], + 'linux': [gc.home_dir,'.local','share','io.parity.ethereum'], 'win': [os.getenv('LOCALAPPDATA'),'Parity','Ethereum'] } @@ -97,7 +97,7 @@ class geth_daemon(ethereum_daemon): avail_opts = ('no_daemonize','online') version_info_arg = 'version' datadirs = { - 'linux': [g.home_dir,'.ethereum','geth'], + 'linux': [gc.home_dir,'.ethereum','geth'], 'win': [os.getenv('LOCALAPPDATA'),'Geth'] # FIXME } @@ -133,7 +133,7 @@ class erigon_daemon(geth_daemon): torrent_ports = _nw(42069,42070,None) # testnet is non-standard version_info_arg = '--version' datadirs = { - 'linux': [g.home_dir,'.local','share','erigon'], + 'linux': [gc.home_dir,'.local','share','erigon'], 'win': [os.getenv('LOCALAPPDATA'),'Erigon'] # FIXME } diff --git a/mmgen/proto/xmr/daemon.py b/mmgen/proto/xmr/daemon.py index cd7d20a4..f9a6d762 100755 --- a/mmgen/proto/xmr/daemon.py +++ b/mmgen/proto/xmr/daemon.py @@ -14,7 +14,7 @@ proto.xmr.daemon: Monero base protocol daemon classes import os -from ...globalvars import g +from ...globalvars import g,gc from ...opts import opt from ...util import list_gen,die,contains_any from ...daemon import CoinDaemon,RPCDaemon,_nw,_dd @@ -29,7 +29,7 @@ class monero_daemon(CoinDaemon): rpc_ports = _nw(18081, 38081, None) # testnet is stagenet cfg_file = 'bitmonero.conf' datadirs = { - 'linux': [g.home_dir,'.bitmonero'], + 'linux': [gc.home_dir,'.bitmonero'], 'win': ['/','c','ProgramData','bitmonero'] } diff --git a/mmgen/protocol.py b/mmgen/protocol.py index 5f03c356..c9b7c80d 100755 --- a/mmgen/protocol.py +++ b/mmgen/protocol.py @@ -22,7 +22,7 @@ protocol: Coin protocol base classes and initializer from collections import namedtuple -from .globalvars import g +from .globalvars import g,gc from .objmethods import MMGenObject decoded_wif = namedtuple('decoded_wif',['sec','pubkey_type','compressed']) @@ -36,7 +36,7 @@ class CoinProtocol(MMGenObject): proto_info = namedtuple('proto_info',['name','trust_level']) # trust levels: see altcoin.py - # keys are mirrored in g.core_coins: + # keys are mirrored in gc.core_coins: coins = { 'btc': proto_info('Bitcoin', 5), 'bch': proto_info('BitcoinCash', 5), @@ -81,9 +81,9 @@ class CoinProtocol(MMGenObject): self.addr_fmt_to_ver_bytes = {v:k for k,v in self.addr_ver_bytes.items()} self.addr_ver_bytes_len = len(list(self.addr_ver_bytes)[0]) - if 'tx' not in self.mmcaps and g.is_txprog: + if 'tx' not in self.mmcaps and gc.is_txprog: from .util import die - die(2,f'Command {g.prog_name!r} not supported for coin {self.coin}') + die(2,f'Command {gc.prog_name!r} not supported for coin {self.coin}') if hasattr(self,'chain_names'): self.chain_name = self.chain_names[0] # first chain name is default @@ -294,7 +294,7 @@ def warn_trustlevel(coinsym): trust_level = e.trust_level if e else None if trust_level in (None,-1): from .util import die - die(1,f'Coin {coinsym} is not supported by {g.proj_name}') + die(1,f'Coin {coinsym} is not supported by {gc.proj_name}') if trust_level > 3: return @@ -317,7 +317,7 @@ def warn_trustlevel(coinsym): 2: yellow('MEDIUM'), 3: green('OK'), }[trust_level], - p = g.proj_name ) + p = gc.proj_name ) if g.test_suite: qmsg(warning) diff --git a/mmgen/rpc.py b/mmgen/rpc.py index 65ffc92e..df62496a 100755 --- a/mmgen/rpc.py +++ b/mmgen/rpc.py @@ -264,7 +264,7 @@ class RPCClient(MMGenObject): def __init__(self,host,port,test_connection=True): # aiohttp workaround, and may speed up RPC performance overall on some systems: - if g.platform == 'win' and host == 'localhost': + if gc.platform == 'win' and host == 'localhost': host = '127.0.0.1' global dmsg_rpc,dmsg_rpc_backend @@ -291,7 +291,7 @@ class RPCClient(MMGenObject): def _get_backend(self,backend): backend_id = backend or opt.rpc_backend if backend_id == 'auto': - return {'linux':RPCBackends.httplib,'win':RPCBackends.requests}[g.platform](self) + return {'linux':RPCBackends.httplib,'win':RPCBackends.requests}[gc.platform](self) else: return getattr(RPCBackends,backend_id)(self) diff --git a/mmgen/term.py b/mmgen/term.py index c3b0ea40..3fcfa540 100755 --- a/mmgen/term.py +++ b/mmgen/term.py @@ -22,7 +22,9 @@ term: Terminal classes for the MMGen suite import sys,os,time from collections import namedtuple -from .common import * + +from .globalvars import g,gc +from .util import msg,msg_r,die try: import tty,termios @@ -43,7 +45,7 @@ class MMGenTerm(object): @classmethod def register_cleanup(cls): - if g.platform == 'linux' and not hasattr(cls,'cleanup_registered'): + if gc.platform == 'linux' and not hasattr(cls,'cleanup_registered'): import atexit atexit.register( lambda: termios.tcsetattr( diff --git a/mmgen/tool/fileutil.py b/mmgen/tool/fileutil.py index fd328e8b..ce67e674 100755 --- a/mmgen/tool/fileutil.py +++ b/mmgen/tool/fileutil.py @@ -23,6 +23,7 @@ tool.fileutil: File routines for the 'mmgen-tool' utility import os from .common import tool_cmd_base +from ..globalvars import gc from ..util import msg,msg_r,qmsg,die,suf,make_full_path from ..crypto import Crypto @@ -36,11 +37,10 @@ class tool_cmd(tool_cmd_base): "Use an Incog ID to find hidden incognito wallet data" from hashlib import sha256 - from ..globalvars import g ivsize,bsize,mod = ( Crypto.aesctr_iv_len, 4096, 4096*8 ) n,carry = 0,b' '*ivsize - flgs = os.O_RDONLY|os.O_BINARY if g.platform == 'win' else os.O_RDONLY + flgs = os.O_RDONLY|os.O_BINARY if gc.platform == 'win' else os.O_RDONLY f = os.open(filename,flgs) for ch in incog_id: if ch not in '0123456789ABCDEF': diff --git a/mmgen/tool/help.py b/mmgen/tool/help.py index 108203d6..5f4908a9 100755 --- a/mmgen/tool/help.py +++ b/mmgen/tool/help.py @@ -133,7 +133,7 @@ def gen_tool_usage(): def gen_tool_cmd_usage(mod,cmdname): - from ..globalvars import g + from ..globalvars import gc from ..util import capfirst cls = main_tool.get_mod_cls(mod) @@ -145,7 +145,7 @@ def gen_tool_cmd_usage(mod,cmdname): yield capfirst( docstr.split('\n')[0].strip() ) yield '' yield 'USAGE: {b} [OPTS] {c}{d}{e}'.format( - b = g.prog_name, + b = gc.prog_name, c = cmdname, d = f' {ARGS}' if ARGS else '', e = f' [{KWARGS}]' if KWARGS else '' ) diff --git a/mmgen/tool/util.py b/mmgen/tool/util.py index 9b7e6668..cc0f753d 100755 --- a/mmgen/tool/util.py +++ b/mmgen/tool/util.py @@ -20,6 +20,7 @@ tool.util: Utility commands for the 'mmgen-tool' utility """ +from ..globalvars import gc from .common import tool_cmd_base class tool_cmd(tool_cmd_base): @@ -121,8 +122,7 @@ class tool_cmd(tool_cmd_base): def unhexdump(self,infile:str): "decode hexdump from file (use '-' for stdin) (warning: outputs binary data)" - from ..globalvars import g - if g.platform == 'win': + if gc.platform == 'win': import sys,os,msvcrt msvcrt.setmode( sys.stdout.fileno(), os.O_BINARY ) from ..fileutil import get_data_from_file diff --git a/mmgen/tw/unspent.py b/mmgen/tw/unspent.py index c0b7ccd5..9a36edbc 100755 --- a/mmgen/tw/unspent.py +++ b/mmgen/tw/unspent.py @@ -81,7 +81,8 @@ class TwUnspentOutputs(TwView): await super().__init__(proto) self.minconf = minconf self.addrs = addrs - self.min_cols = g.min_screen_width + from ..globalvars import gc + self.min_cols = gc.min_screen_width @property def total(self): diff --git a/mmgen/tw/view.py b/mmgen/tw/view.py index a0901769..71423a8a 100755 --- a/mmgen/tw/view.py +++ b/mmgen/tw/view.py @@ -516,7 +516,8 @@ class TwView(MMGenObject,metaclass=AsyncInit): for k in self.scroll_keys['vi']: assert k not in self.key_mappings, f'{k!r} is in key_mappings' self.key_mappings.update(self.scroll_keys['vi']) - self.key_mappings.update(self.scroll_keys[g.platform]) + from ..globalvars import gc + self.key_mappings.update(self.scroll_keys[gc.platform]) return self.key_mappings scroll = self.scroll = g.scroll diff --git a/mmgen/tx/base.py b/mmgen/tx/base.py index af0d6e0d..46af6fcf 100755 --- a/mmgen/tx/base.py +++ b/mmgen/tx/base.py @@ -12,7 +12,7 @@ tx.base: base transaction class """ -from ..globalvars import * +from ..globalvars import gc from ..objmethods import MMGenObject from ..obj import ( ImmutableAttr, @@ -85,13 +85,13 @@ class Base(MMGenObject): chain = None signed = False non_mmgen_inputs_msg = f""" - This transaction includes inputs with non-{g.proj_name} addresses. When + This transaction includes inputs with non-{gc.proj_name} addresses. When signing the transaction, private keys for the addresses listed below must be supplied using the --keys-from-file option. The key file must contain one key per line. Please note that this transaction cannot be autosigned, as autosigning does not support the use of key files. - Non-{g.proj_name} addresses found in inputs: + Non-{gc.proj_name} addresses found in inputs: {{}} """ diff --git a/mmgen/tx/info.py b/mmgen/tx/info.py index c37a86fa..4453ed9b 100755 --- a/mmgen/tx/info.py +++ b/mmgen/tx/info.py @@ -12,7 +12,7 @@ tx.info: transaction info class """ -from ..globalvars import * +from ..globalvars import gc from ..color import red,green,orange from ..opts import opt from ..util import msg,msg_r @@ -43,7 +43,7 @@ class TxInfo: sel_f = lambda o: len(o.mmid) + (2,8)[bool(o.is_chg)] # + len(' (chg)') return max(max([sel_f(o) for o in io if o.mmid] or [0]),len(nonmm_str)) - nonmm_str = f'(non-{g.proj_name} address)' + nonmm_str = f'(non-{gc.proj_name} address)' max_mmwid = max(get_max_mmwid(tx.inputs),get_max_mmwid(tx.outputs)) def gen_view(): diff --git a/mmgen/tx/new.py b/mmgen/tx/new.py index a647503f..a78bcaf5 100755 --- a/mmgen/tx/new.py +++ b/mmgen/tx/new.py @@ -15,6 +15,7 @@ tx.new: new transaction class from ..globalvars import * from ..opts import opt from .base import Base +from ..globalvars import gc from ..color import pink,yellow from ..obj import get_obj,MMGenList from ..util import msg,qmsg,fmt,die,suf,remove_dups,get_extension @@ -37,12 +38,12 @@ def mmaddr2coinaddr(mmaddr,ad_w,ad_f,proto): the address into your tracking wallet before broadcasting this transaction. """, 'addr_not_found': f""" - No data for {g.proj_name} address {mmaddr} could be found in either the + No data for {gc.proj_name} address {mmaddr} could be found in either the tracking wallet or the supplied address file. Please import this address into your tracking wallet, or supply an address file on the command line. """, 'addr_not_found_no_addrfile': f""" - No data for {g.proj_name} address {mmaddr} could be found in the tracking + No data for {gc.proj_name} address {mmaddr} could be found in the tracking wallet. Please import this address into your tracking wallet or supply an address file for it on the command line. """ @@ -227,7 +228,7 @@ class New(Base): 'ERROR: No change output specified' )) if self.has_segwit_outputs() and not self.rpc.info('segwit_is_active'): - die(2,f'{g.proj_name} Segwit address requested on the command line, ' + die(2,f'{gc.proj_name} Segwit address requested on the command line, ' + 'but Segwit is not active on this chain') if not self.outputs: diff --git a/mmgen/tx/sign.py b/mmgen/tx/sign.py index f6b8c86d..047f3c39 100755 --- a/mmgen/tx/sign.py +++ b/mmgen/tx/sign.py @@ -20,7 +20,7 @@ tx.sign: Sign a transaction generated by 'mmgen-txcreate' """ -from ..globalvars import g +from ..globalvars import g,gc from ..opts import opt from ..util import msg,vmsg,qmsg,suf,fmt,die,remove_dups,get_extension from ..obj import MMGenList @@ -83,7 +83,7 @@ def add_keys(tx,src,infiles=None,saved_seeds=None,keyaddr_list=None): desc,src_desc = ( ('key-address file','From key-address file:') if keyaddr_list else ('seed(s)','Generated from seed:') ) - qmsg(f'Checking {g.proj_name} -> {tx.proto.coin} address mappings for {src} (from {desc})') + qmsg(f'Checking {gc.proj_name} -> {tx.proto.coin} address mappings for {src} (from {desc})') d = ( MMGenList([keyaddr_list]) if keyaddr_list else generate_kals_for_mmgen_addrs(need_keys,infiles,saved_seeds,tx.proto) ) @@ -99,7 +99,7 @@ def add_keys(tx,src,infiles=None,saved_seeds=None,keyaddr_list=None): new_keys.append(f) else: die(3,fmt(f""" - {g.proj_name} -> {tx.proto.coin} address mappings differ! + {gc.proj_name} -> {tx.proto.coin} address mappings differ! {{src_desc:<23}} {{mmid}} -> {{f.addr}} {{'tx file:':<23}} {{e.mmid}} -> {{e.addr}} """).strip()) @@ -157,7 +157,7 @@ async def txsign(tx,seed_files,kl,kal,tx_num_str=''): if missing: sep = '\n ' die(2,'ERROR: a key file must be supplied for the following non-{} address{}:{}'.format( - g.proj_name, + gc.proj_name, suf(missing,'es'), sep + sep.join(missing) )) keys += tmp.data diff --git a/mmgen/ui.py b/mmgen/ui.py index cc89c58d..6ab54bfa 100755 --- a/mmgen/ui.py +++ b/mmgen/ui.py @@ -14,7 +14,7 @@ ui: Interactive user interface functions for the MMGen suite import sys,os -from .globalvars import g +from .globalvars import g,gc from .opts import opt from .util import msg,msg_r,Msg,dmsg,die @@ -116,7 +116,7 @@ def do_pager(text): end_msg = '\n(end of text)\n\n' # --- Non-MSYS Windows code deleted --- # raw, chop, horiz scroll 8 chars, disable buggy line chopping in MSYS - os.environ['LESS'] = (('--shift 8 -RS'),('--shift 16 -RS'))[g.platform=='win'] + os.environ['LESS'] = (('--shift 8 -RS'),('--shift 16 -RS'))[gc.platform=='win'] if 'PAGER' in os.environ and os.environ['PAGER'] != pagers[0]: pagers = [os.environ['PAGER']] + pagers diff --git a/mmgen/util.py b/mmgen/util.py index 2a854811..aa19b3ae 100755 --- a/mmgen/util.py +++ b/mmgen/util.py @@ -23,7 +23,7 @@ util: Frequently-used variables, classes and utility functions for the MMGen sui import sys,os,time,re from .color import * -from .globalvars import g +from .globalvars import g,gc,gv from .opts import opt ascii_lowercase = 'abcdefghijklmnopqrstuvwxyz' @@ -32,11 +32,11 @@ hexdigits = '0123456789abcdefABCDEF' hexdigits_uc = '0123456789ABCDEF' hexdigits_lc = '0123456789abcdef' -if g.platform == 'win': +if gc.platform == 'win': def msg_r(s): try: - g.stderr.write(s) - g.stderr.flush() + gv.stderr.write(s) + gv.stderr.flush() except: os.write(2,s.encode()) @@ -45,8 +45,8 @@ if g.platform == 'win': def Msg_r(s): try: - g.stdout.write(s) - g.stdout.flush() + gv.stdout.write(s) + gv.stdout.flush() except: os.write(1,s.encode()) @@ -54,18 +54,18 @@ if g.platform == 'win': Msg_r(s + '\n') else: def msg(s): - g.stderr.write(s + '\n') + gv.stderr.write(s + '\n') def msg_r(s): - g.stderr.write(s) - g.stderr.flush() + gv.stderr.write(s) + gv.stderr.flush() def Msg(s): - g.stdout.write(s + '\n') + gv.stdout.write(s + '\n') def Msg_r(s): - g.stdout.write(s) - g.stdout.flush() + gv.stdout.write(s) + gv.stdout.flush() def rmsg(s): msg(red(s)) @@ -413,5 +413,5 @@ def wrap_ripemd160(called=[]): called.append(True) def exit_if_mswin(feature): - if g.platform == 'win': + if gc.platform == 'win': die(2, capfirst(feature) + ' not supported on the MSWin / MSYS2 platform' ) diff --git a/mmgen/wallet/enc.py b/mmgen/wallet/enc.py index f5b2f9cb..b05fdcc7 100755 --- a/mmgen/wallet/enc.py +++ b/mmgen/wallet/enc.py @@ -12,7 +12,7 @@ wallet.enc: encrypted wallet base class """ -from ..globalvars import g +from ..globalvars import gc from ..opts import opt from ..util import msg,qmsg,make_chksum_8 from .base import wallet @@ -60,7 +60,7 @@ class wallet(wallet): qmsg(f'Using hash preset {hp!r} requested on command line') else: hp = self._get_hash_preset_from_user( - old_preset = g.dfl_hash_preset, + old_preset = gc.dfl_hash_preset, add_desc = add_desc ) self.ssdata.hash_preset = hp diff --git a/mmgen/wallet/incog_hidden.py b/mmgen/wallet/incog_hidden.py index ada5a106..1ef86bba 100755 --- a/mmgen/wallet/incog_hidden.py +++ b/mmgen/wallet/incog_hidden.py @@ -14,7 +14,7 @@ wallet.incog_hidden: hidden incognito wallet class import os -from ..globalvars import g +from ..globalvars import gc from ..opts import opt from ..seed import Seed from ..util import msg,dmsg,qmsg,die,compare_or_die,capfirst @@ -74,7 +74,7 @@ class wallet(wallet): d.target_data_len = self._get_incog_data_len(opt.seed_len or Seed.dfl_len) self._check_valid_offset(self.infile,'read') - flgs = os.O_RDONLY|os.O_BINARY if g.platform == 'win' else os.O_RDONLY + flgs = os.O_RDONLY|os.O_BINARY if gc.platform == 'win' else os.O_RDONLY fh = os.open(self.infile.name,flgs) os.lseek(fh,int(d.hincog_offset),os.SEEK_SET) self.fmt_data = os.read(fh,d.target_data_len) @@ -135,7 +135,7 @@ class wallet(wallet): message = '', action = f'alter file {f.name!r}' ) - flgs = os.O_RDWR|os.O_BINARY if g.platform == 'win' else os.O_RDWR + flgs = os.O_RDWR|os.O_BINARY if gc.platform == 'win' else os.O_RDWR fh = os.open(f.name,flgs) os.lseek(fh, int(d.hincog_offset), os.SEEK_SET) os.write(fh, self.fmt_data) diff --git a/scripts/uninstall-mmgen.py b/scripts/uninstall-mmgen.py index f5d091d7..152bc7eb 100755 --- a/scripts/uninstall-mmgen.py +++ b/scripts/uninstall-mmgen.py @@ -19,7 +19,7 @@ import sys,os import mmgen.opts as opts -from mmgen.globalvars import g +from mmgen.globalvars import gc from mmgen.util import msg,die def normalize_path(p): @@ -53,7 +53,7 @@ opts_data = { cmd_args = opts.init(opts_data) -if g.platform == 'linux' and os.getenv('USER') != 'root': +if gc.platform == 'linux' and os.getenv('USER') != 'root': die(1,'This program must be run as root') if len(cmd_args): diff --git a/test/gentest.py b/test/gentest.py index e5519da5..f294742a 100755 --- a/test/gentest.py +++ b/test/gentest.py @@ -28,7 +28,7 @@ sys.path.insert(0,overlay_setup(repo_root)) # Import these _after_ local path's been added to sys.path import mmgen.opts as opts -from mmgen.globalvars import g +from mmgen.globalvars import g,gc from mmgen.opts import opt from mmgen.color import green,red,purple from mmgen.util import msg,qmsg,qmsg_r,vmsg,capfirst,is_int,die @@ -131,7 +131,7 @@ SUPPORTED EXTERNAL TOOLS: ), 'notes': lambda s: s.format( prog='test/gentest.py', - pnm=g.proj_name, + pnm=gc.proj_name, snum=rounds ) } } diff --git a/test/include/coin_daemon_control.py b/test/include/coin_daemon_control.py index e35fcfee..16250ed5 100755 --- a/test/include/coin_daemon_control.py +++ b/test/include/coin_daemon_control.py @@ -15,7 +15,7 @@ test.include.coin_daemon_control: Start and stop daemons for the MMGen test suit from .tests_header import repo_root from mmgen.common import * -action = g.prog_name.split('-')[0] +action = gc.prog_name.split('-')[0] opts_data = { 'sets': [('debug',True,'verbose',True)], @@ -44,7 +44,7 @@ Valid network IDs: {nid}, all, or no_xmr """ }, 'code': { - 'options': lambda s: s.format(a=action.capitalize(),pn=g.prog_name), + 'options': lambda s: s.format(a=action.capitalize(),pn=gc.prog_name), 'notes': lambda s,help_notes: s.format(nid=help_notes('coin_daemon_network_ids')) } } diff --git a/test/include/common.py b/test/include/common.py index a8c28828..f2000be3 100755 --- a/test/include/common.py +++ b/test/include/common.py @@ -162,13 +162,13 @@ def init_coverage(): def silence(): if not (opt.verbose or opt.exact_output): - g.stdout = g.stderr = open(os.devnull,'w') + gv.stdout = gv.stderr = open(os.devnull,'w') def end_silence(): if not (opt.verbose or opt.exact_output): - g.stdout.close() - g.stdout = sys.stdout - g.stderr = sys.stderr + gv.stdout.close() + gv.stdout = sys.stdout + gv.stderr = sys.stderr def omsg(s): sys.stderr.write(s + '\n') diff --git a/test/misc/get_passphrase.py b/test/misc/get_passphrase.py index e1460041..28ae54fe 100755 --- a/test/misc/get_passphrase.py +++ b/test/misc/get_passphrase.py @@ -29,7 +29,7 @@ def crypto(): from mmgen.crypto import Crypto crypto = Crypto() - pw = crypto.get_new_passphrase(data_desc=desc,hash_preset=g.dfl_hash_preset,passwd_file=None) + pw = crypto.get_new_passphrase(data_desc=desc,hash_preset=gc.dfl_hash_preset,passwd_file=None) msg(f'==> got new passphrase: [{pw}]\n') pw = crypto.get_passphrase(data_desc=desc,passwd_file=None) diff --git a/test/misc/term.py b/test/misc/term.py index 77a2f49f..d27c814c 100755 --- a/test/misc/term.py +++ b/test/misc/term.py @@ -19,13 +19,13 @@ commands = [ 'get_char_one', 'get_char_one_raw', ] -if g.platform == 'linux': +if gc.platform == 'linux': commands.extend([ 'get_char', 'get_char_immed_chars', 'get_char_raw', ]) -elif g.platform == 'win': +elif gc.platform == 'win': commands.extend([ 'get_char_one_char_immed_chars', ]) @@ -38,7 +38,7 @@ opts_data = { -h, --help Print this help message """, 'notes': f""" -available commands for platform {g.platform!r}: +available commands for platform {gc.platform!r}: {fmt_list(commands,fmt='col',indent=' ')} """ } @@ -118,7 +118,7 @@ def _tt_get_char(raw=False,one_char=False,immed_chars=''): if one_char else 'echoed as a FULL CONTROL SEQUENCE.' ) - if g.platform == 'win': + if gc.platform == 'win': if raw: m3 = 'The Escape and F1-F12 keys will be returned as two-character strings.' else: @@ -149,7 +149,7 @@ def tt_urand(): msg(f'USER ENTROPY (user input + keystroke timings):\n\n{fmt(ret," ")}') times = ret.splitlines()[1:] avg_prec = sum(len(t.split('.')[1]) for t in times) // len(times) - if avg_prec < g.min_time_precision: + if avg_prec < gc.min_time_precision: ymsg(f'WARNING: Avg. time precision of only {avg_prec} decimal points. User entropy quality is degraded!') else: msg(f'Average time precision: {avg_prec} decimal points - OK') diff --git a/test/scrambletest.py b/test/scrambletest.py index 32eb7478..c1633819 100755 --- a/test/scrambletest.py +++ b/test/scrambletest.py @@ -127,7 +127,7 @@ def do_coin_tests(): for tname,tdata in ( tuple(bitcoin_data.items()) + tuple(altcoin_data.items() if not opt.no_altcoin else []) ): - if tname == 'zec_zcash_z' and g.platform == 'win': + if tname == 'zec_zcash_z' and gc.platform == 'win': msg("Skipping 'zec_zcash_z' test for Windows platform") continue coin,mmtype = tname.split('_',1) if '_' in tname else (tname,None) diff --git a/test/test.py b/test/test.py index 9433b448..09fccc78 100755 --- a/test/test.py +++ b/test/test.py @@ -30,7 +30,7 @@ def create_shm_dir(data_dir,trash_dir): # under '/dev/shm' and put datadir and tmpdirs here. import shutil from subprocess import run - if g.platform == 'win': + if gc.platform == 'win': for tdir in (data_dir,trash_dir): try: os.listdir(tdir) except: pass @@ -195,7 +195,7 @@ opts.UserOpts._reset_ok += ( parsed_opts = opts.init(opts_data,return_parsed=True) usr_args = parsed_opts.cmd_args -if opt.pexpect_spawn and g.platform == 'win': +if opt.pexpect_spawn and gc.platform == 'win': die(1,'--pexpect-spawn option not supported on Windows platform, exiting') if opt.daemon_id and opt.daemon_id in g.blacklisted_daemons.split(): @@ -313,7 +313,7 @@ def clean(usr_dirs=None,clean_overlay=True): iqmsg(green(f'Cleaned directory {os.path.relpath(overlay_tree_dir)!r}')) def create_tmp_dirs(shm_dir): - if g.platform == 'win': + if gc.platform == 'win': for cfg in sorted(cfgs): mk_tmpdir(cfgs[cfg]['tmpdir']) else: @@ -556,7 +556,7 @@ class TestSuiteRunner(object): omsg(f'INFO → Writing coverage files to {coverdir!r}') self.pre_args = ['python3','-m','trace','--count','--coverdir='+coverdir,'--file='+accfile] else: - self.pre_args = ['python3'] if g.platform == 'win' else [] + self.pre_args = ['python3'] if gc.platform == 'win' else [] if opt.pexpect_spawn: omsg(f'INFO → Using pexpect.spawn() for real terminal emulation') @@ -612,7 +612,7 @@ class TestSuiteRunner(object): clr1,clr2 = (nocolor,nocolor) if opt.print_cmdline else (green,cyan) omsg( clr1('Executing: ') + - clr2(repr(cmd_disp) if g.platform == 'win' else cmd_disp) + clr2(repr(cmd_disp) if gc.platform == 'win' else cmd_disp) ) else: omsg_r(f'{t_pfx}Testing {desc}: ') @@ -918,7 +918,7 @@ class TestSuiteRunner(object): def check_deps(self,cmds): # TODO: broken if len(cmds) != 1: - die(1,f'Usage: {g.prog_name} check_deps ') + die(1,f'Usage: {gc.prog_name} check_deps ') cmd = cmds[0] diff --git a/test/test_py_d/common.py b/test/test_py_d/common.py index 91f3c7e3..d63e1212 100755 --- a/test/test_py_d/common.py +++ b/test/test_py_d/common.py @@ -20,8 +20,9 @@ test.test_py_d.common: Shared routines and data for the test.py test suite """ -import os -from mmgen.common import * +import sys,os +from mmgen.globalvars import g,gc +from mmgen.util import msg from ..include.common import * log_file = 'test.py.log' @@ -53,7 +54,7 @@ from mmgen.obj import MMGenTxComment,TwComment tx_comment_jp = text_jp tx_comment_zh = text_zh -lcg = ascii_cyr_gr if g.platform == 'win' else lat_cyr_gr # MSYS2 popen_spawn issue +lcg = ascii_cyr_gr if gc.platform == 'win' else lat_cyr_gr # MSYS2 popen_spawn issue tx_comment_lat_cyr_gr = lcg[:MMGenTxComment.max_len] # 72 chars tw_comment_zh = text_zh[:TwComment.max_screen_width // 2] diff --git a/test/test_py_d/ts_autosign.py b/test/test_py_d/ts_autosign.py index 18a54852..5bbf5a70 100755 --- a/test/test_py_d/ts_autosign.py +++ b/test/test_py_d/ts_autosign.py @@ -23,7 +23,7 @@ test.test_py_d.ts_autosign: Autosign tests for the test.py test suite import os,shutil from subprocess import run -from mmgen.globalvars import g +from mmgen.globalvars import g,gc from mmgen.opts import opt from ..include.common import * @@ -84,7 +84,7 @@ class TestSuiteAutosignBase(TestSuiteBase): super().__init__(trunner,cfgs,spawn) if trunner == None: return - if g.platform == 'win': + if gc.platform == 'win': die(1,f'Test {type(self).__name__} not supported for Windows platform') self.network_ids = [c+'_tn' for c in self.daemon_coins] + self.daemon_coins @@ -126,7 +126,7 @@ class TestSuiteAutosignBase(TestSuiteBase): self.bad_msg_count = 0 def __del__(self): - if g.platform == 'win' or self.tr == None: + if gc.platform == 'win' or self.tr == None: return if self.simulate or not self.live: LEDControl.delete_dummy_control_files() diff --git a/test/test_py_d/ts_base.py b/test/test_py_d/ts_base.py index 1e363597..97420e0e 100755 --- a/test/test_py_d/ts_base.py +++ b/test/test_py_d/ts_base.py @@ -21,7 +21,7 @@ test.test_py_d.ts_base: Base class for the test.py test suite """ import os -from mmgen.globalvars import g +from mmgen.globalvars import g,gc from mmgen.opts import opt from ..include.common import * from .common import * @@ -74,7 +74,7 @@ class TestSuiteBase(object): return write_to_file(os.path.join(self.tmpdir,fn),data,binary=binary) def skip_for_win(self): - if g.platform == 'win': + if gc.platform == 'win': msg(f'Skipping test {self.test_name!r}: not supported on MSys2 platform') return True else: diff --git a/test/test_py_d/ts_cfgfile.py b/test/test_py_d/ts_cfgfile.py index 98c0e4cb..af36354f 100755 --- a/test/test_py_d/ts_cfgfile.py +++ b/test/test_py_d/ts_cfgfile.py @@ -158,7 +158,7 @@ class TestSuiteCfgFile(TestSuiteBase): write_to_file(self.path('usr'),'\n'.join(d) + '\n') return self.old_sample_common( old_set = True, - pexpect_spawn = False if g.platform == 'win' else True ) + pexpect_spawn = False if gc.platform == 'win' else True ) def _autoset_opts(self,args=[],text='rpc_backend aiohttp\n'): write_to_file( self.path('usr'), text ) diff --git a/test/test_py_d/ts_ethdev.py b/test/test_py_d/ts_ethdev.py index 11668459..a01c9d11 100755 --- a/test/test_py_d/ts_ethdev.py +++ b/test/test_py_d/ts_ethdev.py @@ -25,7 +25,7 @@ from decimal import Decimal from collections import namedtuple from subprocess import run,PIPE,DEVNULL -from mmgen.globalvars import g +from mmgen.globalvars import g,gc from mmgen.opts import opt from mmgen.util import die from mmgen.protocol import CoinProtocol @@ -1290,7 +1290,7 @@ class TestSuiteEthdev(TestSuiteBase,TestSuiteShared): def edit_comment1(self): return self.edit_comment(out_num=del_addrs[0],comment_text=tw_comment_zh[:3]) def edit_comment2(self): - spawn = False if g.platform == 'win' else True + spawn = False if gc.platform == 'win' else True return self.edit_comment(out_num=del_addrs[0],comment_text=tw_comment_zh[3:],changed=True,pexpect_spawn=spawn) def edit_comment3(self): return self.edit_comment(out_num=del_addrs[1],comment_text=tw_comment_lat_cyr_gr) diff --git a/test/test_py_d/ts_input.py b/test/test_py_d/ts_input.py index fef8d024..7deadeeb 100755 --- a/test/test_py_d/ts_input.py +++ b/test/test_py_d/ts_input.py @@ -219,12 +219,12 @@ class TestSuiteInput(TestSuiteBase): # hash preset (default) t.expect('accept the default .*: ', '\n', regex=True) - t.expect(f'[{g.dfl_hash_preset}]') + t.expect(f'[{gc.dfl_hash_preset}]') return t def _input_func(self,func_name,arg_dfls,func_args,text,expect,term): - if term and g.platform == 'win': + if term and gc.platform == 'win': return ('skip_warn','pexpect_spawn not supported on Windows platform') func_args = {k:v for k,v in zip(arg_dfls.keys(),func_args)} t = self.spawn( @@ -268,7 +268,7 @@ class TestSuiteInput(TestSuiteBase): return self._get_char(['prompt> ','',True,5],'x','x',False) def get_char2(self): - expect = 'x' if g.platform == 'win' else 'xxxxx' + expect = 'x' if gc.platform == 'win' else 'xxxxx' return self._get_char(['prompt> ','',True,5],'xxxxx',expect,False) def get_char3(self): @@ -314,7 +314,7 @@ class TestSuiteInput(TestSuiteBase): return self._line_input(['prompt> ',True,'foobarbaz',True],Ctrl_U+'foobar','foobar',True) def _password_entry(self,prompt,opts=[],term=False): - if term and g.platform == 'win': + if term and gc.platform == 'win': return ('skip_warn','pexpect_spawn not supported on Windows platform') t = self.spawn( 'test/misc/input_func.py', opts + ['passphrase'], cmd_dir='.', pexpect_spawn=term ) imsg('Terminal: {}'.format(term)) diff --git a/test/test_py_d/ts_misc.py b/test/test_py_d/ts_misc.py index 96699a17..0fc43b22 100755 --- a/test/test_py_d/ts_misc.py +++ b/test/test_py_d/ts_misc.py @@ -20,7 +20,7 @@ test.test_py_d.ts_misc: Miscellaneous test groups for the test.py test suite """ -from mmgen.globalvars import g +from mmgen.globalvars import g,gc from ..include.common import * from .common import * from .ts_base import * @@ -233,7 +233,7 @@ class TestSuiteOutput(TestSuiteBase): def oneshot_warning(self,pexpect_spawn=None): t = self.spawn('test/misc/oneshot_warning.py',cmd_dir='.',pexpect_spawn=pexpect_spawn) - nl = '\r\n' if g.platform == 'win' or t.pexpect_spawn else '\n' + nl = '\r\n' if gc.platform == 'win' or t.pexpect_spawn else '\n' for s in ( f'pw{nl}wg1', 'foo is experimental', diff --git a/test/test_py_d/ts_tool.py b/test/test_py_d/ts_tool.py index 3fa03e5c..d236e4c8 100755 --- a/test/test_py_d/ts_tool.py +++ b/test/test_py_d/ts_tool.py @@ -74,7 +74,7 @@ class TestSuiteTool(TestSuiteMain,TestSuiteBase): vmsg(f'Incog ID: {cyan(i_id)}') t = self.spawn('mmgen-tool',['-d',self.tmpdir,'find_incog_data',f1,i_id]) o = t.expect_getend(f'Incog data for ID {i_id} found at offset ') - if not g.platform == 'win': + if not gc.platform == 'win': os.unlink(f1) # causes problems with MSYS2 cmp_or_die(hincog_offset,int(o)) return t diff --git a/test/test_py_d/ts_xmrwallet.py b/test/test_py_d/ts_xmrwallet.py index 940190b6..25ed8d94 100755 --- a/test/test_py_d/ts_xmrwallet.py +++ b/test/test_py_d/ts_xmrwallet.py @@ -23,7 +23,7 @@ test.test_py_d.ts_xmrwallet: xmrwallet tests for the test.py test suite import sys,os,atexit,asyncio,shutil from subprocess import run,PIPE -from mmgen.globalvars import g +from mmgen.globalvars import gc from mmgen.opts import opt from mmgen.obj import MMGenRange from mmgen.amt import XMRAmt @@ -128,7 +128,7 @@ class TestSuiteXMRWallet(TestSuiteBase): omsg(f'SSH SOCKS server started, listening at localhost:{cls.socks_port}') def kill_proxy(): - if g.platform == 'linux': + if gc.platform == 'linux': omsg(f'Killing SSH SOCKS server at localhost:{cls.socks_port}') cmd = [ 'pkill', '-f', ' '.join(a + b2) ] run(cmd) diff --git a/test/tooltest.py b/test/tooltest.py index 46c92cdf..0af46778 100755 --- a/test/tooltest.py +++ b/test/tooltest.py @@ -141,7 +141,7 @@ spawn_cmd = ['scripts/exec_wrapper.py',mmgen_cmd] if opt.coverage: d,f = init_coverage() spawn_cmd = ['python3','-m','trace','--count','--coverdir='+d,'--file='+f] + spawn_cmd -elif g.platform == 'win': +elif gc.platform == 'win': spawn_cmd = ['python3'] + spawn_cmd add_spawn_args = ['--data-dir='+cfg['tmpdir']] + ['--{}{}'.format( diff --git a/test/tooltest2.py b/test/tooltest2.py index f52db3ba..ae55ed65 100755 --- a/test/tooltest2.py +++ b/test/tooltest2.py @@ -40,7 +40,7 @@ from mmgen.baseconv import * skipped_tests = ['mn2hex_interactive'] -NL = ('\n','\r\n')[g.platform=='win'] +NL = ('\n','\r\n')[gc.platform=='win'] def is_str(s): return type(s) == str @@ -866,7 +866,7 @@ async def run_test(cls,gid,cmd_name): elif opt.fork: cmd_out = fork_cmd(cmd_name,args,out,opts,stdin_input) else: - if stdin_input and g.platform == 'win': + if stdin_input and gc.platform == 'win': msg('Skipping for MSWin - no os.fork()') continue method = getattr(cls(cmdname=cmd_name,proto=proto,mmtype=mmtype),cmd_name) diff --git a/test/unit_tests.py b/test/unit_tests.py index 8318720b..47cde32e 100755 --- a/test/unit_tests.py +++ b/test/unit_tests.py @@ -142,7 +142,7 @@ def run_test(test,subtest=None): if opt.no_altcoin_deps and subtest in altcoin_deps: qmsg(gray(f'Invoked with --no-altcoin-deps, so skipping {subtest_disp!r}')) continue - if g.platform == 'win' and subtest in win_skip: + if gc.platform == 'win' and subtest in win_skip: qmsg(gray(f'Skipping {subtest_disp!r} for Windows platform')) continue elif platform.machine() == 'aarch64' and subtest in arm_skip: diff --git a/test/unit_tests_d/__init__.py b/test/unit_tests_d/__init__.py index de29f6a1..554f89cf 100755 --- a/test/unit_tests_d/__init__.py +++ b/test/unit_tests_d/__init__.py @@ -6,7 +6,7 @@ test.unit_tests_d.__init__: shared data for unit tests for the MMGen suite import sys,os -from mmgen.globalvars import g +from mmgen.globalvars import gv from mmgen.opts import opt class unit_tests_base: @@ -15,9 +15,9 @@ class unit_tests_base: if not opt.verbose: self.stdout = sys.stdout self.stderr = sys.stderr - sys.stdout = sys.stderr = g.stdout = g.stderr = open(os.devnull,'w') + sys.stdout = sys.stderr = gv.stdout = gv.stderr = open(os.devnull,'w') def _end_silence(self): if not opt.verbose: - sys.stdout = g.stdout = self.stdout - sys.stderr = g.stderr = self.stderr + sys.stdout = gv.stdout = self.stdout + sys.stderr = gv.stderr = self.stderr diff --git a/test/unit_tests_d/ut_rpc.py b/test/unit_tests_d/ut_rpc.py index 02265ef5..d75a9ecf 100755 --- a/test/unit_tests_d/ut_rpc.py +++ b/test/unit_tests_d/ut_rpc.py @@ -120,7 +120,7 @@ def run_test(network_ids,test_cf_auth=False,daemon_ids=None): if not opt.no_daemon_stop: d.stop() - if test_cf_auth and g.platform != 'win': + if test_cf_auth and gc.platform != 'win': cfg_file_auth_test(d.proto,d) cfg_file_auth_test(d.proto,d,bad_auth=True) diff --git a/test/unit_tests_d/ut_testdep.py b/test/unit_tests_d/ut_testdep.py index af3317c2..352c3ddc 100755 --- a/test/unit_tests_d/ut_testdep.py +++ b/test/unit_tests_d/ut_testdep.py @@ -48,7 +48,7 @@ class unit_tests: return True def ethkey(self,name,ut): - if g.platform == 'linux' and os.uname().machine != 'x86_64': + if gc.platform == 'linux' and os.uname().machine != 'x86_64': distro = [l for l in open('/etc/os-release').read().split('\n') if l.startswith('ID=')][0][3:] if distro != 'archarm': ymsg('Skipping ethkey availability test for distro {!r} on architecture {!r}'.format(