From b9c96c521589ec0f5b478702711983849470a207 Mon Sep 17 00:00:00 2001 From: The MMGen Project Date: Thu, 3 Feb 2022 20:40:40 +0000 Subject: [PATCH] avoid use of globals() wherever practicable --- mmgen/color.py | 8 +++++--- mmgen/daemon.py | 7 +++++-- mmgen/main_addrgen.py | 7 ++++--- mmgen/main_autosign.py | 2 +- mmgen/mn_entry.py | 6 ++++-- mmgen/objmethods.py | 4 ++-- mmgen/term.py | 5 ++--- mmgen/txfile.py | 1 + mmgen/util.py | 4 +++- test/colortest.py | 4 ++-- test/include/coin_daemon_control.py | 3 ++- test/misc/term.py | 7 ++++--- test/test_py_d/ts_regtest.py | 4 +++- test/unit_tests_d/ut_daemon.py | 3 ++- 14 files changed, 40 insertions(+), 25 deletions(-) diff --git a/mmgen/color.py b/mmgen/color.py index 175eff37..49f43c8e 100755 --- a/mmgen/color.py +++ b/mmgen/color.py @@ -74,6 +74,8 @@ def get_terminfo_colors(term=None): def init_color(num_colors='auto'): assert num_colors in ('auto',8,16,256,0) + import mmgen.color as self + if num_colors == 'auto': import os t = os.getenv('TERM') @@ -83,19 +85,19 @@ def init_color(num_colors='auto'): if num_colors == 0: ncc = (lambda s: s).__code__ for c in _colors: - globals()[c].__code__ = ncc + getattr(self,c).__code__ = ncc elif num_colors == 256: for c,e in _colors.items(): start = ( '\033[38;5;{};1m'.format(e[0]) if type(e[0]) == int else '\033[38;5;{};48;5;{};1m'.format(*e[0]) ) - globals()[c].__code__ = eval(f'(lambda s: "{start}" + s + "{reset}").__code__') + getattr(self,c).__code__ = eval(f'(lambda s: "{start}" + s + "{reset}").__code__') elif num_colors in (8,16): for c,e in _colors.items(): start = ( '\033[{}m'.format(e[1][0]) if e[1][1] == 0 else '\033[{};{}m'.format(*e[1]) ) - globals()[c].__code__ = eval(f'(lambda s: "{start}" + s + "{reset}").__code__') + getattr(self,c).__code__ = eval(f'(lambda s: "{start}" + s + "{reset}").__code__') set_vt100() diff --git a/mmgen/daemon.py b/mmgen/daemon.py index 62f9da37..468a082a 100755 --- a/mmgen/daemon.py +++ b/mmgen/daemon.py @@ -338,9 +338,10 @@ class CoinDaemon(Daemon): @classmethod def get_network_ids(cls): # FIXME: gets IDs for _default_ daemon only from .protocol import CoinProtocol + import mmgen.daemon as daemon_mod def gen(): for coin,data in cls.coins.items(): - for network in globals()[data.daemon_ids[0]+'_daemon'].networks: + for network in getattr( daemon_mod, data.daemon_ids[0]+'_daemon' ).networks: yield CoinProtocol.Base.create_network_id(coin,network) return list(gen()) @@ -375,7 +376,9 @@ class CoinDaemon(Daemon): if daemon_id not in daemon_ids: die(1,f'{daemon_id!r}: invalid daemon_id - valid choices: {fmt_list(daemon_ids)}') - me = Daemon.__new__(globals()[daemon_id + '_daemon']) + import mmgen.daemon + me = Daemon.__new__( getattr(mmgen.daemon, daemon_id+'_daemon') ) + assert network in me.networks, f'{network!r}: unsupported network for daemon {daemon_id}' me.network = network me.coin = coin diff --git a/mmgen/main_addrgen.py b/mmgen/main_addrgen.py index 8fc36b55..a424ad96 100755 --- a/mmgen/main_addrgen.py +++ b/mmgen/main_addrgen.py @@ -23,10 +23,11 @@ mmgen-addrgen: Generate a series or range of addresses from an MMGen from .common import * from .addr import MMGenAddrType -from .addrlist import AddrList,KeyAddrList,KeyList,AddrIdxList from .addrfile import AddrFile from .wallet import Wallet +import mmgen.addrlist + if g.prog_name == 'mmgen-keygen': gen_what = 'keys' gen_clsname = 'KeyAddrList' @@ -142,7 +143,7 @@ if opt.keygen_backend: from .keygen import check_backend check_backend( proto, opt.keygen_backend, opt.type ) -idxs = AddrIdxList(fmt_str=cmd_args.pop()) +idxs = mmgen.addrlist.AddrIdxList( fmt_str=cmd_args.pop() ) from .fileutil import get_seed_file sf = get_seed_file(cmd_args,1) @@ -156,7 +157,7 @@ ss_seed = ss.seed if opt.subwallet is None else ss.seed.subseed(opt.subwallet,pr if opt.no_addresses: gen_clsname = 'KeyList' -al = globals()[gen_clsname]( +al = getattr( mmgen.addrlist, gen_clsname )( proto = proto, seed = ss_seed, addr_idxs = idxs, diff --git a/mmgen/main_autosign.py b/mmgen/main_autosign.py index e2dfd10f..96b6821c 100755 --- a/mmgen/main_autosign.py +++ b/mmgen/main_autosign.py @@ -388,7 +388,7 @@ if len(cmd_args) not in (0,1): if len(cmd_args) == 1: cmd = cmd_args[0] if cmd in ('gen_key','setup'): - globals()[cmd]() + (gen_key if cmd == 'gen_key' else setup)() sys.exit(0) elif cmd != 'wait': die(1,f'{cmd!r}: unrecognized command') diff --git a/mmgen/mn_entry.py b/mmgen/mn_entry.py index 0ba603f9..fe246e14 100755 --- a/mmgen/mn_entry.py +++ b/mmgen/mn_entry.py @@ -222,7 +222,8 @@ def mn_entry(wl_id,entry_mode=None): me.wl = me.bconv.digits obj = me() if entry_mode: - obj.em = globals()['MnEntryMode'+capfirst(entry_mode)](obj) + import mmgen.mn_entry + obj.em = getattr( mmgen.mn_entry, 'MnEntryMode'+capfirst(entry_mode) )(obj) return obj class MnemonicEntry(object): @@ -306,7 +307,8 @@ class MnemonicEntry(object): lo = idx + 1 def get_cls_by_entry_mode(self,entry_mode): - return globals()['MnEntryMode'+capfirst(entry_mode)] + import mmgen.mn_entry + return getattr( mmgen.mn_entry, 'MnEntryMode'+capfirst(entry_mode) ) def choose_entry_mode(self): msg('Choose an entry mode:\n') diff --git a/mmgen/objmethods.py b/mmgen/objmethods.py index 9a81c24f..d1d27bcb 100755 --- a/mmgen/objmethods.py +++ b/mmgen/objmethods.py @@ -21,9 +21,9 @@ objmethods.py: Mixin classes for MMGen data objects """ import unicodedata -from .color import * from .globalvars import g from .devtools import * +import mmgen.color as color_mod def truncate_str(s,width): # width = screen width wide_count = 0 @@ -81,7 +81,7 @@ class Hilite: @classmethod def colorize(cls,s,color=True,color_override=''): - return globals()[color_override or cls.color](s) if color else s + return getattr( color_mod, color_override or cls.color )(s) if color else s def fmt(self,*args,**kwargs): assert args == () # forbid invocation w/o keywords diff --git a/mmgen/term.py b/mmgen/term.py index 52555bb7..f116f193 100755 --- a/mmgen/term.py +++ b/mmgen/term.py @@ -238,7 +238,6 @@ def init_term(): term.init() - global get_char,get_char_raw,kb_hold_protect,get_terminal_size - + import mmgen.term as self for var in ('get_char','get_char_raw','kb_hold_protect','get_terminal_size'): - globals()[var] = getattr(term,var) + setattr( self, var, getattr(term,var) ) diff --git a/mmgen/txfile.py b/mmgen/txfile.py index c1ffe321..5782f5fd 100755 --- a/mmgen/txfile.py +++ b/mmgen/txfile.py @@ -130,6 +130,7 @@ class MMGenTxFile: desc = 'outputs data' tx.outputs = eval_io_data(outputs_data,'outputs') desc = 'send amount in metadata' + from decimal import Decimal assert Decimal(send_amt) == tx.send_amt, f'{send_amt} != {tx.send_amt}' except Exception as e: die(2,f'Invalid {desc} in transaction file: {e!s}') diff --git a/mmgen/util.py b/mmgen/util.py index e259962b..a193facd 100755 --- a/mmgen/util.py +++ b/mmgen/util.py @@ -26,6 +26,8 @@ from .color import * from .globalvars import g from .opts import opt +import mmgen.color as color_mod + ascii_lowercase = 'abcdefghijklmnopqrstuvwxyz' hexdigits = '0123456789abcdefABCDEF' @@ -504,7 +506,7 @@ class oneshot_warning: def do_warning(): message = getattr(wcls,'message') - color = globals()[getattr(wcls,'color')] + color = getattr( color_mod, getattr(wcls,'color') ) msg(color('WARNING: ' + message.format(*fmt_args))) if not hasattr(wcls,'data'): diff --git a/test/colortest.py b/test/colortest.py index a71354b2..616a7003 100755 --- a/test/colortest.py +++ b/test/colortest.py @@ -10,7 +10,7 @@ colortest.py: test color handling for the MMGen suite import include.tests_header from include.common import * from mmgen.color import * -from mmgen.color import _colors +import mmgen.color as color_mod def test_color(): @@ -21,7 +21,7 @@ def test_color(): init_color(num_colors=nc) msg('{:9}: {}'.format( desc, - ' '.join(globals()[c](c) for c in sorted(_colors)) )) + ' '.join( getattr(color_mod,c)(c) for c in sorted(color_mod._colors) ) )) init_color() gmsg("\nParsed terminfo 'colors' values:") diff --git a/test/include/coin_daemon_control.py b/test/include/coin_daemon_control.py index 1e40267a..abe6c421 100755 --- a/test/include/coin_daemon_control.py +++ b/test/include/coin_daemon_control.py @@ -64,11 +64,12 @@ if 'all' in cmd_args or 'no_xmr' in cmd_args: if len(cmd_args) != 1: die(1,"'all' or 'no_xmr' must be the sole argument") from mmgen.protocol import init_proto + import mmgen.daemon as daemon_mod for coin,data in CoinDaemon.coins.items(): if coin == 'XMR' and cmd_args[0] == 'no_xmr': continue for daemon_id in data.daemon_ids: - for network in globals()[daemon_id+'_daemon'].networks: + for network in getattr( daemon_mod, daemon_id+'_daemon' ).networks: run(proto=init_proto(coin=coin,network=network),daemon_id=daemon_id) else: ids = cmd_args diff --git a/test/misc/term.py b/test/misc/term.py index 3be702d0..baec5ebe 100755 --- a/test/misc/term.py +++ b/test/misc/term.py @@ -22,6 +22,7 @@ opts_data = { cmd_args = opts.init(opts_data) from mmgen.term import get_char,get_char_raw,get_terminal_size +import mmgen.term as term_mod def cmsg(m): msg('\n'+cyan(m)) @@ -68,7 +69,7 @@ def tt_line_input(): confirm(f'Did you enter the text {reply!r}?') def tt_get_char(raw=False,one_char=False,sleep=0,immed_chars=''): - fname = ('get_char','get_char_raw')[raw] + funcname = ('get_char','get_char_raw')[raw] fs = fmt(""" Press some keys in quick succession. {}{}{} @@ -105,14 +106,14 @@ def tt_get_char(raw=False,one_char=False,sleep=0,immed_chars=''): kwargs.update({'immed_chars':immed_chars}) cmsg('Testing {}({}):'.format( - fname, + funcname, ','.join(f'{a}={b!r}' for a,b in kwargs.items()) )) msg(fs.format( m1, yellow(m2), yellow(m3), yellow(m4) )) try: while True: - ret = globals()[fname]('Enter a letter: ',**kwargs) + ret = getattr( term_mod, funcname )('Enter a letter: ',**kwargs) msg(f'You typed {ret!r}') except KeyboardInterrupt: msg('\nDone') diff --git a/test/test_py_d/ts_regtest.py b/test/test_py_d/ts_regtest.py index 5c6b2bb3..2ce3ff2a 100755 --- a/test/test_py_d/ts_regtest.py +++ b/test/test_py_d/ts_regtest.py @@ -267,8 +267,10 @@ class TestSuiteRegtest(TestSuiteBase,TestSuiteShared): die(2,'--testnet and --regtest options incompatible with regtest test suite') self.proto = init_proto(self.proto.coin,network='regtest',need_amt=True) coin = self.proto.coin.lower() + + import test.test_py_d.ts_regtest as rt_mod for k in rt_data: - globals()[k] = rt_data[k][coin] if coin in rt_data[k] else None + setattr( rt_mod, k, rt_data[k][coin] if coin in rt_data[k] else None ) if self.proto.coin == 'BTC': self.test_rbf = True # tests are non-coin-dependent, so run just once for BTC diff --git a/test/unit_tests_d/ut_daemon.py b/test/unit_tests_d/ut_daemon.py index df1a53a3..39135b19 100755 --- a/test/unit_tests_d/ut_daemon.py +++ b/test/unit_tests_d/ut_daemon.py @@ -56,13 +56,14 @@ arm_skip_daemons = ('openethereum','parity') def test_cmds(op): network_ids = CoinDaemon.get_network_ids() + import mmgen.daemon as daemon_mod for test_suite in [True,False] if op == 'print' else [True]: vmsg(orange(f'Start commands (op={op}, test_suite={test_suite}):')) for coin,data in CoinDaemon.coins.items(): for daemon_id in data.daemon_ids: if daemon_id in arm_skip_daemons: continue - for network in globals()[daemon_id+'_daemon'].networks: + for network in getattr( daemon_mod, daemon_id+'_daemon' ).networks: if opt.no_altcoin_deps and coin != 'BTC': continue d = CoinDaemon(