From ffae4b4f55b6eb94047e861aa2efd5ecae4f631b Mon Sep 17 00:00:00 2001 From: The MMGen Project Date: Sat, 29 Jan 2022 11:23:38 +0000 Subject: [PATCH] remove dependence on string module (digits,hexdigits,ascii_letters) --- mmgen/addr.py | 3 +-- mmgen/color.py | 5 +---- mmgen/key.py | 5 ++--- mmgen/mn_entry.py | 11 +++++------ mmgen/obj.py | 6 +++--- mmgen/seed.py | 6 ++---- mmgen/tw.py | 3 +-- mmgen/util.py | 15 +++++++++------ 8 files changed, 24 insertions(+), 30 deletions(-) diff --git a/mmgen/addr.py b/mmgen/addr.py index 2d4d5579..1084c7e2 100755 --- a/mmgen/addr.py +++ b/mmgen/addr.py @@ -20,7 +20,6 @@ addr.py: MMGen address-related types """ -from string import ascii_letters,digits from collections import namedtuple from .objmethods import Hilite,InitErrors,MMGenObject @@ -142,7 +141,7 @@ class CoinAddr(str,Hilite,InitErrors,MMGenObject): if type(addr) == cls: return addr try: - assert set(addr) <= set(ascii_letters+digits),'contains non-alphanumeric characters' + assert addr.isascii() and addr.isalnum(), 'not an ASCII alphanumeric string' me = str.__new__(cls,addr) ap = proto.parse_addr(addr) assert ap, f'coin address {addr!r} could not be parsed' diff --git a/mmgen/color.py b/mmgen/color.py index d73ed66f..175eff37 100755 --- a/mmgen/color.py +++ b/mmgen/color.py @@ -57,16 +57,13 @@ def get_terminfo_colors(term=None): if term: cmd.append(term) - def is_hex_str(s): - from string import hexdigits - return set(list(s)) <= set(list(hexdigits)) - try: cmdout = run(cmd,stdout=PIPE,check=True).stdout.decode() except: return None else: s = [e.split('#')[1] for e in cmdout.split(',') if e.startswith('colors')][0] + from .util import is_hex_str if s.isdecimal(): return int(s) elif s.startswith('0x') and is_hex_str(s[2:]): diff --git a/mmgen/key.py b/mmgen/key.py index 72cb1a95..68d02336 100755 --- a/mmgen/key.py +++ b/mmgen/key.py @@ -20,7 +20,6 @@ key.py: MMGen public and private key objects """ -from string import ascii_letters,digits from .objmethods import Hilite,InitErrors,MMGenObject from .obj import ImmutableAttr,get_obj @@ -35,7 +34,7 @@ class WifKey(str,Hilite,InitErrors): if type(wif) == cls: return wif try: - assert set(wif) <= set(ascii_letters+digits),'not an ascii alphanumeric string' + assert wif.isascii() and wif.isalnum(), 'not an ASCII alphanumeric string' proto.parse_wif(wif) # raises exception on error return str.__new__(cls,wif) except Exception as e: @@ -76,7 +75,7 @@ class PrivKey(bytes,Hilite,InitErrors,MMGenObject): if wif: try: assert s == None,"'wif' and key hex args are mutually exclusive" - assert set(wif) <= set(ascii_letters+digits),'not an ascii alphanumeric string' + assert wif.isascii() and wif.isalnum(), 'not an ASCII alphanumeric string' k = proto.parse_wif(wif) # raises exception on error me = bytes.__new__(cls,k.sec) me.compressed = k.compressed diff --git a/mmgen/mn_entry.py b/mmgen/mn_entry.py index 7ce87117..0ba603f9 100755 --- a/mmgen/mn_entry.py +++ b/mmgen/mn_entry.py @@ -23,11 +23,10 @@ mn_entry.py - Mnemonic user entry methods for the MMGen suite import time from .globalvars import * -from .util import msg,msg_r,qmsg,fmt,fmt_list,capfirst,die +from .util import msg,msg_r,qmsg,fmt,fmt_list,capfirst,die,ascii_lowercase from .term import get_char,get_char_raw from .color import cyan -from string import ascii_lowercase as _word_chars _return_chars = '\n\r ' _erase_chars = '\b\x7f' @@ -82,7 +81,7 @@ class MnEntryModeFull(MnEntryMode): if ch in _return_chars: if s: break - elif ch in _word_chars: + elif ch in ascii_lowercase: s += ch else: pad += 1 @@ -122,7 +121,7 @@ class MnEntryModeShort(MnEntryMode): if ch in _return_chars: if s: break - elif ch in _word_chars: + elif ch in ascii_lowercase: s += ch if len(s) == self.ss_len: break @@ -165,7 +164,7 @@ class MnEntryModeFixed(MnEntryMode): if ch in _return_chars: if s: break - elif ch in _word_chars: + elif ch in ascii_lowercase: s += ch if len(s) + pad == self.ss_len: return mne.idx(s,'short') @@ -203,7 +202,7 @@ class MnEntryModeMinimal(MnEntryMode): if ch in _return_chars: if s: return mne.idx(s,'full',lo_idx=lo,hi_idx=hi) - elif ch in _word_chars: + elif ch in ascii_lowercase: s += ch ret = mne.idx(s,'minimal',lo_idx=lo,hi_idx=hi) if type(ret) != tuple: diff --git a/mmgen/obj.py b/mmgen/obj.py index 52e01c72..9c301ea5 100755 --- a/mmgen/obj.py +++ b/mmgen/obj.py @@ -21,8 +21,6 @@ obj.py: MMGen native classes """ import sys,os,re,unicodedata -from decimal import * -from string import hexdigits,ascii_letters,digits from .objmethods import * from .exception import BadTwComment @@ -310,10 +308,12 @@ class HexStr(str,Hilite,InitErrors): return s if case == None: case = cls.hexcase + from .util import hexdigits_lc,hexdigits_uc try: assert isinstance(s,str),'not a string or string subclass' assert case in ('upper','lower'), f'{case!r} incorrect case specifier' - assert set(s) <= set(getattr(hexdigits,case)()), f'not {case}case hexadecimal symbols' + assert set(s) <= set(hexdigits_lc if case == 'lower' else hexdigits_uc), ( + f'not {case}case hexadecimal symbols' ) assert not len(s) % 2,'odd-length string' if cls.width: assert len(s) == cls.width, f'Value is not {cls.width} characters wide' diff --git a/mmgen/seed.py b/mmgen/seed.py index 5c6367b0..2f28846d 100755 --- a/mmgen/seed.py +++ b/mmgen/seed.py @@ -20,9 +20,7 @@ seed.py: Seed-related classes and methods for the MMGen suite """ -from string import hexdigits - -from .util import make_chksum_8 +from .util import make_chksum_8,hexdigits_uc from .objmethods import Hilite,InitErrors,MMGenObject from .obj import ImmutableAttr,get_obj @@ -38,7 +36,7 @@ class SeedID(str,Hilite,InitErrors): assert isinstance(seed,SeedBase),'not a subclass of SeedBase' return str.__new__(cls,make_chksum_8(seed.data)) elif sid: - assert set(sid) <= set(hexdigits.upper()),'not uppercase hex digits' + assert set(sid) <= set(hexdigits_uc), 'not uppercase hex digits' assert len(sid) == cls.width, f'not {cls.width} characters wide' return str.__new__(cls,sid) raise ValueError('no arguments provided') diff --git a/mmgen/tw.py b/mmgen/tw.py index b5468052..99eed047 100755 --- a/mmgen/tw.py +++ b/mmgen/tw.py @@ -21,7 +21,6 @@ tw: Tracking wallet dependency classes for the MMGen suite """ import time -from string import ascii_letters,digits from .exception import BadTwLabel,BadTwComment from .objmethods import Hilite,InitErrors,MMGenObject @@ -72,7 +71,7 @@ class TwMMGenID(str,Hilite,InitErrors,MMGenObject): try: assert id_str.split(':',1)[0] == proto.base_coin.lower(),( f'not a string beginning with the prefix {proto.base_coin.lower()!r}:' ) - assert set(id_str[4:]) <= set(ascii_letters+digits),'contains non-alphanumeric characters' + assert id_str.isascii() and id_str[4:].isalnum(), 'not an ASCII alphanumeric string' assert len(id_str) > 4,'not more that four characters long' ret,sort_key,idtype = str(id_str),'z_'+id_str,'non-mmgen' except Exception as e2: diff --git a/mmgen/util.py b/mmgen/util.py index 645939c5..c79d7bbc 100755 --- a/mmgen/util.py +++ b/mmgen/util.py @@ -26,6 +26,12 @@ from .color import * from .globalvars import g from .opts import opt +ascii_lowercase = 'abcdefghijklmnopqrstuvwxyz' + +hexdigits = '0123456789abcdefABCDEF' +hexdigits_uc = '0123456789ABCDEF' +hexdigits_lc = '0123456789abcdef' + if g.platform == 'win': def msg_r(s): try: @@ -347,7 +353,7 @@ def make_chksum_6(s): return HexStr(sha256(s).hexdigest()[:6]) def is_chksum_6(s): - return len(s) == 6 and is_hex_str_lc(s) + return len(s) == 6 and set(s) <= set(hexdigits_lc) def make_iv_chksum(s): from hashlib import sha256 @@ -408,12 +414,10 @@ def is_int(s): return False def is_hex_str(s): - from string import hexdigits - return set(list(s.lower())) <= set(list(hexdigits.lower())) + return set(s) <= set(hexdigits) def is_hex_str_lc(s): - from string import hexdigits - return set(list(s)) <= set(list(hexdigits.lower())) + return set(s) <= set(hexdigits_lc) def is_utf8(s): try: s.decode('utf8') @@ -452,7 +456,6 @@ def pretty_hexdump(data,gw=2,cols=8,line_nums=None): return block_format(data.hex(),gw,cols,line_nums,data_is_hex=True) def decode_pretty_hexdump(data): - from string import hexdigits pat = re.compile(fr'^[{hexdigits}]+:\s+') lines = [pat.sub('',line) for line in data.splitlines()] try: