import sys import gc from trezorutils import halt, memcpy, set_mode_unprivileged, symbol, model # noqa: F401 def unimport_begin(): return set(sys.modules) def unimport_end(mods): for mod in sys.modules: if mod not in mods: # remove reference from sys.modules del sys.modules[mod] # remove reference from the parent module i = mod.rfind('.') if i < 0: continue path = mod[:i] name = mod[i + 1:] delattr(sys.modules[path], name) # collect removed modules gc.collect() def ensure(cond, msg=None): if not cond: if msg is None: raise AssertionError() else: raise AssertionError(msg) def chunks(items, size): for i in range(0, len(items), size): yield items[i:i + size] def split_words(sentence, width, metric=len): line = [] for w in sentence.split(' '): # empty word -> skip if not w: continue # new word will not fit -> break the line if metric(' '.join(line + [w])) >= width: yield ' '.join(line) line = [] # word is too wide -> split the word while metric(w) >= width: for i in range(1, len(w) + 1): if metric(w[:-i]) < width: yield w[:-i] + '-' w = w[-i:] break line.append(w) yield ' '.join(line) def format_amount(amount, decimals): d = pow(10, decimals) amount = ('%d.%0*d' % (amount // d, decimals, amount % d)).rstrip('0') if amount.endswith('.'): amount = amount[:-1] return amount def format_ordinal(number): return str(number) + {1: 'st', 2: 'nd', 3: 'rd'}.get(4 if 10 <= number % 100 < 20 else number % 10, 'th') class HashWriter: def __init__(self, hashfunc): self.ctx = hashfunc() self.buf = bytearray(1) # used in append() def extend(self, buf: bytearray): self.ctx.update(buf) def append(self, b: int): self.buf[0] = b self.ctx.update(self.buf) def get_digest(self, *args) -> bytes: return self.ctx.digest(*args)