From 6b3ea8b251a098278b295634e7a3c20a5d64d218 Mon Sep 17 00:00:00 2001 From: The MMGen Project Date: Wed, 19 Jan 2022 11:43:51 +0000 Subject: [PATCH] permit execution of scripts with docstrings removed - scripts now run with PYTHONOPTIMIZE=2, though PYTHONOPTIMIZE should never be set in a production environment --- mmgen/tool.py | 21 +++++++++++---------- test/test.py | 8 ++++++-- test/tooltest2.py | 8 +++++--- 3 files changed, 22 insertions(+), 15 deletions(-) diff --git a/mmgen/tool.py b/mmgen/tool.py index 4d575647..a8a651e3 100755 --- a/mmgen/tool.py +++ b/mmgen/tool.py @@ -247,7 +247,7 @@ class MMGenToolCmdMeta(type): classes = {} methods = {} def __new__(mcls,name,bases,namespace): - methods = {k:v for k,v in namespace.items() if k[0] != '_' and callable(v) and v.__doc__} + methods = { k:v for k,v in namespace.items() if k[0] != '_' and callable(v) } cls = super().__new__(mcls,name,bases,namespace) if bases and name != 'tool_api': mcls.classes[name] = cls @@ -273,6 +273,7 @@ class MMGenToolCmdMeta(type): def user_commands(cls): return {k:v for k,v in cls.__dict__.items() if k in cls.methods} +# all non-user-visible methods must begin with an underscore! class MMGenToolCmds(metaclass=MMGenToolCmdMeta): def __init__(self,proto=None,mmtype=None): @@ -282,7 +283,7 @@ class MMGenToolCmds(metaclass=MMGenToolCmdMeta): if g.token: self.proto.tokensym = g.token.upper() - def init_generators(self,arg=None): + def _init_generators(self,arg=None): gd = namedtuple('generator_data',['at','kg','ag']) at = MMGenAddrType( @@ -439,7 +440,7 @@ class MMGenToolCmdCoin(MMGenToolCmds): """ def randwif(self): "generate a random private key in WIF format" - gd = self.init_generators('addrtype_only') + gd = self._init_generators('addrtype_only') return PrivKey( self.proto, get_random(32), @@ -448,7 +449,7 @@ class MMGenToolCmdCoin(MMGenToolCmds): def randpair(self): "generate a random private key/address pair" - gd = self.init_generators() + gd = self._init_generators() privkey = PrivKey( self.proto, get_random(32), @@ -465,7 +466,7 @@ class MMGenToolCmdCoin(MMGenToolCmds): def hex2wif(self,privhex:'sstr'): "convert a private key from hex to WIF format" - gd = self.init_generators('addrtype_only') + gd = self._init_generators('addrtype_only') return PrivKey( self.proto, bytes.fromhex(privhex), @@ -474,7 +475,7 @@ class MMGenToolCmdCoin(MMGenToolCmds): def wif2addr(self,wifkey:'sstr'): "generate a coin address from a key in WIF format" - gd = self.init_generators() + gd = self._init_generators() privkey = PrivKey( self.proto, wif = wifkey ) @@ -484,7 +485,7 @@ class MMGenToolCmdCoin(MMGenToolCmds): def wif2redeem_script(self,wifkey:'sstr'): # new "convert a WIF private key to a Segwit P2SH-P2WPKH redeem script" assert self.mmtype.name == 'segwit','This command is meaningful only for --type=segwit' - gd = self.init_generators() + gd = self._init_generators() privkey = PrivKey( self.proto, wif = wifkey ) @@ -493,7 +494,7 @@ class MMGenToolCmdCoin(MMGenToolCmds): def wif2segwit_pair(self,wifkey:'sstr'): "generate both a Segwit P2SH-P2WPKH redeem script and address from WIF" assert self.mmtype.name == 'segwit','This command is meaningful only for --type=segwit' - gd = self.init_generators() + gd = self._init_generators() data = gd.kg.gen_data(PrivKey( self.proto, wif = wifkey )) @@ -503,7 +504,7 @@ class MMGenToolCmdCoin(MMGenToolCmds): def privhex2addr(self,privhex:'sstr',output_pubhex=False): "generate coin address from raw private key data in hexadecimal format" - gd = self.init_generators() + gd = self._init_generators() pk = PrivKey( self.proto, bytes.fromhex(privhex), @@ -542,7 +543,7 @@ class MMGenToolCmdCoin(MMGenToolCmds): if self.mmtype.name == 'bech32': return self.proto.pubhash2bech32addr( pubhash ) else: - gd = self.init_generators('addrtype_only') + gd = self._init_generators('addrtype_only') return self.proto.pubhash2addr( pubhash, gd.at.addr_fmt=='p2sh' ) def addr2pubhash(self,addr:'sstr'): diff --git a/test/test.py b/test/test.py index 42bbdb01..104f3e3e 100755 --- a/test/test.py +++ b/test/test.py @@ -385,7 +385,8 @@ def list_cmds(): Msg(green('AVAILABLE COMMANDS:')) for gname in gm.cmd_groups: ts = gm.gm_init_group(None,gname,None) - d.append((gname,ts.__doc__.strip(),gm.cmd_list,gm.dpy_data)) + desc = ts.__doc__.strip() if ts.__doc__ else type(ts).__name__ + d.append( (gname,desc,gm.cmd_list,gm.dpy_data) ) cw = max(max(len(k) for k in gm.dpy_data),cw) for gname,gdesc,clist,dpdata in d: @@ -590,7 +591,10 @@ class CmdGroupMgr(object): and g[0] in tuple(self.cmd_groups_dfl) + tuple(usr_args) ] for name,cls in ginfo: - msg(f'{name:17} - {cls.__doc__.strip()}') + msg('{:17} - {}'.format( + name, + cls.__doc__.strip() if cls.__doc__ else cls.__name__ + )) Die(0,'\n'+' '.join(e[0] for e in ginfo)) diff --git a/test/tooltest2.py b/test/tooltest2.py index 6d72521b..cc61c798 100755 --- a/test/tooltest2.py +++ b/test/tooltest2.py @@ -922,12 +922,14 @@ async def run_test(gid,cmd_name): msg('OK') def docstring_head(obj): - return obj.__doc__.strip().split('\n')[0] + return obj.__doc__.strip().split('\n')[0] if obj.__doc__ else None async def do_group(gid): + desc = f'command group {gid!r}' qmsg(blue('Testing ' + - f'command group {gid!r}' if opt.names else - docstring_head(tc.classes['MMGenToolCmd'+gid]) )) + desc if opt.names else + ( docstring_head(tc.classes['MMGenToolCmd'+gid]) or desc ) + )) for cname in tc.classes['MMGenToolCmd'+gid].user_commands: if cname in skipped_tests: