From 85ba7c12baa02e57174effc824413bf0d1ddde10 Mon Sep 17 00:00:00 2001 From: amadejpapez Date: Mon, 27 Sep 2021 12:13:51 +0200 Subject: [PATCH] style(all): use f-strings for formatting [no changelog] --- ci/hardware_tests/device/device.py | 18 ++--- ci/hardware_tests/device/t1.py | 10 +-- ci/hardware_tests/device/tt.py | 4 +- common/protob/graph.py | 11 +-- common/tools/coin_info.py | 20 ++--- common/tools/cointool.py | 30 ++++---- common/tools/marketcap.py | 2 +- common/tools/maxfee.py | 12 ++- core/prof/prof.py | 2 +- .../site_tools/micropython/__init__.py | 2 +- .../site_tools/micropython/qstrdefs.py | 2 +- core/src/apps/bitcoin/get_address.py | 2 +- core/src/apps/bitcoin/sign_tx/layout.py | 2 +- core/src/apps/bitcoin/sign_tx/omni.py | 18 ++--- core/src/apps/cardano/helpers/credential.py | 6 +- core/src/apps/cardano/helpers/paths.py | 6 +- core/src/apps/cardano/helpers/utils.py | 4 +- core/src/apps/cardano/layout.py | 53 ++++++------- core/src/apps/cardano/sign_tx.py | 6 +- core/src/apps/common/cbor.py | 4 +- core/src/apps/common/coininfo.py | 2 +- core/src/apps/common/coininfo.py.mako | 2 +- core/src/apps/common/passphrase.py | 2 +- core/src/apps/common/signverify.py | 2 +- core/src/apps/debug/__init__.py | 4 +- core/src/apps/eos/actions/layout.py | 26 +++---- core/src/apps/eos/helpers.py | 4 +- core/src/apps/ethereum/layout.py | 4 +- core/src/apps/management/apply_settings.py | 4 +- .../management/recovery_device/__init__.py | 4 +- .../management/recovery_device/homescreen.py | 4 +- .../apps/management/reset_device/layout.py | 16 ++-- core/src/apps/misc/get_ecdh_session_key.py | 2 +- core/src/apps/monero/diag.py | 4 +- core/src/apps/monero/layout.py | 12 +-- .../apps/monero/signing/step_02_set_input.py | 3 +- .../apps/monero/signing/step_06_set_output.py | 2 +- .../monero/signing/step_07_all_outputs_set.py | 10 +-- core/src/apps/monero/xmr/bulletproof.py | 2 +- core/src/apps/monero/xmr/networks.py | 2 +- .../monero/xmr/serialize/message_types.py | 4 +- core/src/apps/nem/layout.py | 4 +- core/src/apps/nem/transfer/layout.py | 6 +- core/src/apps/nem/validators.py | 8 +- core/src/apps/stellar/operations/layout.py | 6 +- core/src/apps/webauthn/credential.py | 7 +- core/src/apps/webauthn/fido2.py | 2 +- core/src/storage/cache.py | 2 +- core/src/storage/sd_salt.py | 2 +- core/src/trezor/crypto/slip39.py | 30 ++------ core/src/trezor/loop.py | 2 +- core/src/trezor/pin.py | 2 +- core/src/trezor/strings.py | 6 +- core/src/trezor/ui/components/tt/button.py | 2 +- core/src/trezor/ui/components/tt/reset.py | 18 ++--- core/src/trezor/ui/layouts/common.py | 3 +- core/src/trezor/ui/layouts/tt/__init__.py | 14 ++-- core/src/trezor/ui/layouts/tt/altcoin.py | 2 +- core/src/trezor/ui/layouts/tt/recovery.py | 8 +- core/src/trezor/ui/layouts/tt/reset.py | 30 ++++---- core/src/trezor/utils.py | 12 +-- core/src/trezor/wire/__init__.py | 4 +- core/tests/production_tests/main.py | 2 +- core/tests/test_apps.common.paths.py | 10 +-- core/tests/test_trezor.io.fatfs.py | 76 +++++++++---------- core/tests/unittest.py | 46 +++++------ core/tools/alloc.py | 12 ++- core/tools/build_mocks | 4 +- core/tools/headertool.py | 20 +++-- core/tools/hid-bridge/hid_interface.py | 38 +++++----- core/tools/hid-bridge/logger.py | 8 +- core/tools/hid-bridge/udp_interface.py | 8 +- core/tools/hid-bridge/uhid.py | 6 +- legacy/bootloader/combine/prepare.py | 6 +- legacy/bootloader/firmware_align.py | 3 +- legacy/bootloader/firmware_sign.py | 12 +-- legacy/firmware/bl_data.py | 4 +- legacy/firmware/protob/messages_map.py | 24 +++--- legacy/gen/bitmaps/generate.py | 8 +- legacy/gen/handlers/handlers.py | 5 +- legacy/script/fingerprint | 3 +- legacy/script/wait_for_emulator.py | 2 +- python/setup.py | 2 +- python/src/trezorlib/_internal/emulator.py | 20 ++--- .../trezorlib/_internal/firmware_headers.py | 20 ++--- python/src/trezorlib/btc.py | 2 +- python/src/trezorlib/cli/__init__.py | 2 +- python/src/trezorlib/cli/debug.py | 6 +- python/src/trezorlib/cli/eos.py | 2 +- python/src/trezorlib/cli/ethereum.py | 17 +++-- python/src/trezorlib/cli/fido.py | 24 +++--- python/src/trezorlib/cli/nem.py | 4 +- python/src/trezorlib/cli/trezorctl.py | 16 ++-- python/src/trezorlib/client.py | 14 ++-- python/src/trezorlib/debuglink.py | 22 +++--- python/src/trezorlib/eos.py | 2 +- python/src/trezorlib/exceptions.py | 2 +- python/src/trezorlib/firmware.py | 12 ++- python/src/trezorlib/log.py | 2 +- python/src/trezorlib/mapping.py | 3 +- python/src/trezorlib/protobuf.py | 6 +- python/src/trezorlib/stellar.py | 2 +- python/src/trezorlib/toif.py | 6 +- python/src/trezorlib/tools.py | 4 +- python/src/trezorlib/transport/__init__.py | 12 ++- python/src/trezorlib/transport/bridge.py | 14 ++-- python/src/trezorlib/transport/hid.py | 14 ++-- python/src/trezorlib/transport/udp.py | 14 ++-- python/src/trezorlib/transport/webusb.py | 12 +-- python/src/trezorlib/ui.py | 8 +- python/tools/build_tx.py | 2 +- python/tools/encfs_aes_getpass.py | 4 +- python/tools/pwd_reader.py | 4 +- storage/tests/python/src/storage.py | 2 +- tests/burn_tests/burntest_t1.py | 2 +- tests/burn_tests/burntest_t2.py | 2 +- tests/click_tests/recovery.py | 2 +- tests/conftest.py | 2 +- tests/device_tests/test_msg_getaddress.py | 14 ++-- .../test_msg_getaddress_segwit.py | 4 +- .../test_msg_getaddress_segwit_native.py | 8 +- tests/device_tests/test_msg_getentropy.py | 2 +- .../test_msg_getownershipproof.py | 2 +- tests/ui_tests/__init__.py | 7 +- tests/ui_tests/reporting/download.py | 2 +- tests/upgrade_tests/test_firmware_upgrades.py | 4 +- tools/bump-version.py | 2 +- tools/generate-changelog.py | 2 +- tools/github_issues_to_csv.py | 4 +- 129 files changed, 508 insertions(+), 623 deletions(-) diff --git a/ci/hardware_tests/device/device.py b/ci/hardware_tests/device/device.py index 4aa4f59f1..67c5bf756 100644 --- a/ci/hardware_tests/device/device.py +++ b/ci/hardware_tests/device/device.py @@ -16,7 +16,7 @@ class Device: def run_trezorctl(self, cmd: str, **kwargs): full_cmd = "trezorctl " full_cmd += cmd - self.log("[software/trezorctl] Running '{}'".format(full_cmd)) + self.log(f"[software/trezorctl] Running '{full_cmd}'") return run(full_cmd, shell=True, check=True, **kwargs) def check_model(self, model=None): @@ -26,11 +26,9 @@ class Device: self.run_trezorctl("get-features | grep version") lines = res.stdout.splitlines() if len(lines) != 1: - raise RuntimeError("{} trezors connected".format(len(lines))) + raise RuntimeError(f"{len(lines)} trezors connected") if model and model not in lines[0]: - raise RuntimeError( - "invalid trezor model connected (expected {})".format(model) - ) + raise RuntimeError(f"invalid trezor model connected (expected {model})") return lines[0].split()[0] def reboot(self): @@ -41,7 +39,7 @@ class Device: self.now() self.log("[hardware/usb] Turning power on...") run( - "uhubctl -l {} -p {} -a on".format(self.uhub_location, self.device_port), + f"uhubctl -l {self.uhub_location} -p {self.device_port} -a on", shell=True, check=True, ) @@ -51,9 +49,7 @@ class Device: self.now() self.log("[hardware/usb] Turning power off...") run( - "uhubctl -l {} -p {} -r 100 -a off".format( - self.uhub_location, self.device_port - ), + f"uhubctl -l {self.uhub_location} -p {self.device_port} -r 100 -a off", shell=True, check=True, ) @@ -65,9 +61,9 @@ class Device: @staticmethod def wait(seconds): Device.now() - Device.log("[software] Waiting for {} seconds...".format(seconds)) + Device.log(f"[software] Waiting for {seconds} seconds...") time.sleep(seconds) @staticmethod def now(): - Device.log("\n[timestamp] {}".format(datetime.datetime.now())) + Device.log(f"\n[timestamp] {datetime.datetime.now()}") diff --git a/ci/hardware_tests/device/t1.py b/ci/hardware_tests/device/t1.py index 5acb0e20b..c1ae63248 100644 --- a/ci/hardware_tests/device/t1.py +++ b/ci/hardware_tests/device/t1.py @@ -10,16 +10,14 @@ class TrezorOne(Device): def touch(self, location, action): self.now() - self.log( - "[hardware/trezor] Touching the {} button by {}...".format(location, action) - ) - self.serial.write(("{} {}\n".format(location, action)).encode()) + self.log(f"[hardware/trezor] Touching the {location} button by {action}...") + self.serial.write(f"{location} {action}\n".encode()) def update_firmware(self, file=None): if file: unofficial = True - trezorctlcmd = "firmware-update -s -f {} &".format(file) - self.log("[software] Updating the firmware to {}".format(file)) + trezorctlcmd = f"firmware-update -s -f {file} &" + self.log(f"[software] Updating the firmware to {file}") else: unofficial = False trezorctlcmd = "firmware-update &" diff --git a/ci/hardware_tests/device/tt.py b/ci/hardware_tests/device/tt.py index a34e7b99b..3cf66618a 100644 --- a/ci/hardware_tests/device/tt.py +++ b/ci/hardware_tests/device/tt.py @@ -21,8 +21,8 @@ class TrezorT(Device): self.power_on() self.wait(5) - self.log("[software] Updating the firmware to {}".format(file)) - self.run_trezorctl("firmware-update -s -f {}".format(file)) + self.log(f"[software] Updating the firmware to {file}") + self.run_trezorctl(f"firmware-update -s -f {file}") # after firmware-update finishes wait for reboot self.wait(15) diff --git a/common/protob/graph.py b/common/protob/graph.py index 362a1d8b1..b16e11edf 100755 --- a/common/protob/graph.py +++ b/common/protob/graph.py @@ -10,7 +10,7 @@ class Message(object): self.fname = basename(fname) self.name = name if len(attrs) == 0: - raise ValueError("message '%s' has no attributes" % name) + raise ValueError(f"message {name} has no attributes") t = attrs[0][0] if t in ["start", "end", "auxstart", "auxend", "embed", "ignore"]: self.typ = t @@ -19,19 +19,14 @@ class Message(object): self.typ = "normal" attrs = attrs else: - raise ValueError("wrong message type in message '%s'" % name) + raise ValueError(f"wrong message type in message {name}") self.next = [] for a in attrs: if a[0] == "next": self.next.append(a[1]) def __repr__(self): - return '%s(type=%s, fname="%s", next=%s)' % ( - self.name, - self.typ, - self.fname, - self.next, - ) + return f'{self.name}(type={self.typ}, fname="{self.fname}", next={self.next})' def generate_messages(files): diff --git a/common/tools/coin_info.py b/common/tools/coin_info.py index 274004baf..194c54e94 100755 --- a/common/tools/coin_info.py +++ b/common/tools/coin_info.py @@ -73,7 +73,7 @@ def check_type(val, types, nullable=False, empty=False, regex=None, choice=None) # check type if not isinstance(val, types): - raise TypeError("Wrong type (expected: {})".format(types)) + raise TypeError(f"Wrong type (expected: {types})") # check empty if isinstance(val, (list, dict)) and not empty and not val: @@ -86,12 +86,12 @@ def check_type(val, types, nullable=False, empty=False, regex=None, choice=None) if types is not str: raise TypeError("Wrong type for regex check") if not re.search(regex, val): - raise ValueError("Value does not match regex {}".format(regex)) + raise ValueError(f"Value does not match regex {regex}") # check choice if choice is not None and val not in choice: choice_str = ", ".join(choice) - raise ValueError("Value not allowed, use one of: {}".format(choice_str)) + raise ValueError(f"Value not allowed, use one of: {choice_str}") def check_key(key, types, optional=False, **kwargs): @@ -100,11 +100,11 @@ def check_key(key, types, optional=False, **kwargs): if optional: return else: - raise KeyError("{}: Missing key".format(key)) + raise KeyError(f"{key}: Missing key") try: check_type(coin[key], types, **kwargs) except Exception as e: - raise ValueError("{}: {}".format(key, e)) from e + raise ValueError(f"{key}: {e}") from e return do_check @@ -216,7 +216,7 @@ def _load_btc_coins(): coin.update( name=coin["coin_label"], shortcut=coin["coin_shortcut"], - key="bitcoin:{}".format(coin["coin_shortcut"]), + key=f"bitcoin:{coin['coin_shortcut']}", icon=str(file.with_suffix(".png")), ) coins.append(coin) @@ -280,7 +280,7 @@ def _load_erc20_tokens(): chain_id=network["chain_id"], address_bytes=bytes.fromhex(token["address"][2:]), shortcut=token["symbol"], - key="erc20:{}:{}".format(chain, token["symbol"]), + key=f"erc20:{chain}:{token['symbol']}", ) tokens.append(token) @@ -292,7 +292,7 @@ def _load_nem_mosaics(): mosaics = load_json("nem/nem_mosaics.json") for mosaic in mosaics: shortcut = mosaic["ticker"].strip() - mosaic.update(shortcut=shortcut, key="nem:{}".format(shortcut)) + mosaic.update(shortcut=shortcut, key=f"nem:{shortcut}") return mosaics @@ -300,7 +300,7 @@ def _load_misc(): """Loads miscellaneous networks from `misc/misc.json`""" others = load_json("misc/misc.json") for other in others: - other.update(key="misc:{}".format(other["shortcut"])) + other.update(key=f"misc:{other['shortcut']}") return others @@ -544,7 +544,7 @@ def deduplicate_keys(all_coins): elif "chain_id" in coin: coin["key"] += ":" + str(coin["chain_id"]) else: - coin["key"] += ":{}".format(i) + coin["key"] += f":{i}" coin["dup_key_nontoken"] = True diff --git a/common/tools/cointool.py b/common/tools/cointool.py index 7e9c2966c..538a59540 100755 --- a/common/tools/cointool.py +++ b/common/tools/cointool.py @@ -149,8 +149,8 @@ def highlight_key(coin, color): else: keylist[-1] = crayon(color, keylist[-1], bold=True) key = crayon(color, ":".join(keylist)) - name = crayon(None, "({})".format(coin["name"]), dim=True) - return "{} {}".format(key, name) + name = crayon(None, f"({coin['name']})", dim=True) + return f"{key} {name}" def find_collisions(coins, field): @@ -169,9 +169,7 @@ def check_eth(coins): check_passed = True chains = find_collisions(coins, "chain") for key, bucket in chains.items(): - bucket_str = ", ".join( - "{} ({})".format(coin["key"], coin["name"]) for coin in bucket - ) + bucket_str = ", ".join(f"{coin['key']} ({coin['name']})" for coin in bucket) chain_name_str = "colliding chain name " + crayon(None, key, bold=True) + ":" print_log(logging.ERROR, chain_name_str, bucket_str) check_passed = False @@ -240,7 +238,7 @@ def check_btc(coins): else: # collision between some unsupported networks is OK level = logging.INFO - print_log(level, "{} {}:".format(prefix, key), collision_str(bucket)) + print_log(level, f"{prefix} {key}:", collision_str(bucket)) return failed @@ -298,7 +296,7 @@ def check_dups(buckets, print_at_level=logging.WARNING): prefix = crayon("green", "*", bold=True) + prefix highlighted = highlight_key(coin, color) - return "{}{}".format(prefix, highlighted) + return f"{prefix}{highlighted}" check_passed = True @@ -344,7 +342,7 @@ def check_dups(buckets, print_at_level=logging.WARNING): if symbol == "_override": print_log(level, "force-set duplicates:", dup_str) else: - print_log(level, "duplicate symbol {}:".format(symbol.upper()), dup_str) + print_log(level, f"duplicate symbol {symbol.upper()}:", dup_str) return check_passed @@ -417,14 +415,12 @@ def check_key_uniformity(coins): keyset = set(coin.keys()) | IGNORE_NONUNIFORM_KEYS missing = ", ".join(reference_keyset - keyset) if missing: - print_log( - logging.ERROR, "coin {} has missing keys: {}".format(key, missing) - ) + print_log(logging.ERROR, f"coin {key} has missing keys: {missing}") additional = ", ".join(keyset - reference_keyset) if additional: print_log( logging.ERROR, - "coin {} has superfluous keys: {}".format(key, additional), + f"coin {key} has superfluous keys: {additional}", ) return False @@ -446,7 +442,7 @@ def check_segwit(coins): print_log( logging.ERROR, coin["name"], - "segwit is True => %s should be set" % field, + f"segwit is True => {field} should be set", ) return False else: @@ -455,7 +451,7 @@ def check_segwit(coins): print_log( logging.ERROR, coin["name"], - "segwit is False => %s should NOT be set" % field, + f"segwit is False => {field} should NOT be set", ) return False return True @@ -863,7 +859,7 @@ def render(paths, outfile, verbose, bitcoin_only): def do_render(src, dst): if verbose: - click.echo("Rendering {} => {}".format(src, dst)) + click.echo(f"Rendering {src} => {dst}") render_file(src, dst, defs, support_info) # single in-out case @@ -878,7 +874,7 @@ def render(paths, outfile, verbose, bitcoin_only): files = [] for path in paths: if not os.path.exists(path): - click.echo("Path {} does not exist".format(path)) + click.echo(f"Path {path} does not exist") elif os.path.isdir(path): files += glob.glob(os.path.join(path, "*.mako")) else: @@ -887,7 +883,7 @@ def render(paths, outfile, verbose, bitcoin_only): # render each file for file in files: if not file.endswith(".mako"): - click.echo("File {} does not end with .mako".format(file)) + click.echo(f"File {file} does not end with .mako") else: target = file[: -len(".mako")] with open(target, "w") as dst: diff --git a/common/tools/marketcap.py b/common/tools/marketcap.py index 94bef4db4..2dc7c8093 100644 --- a/common/tools/marketcap.py +++ b/common/tools/marketcap.py @@ -47,7 +47,7 @@ def init(api_key, refresh=None): first_100 = all_ids[:100] all_ids = all_ids[100:] time.sleep(2.2) - print("Fetching metadata, {} coins remaining...".format(len(all_ids))) + print(f"Fetching metadata, {len(all_ids)} coins remaining...") metadata = call( "cryptocurrency/info", api_key, params={"id": ",".join(first_100)} ) diff --git a/common/tools/maxfee.py b/common/tools/maxfee.py index b1df0830a..d0ec7baef 100644 --- a/common/tools/maxfee.py +++ b/common/tools/maxfee.py @@ -96,12 +96,12 @@ def main(filename, cost, skip, txsize, refresh, api_key, verbose): short = coin["coin_shortcut"] if any(re.search(s, coin["coin_name"]) is not None for s in skip): - logging.warning("{}:\tskipping because --skip matches".format(short)) + logging.warning(f"{short}:\tskipping because --skip matches") continue price = marketcap.fiat_price(short) if price is None: - logging.error("{}:\tno price data, skipping".format(short)) + logging.error(f"{short}:\tno price data, skipping") continue old_maxfee_kb = coin["maxfee_kb"] @@ -111,14 +111,12 @@ def main(filename, cost, skip, txsize, refresh, api_key, verbose): with open(filename, "w") as fh: json.dump(coin, fh, indent=2) fh.write("\n") - logging.info( - "{}:\tupdated {} -> {}".format(short, old_maxfee_kb, new_maxfee_kb) - ) + logging.info(f"{short}:\tupdated {old_maxfee_kb} -> {new_maxfee_kb}") delta = delta_percent(old_maxfee_kb, new_maxfee_kb) if delta > MAX_DELTA_PERCENT: - logging.warning("{}:\tprice has changed by {} %".format(short, delta)) + logging.warning(f"{short}:\tprice has changed by {delta} %") else: - logging.info("{}:\tno change".format(short)) + logging.info(f"{short}:\tno change") if __name__ == "__main__": diff --git a/core/prof/prof.py b/core/prof/prof.py index 9c81042f5..fd72c3e82 100644 --- a/core/prof/prof.py +++ b/core/prof/prof.py @@ -82,7 +82,7 @@ class AllocCounter: allocs_per_last_line = allocs_now - self.last_alloc_count self.count_last_line(allocs_per_last_line) - self.last_line = "{}:{}".format(frame.f_code.co_filename, frame.f_lineno) + self.last_line = f"{frame.f_code.co_filename}:{frame.f_lineno}" self.last_alloc_count = micropython.alloc_count() def dump_data(self, filename): diff --git a/core/site_scons/site_tools/micropython/__init__.py b/core/site_scons/site_tools/micropython/__init__.py index 057a896d6..9fd37183c 100644 --- a/core/site_scons/site_tools/micropython/__init__.py +++ b/core/site_scons/site_tools/micropython/__init__.py @@ -26,7 +26,7 @@ def generate(env): # replace "utils.BITCOIN_ONLY" with literal constant (True/False) # so the compiler can optimize out the things we don't want btc_only = env['bitcoin_only'] == '1' - interim = "%s.i" % target[:-4] # replace .mpy with .i + interim = f"{target[:-4]}.i" # replace .mpy with .i sed_scripts = " ".join([ f"-e 's/utils\.BITCOIN_ONLY/{btc_only}/g'", "-e 's/if TYPE_CHECKING/if False/'", diff --git a/core/site_scons/site_tools/micropython/qstrdefs.py b/core/site_scons/site_tools/micropython/qstrdefs.py index 8560ec73b..718935989 100644 --- a/core/site_scons/site_tools/micropython/qstrdefs.py +++ b/core/site_scons/site_tools/micropython/qstrdefs.py @@ -7,7 +7,7 @@ def process(source, target): for line in source: for match in re_qstr.findall(line): name = match.replace("MP_QSTR_", "") - target.write("Q(%s)\n" % name) + target.write(f"Q({name})\n") if __name__ == "__main__": diff --git a/core/src/apps/bitcoin/get_address.py b/core/src/apps/bitcoin/get_address.py index 5a954c72a..29fd56d3d 100644 --- a/core/src/apps/bitcoin/get_address.py +++ b/core/src/apps/bitcoin/get_address.py @@ -81,7 +81,7 @@ async def get_address( pubnodes = [hd.node for hd in msg.multisig.pubkeys] multisig_index = multisig_pubkey_index(msg.multisig, node.public_key()) - title = "Multisig %d of %d" % (msg.multisig.m, len(pubnodes)) + title = f"Multisig {msg.multisig.m} of {len(pubnodes)}" await show_address( ctx, address=address_short, diff --git a/core/src/apps/bitcoin/sign_tx/layout.py b/core/src/apps/bitcoin/sign_tx/layout.py index a79e05386..2b35669b3 100644 --- a/core/src/apps/bitcoin/sign_tx/layout.py +++ b/core/src/apps/bitcoin/sign_tx/layout.py @@ -35,7 +35,7 @@ def format_coin_amount(amount: int, coin: CoinInfo, amount_unit: AmountUnit) -> decimals -= 3 shortcut = "m" + shortcut # we don't need to do anything for AmountUnit.BITCOIN - return "%s %s" % (format_amount(amount, decimals), shortcut) + return f"{format_amount(amount, decimals)} {shortcut}" async def confirm_output( diff --git a/core/src/apps/bitcoin/sign_tx/omni.py b/core/src/apps/bitcoin/sign_tx/omni.py index 399d2df81..a128dd7e7 100644 --- a/core/src/apps/bitcoin/sign_tx/omni.py +++ b/core/src/apps/bitcoin/sign_tx/omni.py @@ -1,12 +1,15 @@ +from micropython import const from ustruct import unpack from trezor.strings import format_amount +_OMNI_DECIMALS = const(8) + currencies = { - 1: ("OMNI", True), - 2: ("tOMNI", True), - 3: ("MAID", False), - 31: ("USDT", True), + 1: ("OMNI", _OMNI_DECIMALS), + 2: ("tOMNI", _OMNI_DECIMALS), + 3: ("MAID", 0), + 31: ("USDT", _OMNI_DECIMALS), } @@ -20,11 +23,8 @@ def parse(data: bytes) -> str: tx_version, tx_type = unpack(">HH", data[4:8]) if tx_version == 0 and tx_type == 0 and len(data) == 20: # OMNI simple send currency, amount = unpack(">IQ", data[8:20]) - suffix, divisible = currencies.get(currency, ("UNKN", False)) - return "Simple send of %s %s" % ( - format_amount(amount, 8 if divisible else 0), - suffix, - ) + suffix, decimals = currencies.get(currency, ("UNKN", 0)) + return f"Simple send of {format_amount(amount, decimals)} {suffix}" else: # unknown OMNI transaction return "Unknown transaction" diff --git a/core/src/apps/cardano/helpers/credential.py b/core/src/apps/cardano/helpers/credential.py index 6b6cd70fd..644b2076d 100644 --- a/core/src/apps/cardano/helpers/credential.py +++ b/core/src/apps/cardano/helpers/credential.py @@ -188,9 +188,9 @@ class Credential: return [(None, format_script_hash(self.script_hash))] elif self.pointer: return [ - ("Block: %s" % self.pointer.block_index, None), - ("Transaction: %s" % self.pointer.tx_index, None), - ("Certificate: %s" % self.pointer.certificate_index, None), + (f"Block: {self.pointer.block_index}", None), + (f"Transaction: {self.pointer.tx_index}", None), + (f"Certificate: {self.pointer.certificate_index}", None), ] else: return [] diff --git a/core/src/apps/cardano/helpers/paths.py b/core/src/apps/cardano/helpers/paths.py index 443886a6f..c9dc839d7 100644 --- a/core/src/apps/cardano/helpers/paths.py +++ b/core/src/apps/cardano/helpers/paths.py @@ -12,11 +12,11 @@ MINTING_ROOT = [1855 | HARDENED, SLIP44_ID | HARDENED] # fmt: off SCHEMA_PUBKEY = PathSchema.parse("m/[44,1852,1854]'/coin_type'/account'/*", SLIP44_ID) # minting has a specific schema for key derivation - see CIP-1855 -SCHEMA_MINT = PathSchema.parse("m/1855'/coin_type'/[0-%s]'" % (HARDENED - 1), SLIP44_ID) +SCHEMA_MINT = PathSchema.parse(f"m/1855'/coin_type'/[0-{HARDENED - 1}]'", SLIP44_ID) SCHEMA_PAYMENT = PathSchema.parse("m/[44,1852]'/coin_type'/account'/[0,1]/address_index", SLIP44_ID) # staking is only allowed on Shelley paths with suffix /2/0 -SCHEMA_STAKING = PathSchema.parse("m/[1852]'/coin_type'/account'/2/0", SLIP44_ID) -SCHEMA_STAKING_ANY_ACCOUNT = PathSchema.parse("m/[1852]'/coin_type'/[0-%s]'/2/0" % (HARDENED - 1), SLIP44_ID) +SCHEMA_STAKING = PathSchema.parse("m/1852'/coin_type'/account'/2/0", SLIP44_ID) +SCHEMA_STAKING_ANY_ACCOUNT = PathSchema.parse(f"m/1852'/coin_type'/[0-{HARDENED - 1}]'/2/0", SLIP44_ID) # fmt: on ACCOUNT_PATH_INDEX = const(2) diff --git a/core/src/apps/cardano/helpers/utils.py b/core/src/apps/cardano/helpers/utils.py index 30dec7616..706e2d0bc 100644 --- a/core/src/apps/cardano/helpers/utils.py +++ b/core/src/apps/cardano/helpers/utils.py @@ -22,7 +22,7 @@ def variable_length_encode(number: int) -> bytes: https://en.wikipedia.org/wiki/Variable-length_quantity """ if number < 0: - raise ValueError("Negative numbers not supported. Number supplied: %s" % number) + raise ValueError(f"Negative numbers not supported. Number supplied: {number}") encoded = [number & 0x7F] while number > 0x7F: @@ -40,7 +40,7 @@ def format_account_number(path: list[int]) -> str: if len(path) <= ACCOUNT_PATH_INDEX: raise ValueError("Path is too short.") - return "#%d" % (unharden(path[ACCOUNT_PATH_INDEX]) + 1) + return f"#{unharden(path[ACCOUNT_PATH_INDEX]) + 1}" def format_optional_int(number: int | None) -> str: diff --git a/core/src/apps/cardano/layout.py b/core/src/apps/cardano/layout.py index bb092d529..027217f71 100644 --- a/core/src/apps/cardano/layout.py +++ b/core/src/apps/cardano/layout.py @@ -83,7 +83,7 @@ CERTIFICATE_TYPE_NAMES = { def format_coin_amount(amount: int) -> str: - return "%s %s" % (format_amount(amount, 6), "ADA") + return f"{format_amount(amount, 6)} ADA" def is_printable_ascii_bytestring(bytestr: bytes) -> bool: @@ -104,14 +104,14 @@ async def show_native_script( elif script.key_hash: script_type_name_suffix = "hash" + if indices_str: + script_heading = "Script " + indices_str + else: + script_heading = "Script" + props: list[PropertyType] = [ ( - "Script%s - %s %s:" - % ( - (" " + indices_str if indices_str else ""), - SCRIPT_TYPE_NAMES[script.type], - script_type_name_suffix, - ), + f"{script_heading} - {SCRIPT_TYPE_NAMES[script.type]} {script_type_name_suffix}:", None, ) ] @@ -126,8 +126,7 @@ async def show_native_script( assert script.required_signatures_count is not None # validate_script props.append( ( - "Requires %s out of %s signatures." - % (script.required_signatures_count, len(script.scripts)), + f"Requires {script.required_signatures_count} out of {len(script.scripts)} signatures.", None, ) ) @@ -144,7 +143,7 @@ async def show_native_script( CardanoNativeScriptType.N_OF_K, ): assert script.scripts # validate_script - props.append(("Contains %i nested scripts." % len(script.scripts), None)) + props.append((f"Contains {len(script.scripts)} nested scripts.", None)) await confirm_properties( ctx, @@ -263,7 +262,7 @@ async def _show_credential( if is_change_output: title = "Confirm transaction" else: - title = "%s address" % ADDRESS_TYPE_NAMES[credential.address_type] + title = f"{ADDRESS_TYPE_NAMES[credential.address_type]} address" props: list[PropertyType] = [] @@ -279,8 +278,7 @@ async def _show_credential( credential_title = credential.get_title() props.append( ( - "%s %s credential is a %s:" - % (address_usage, credential.type_name, credential_title), + f"{address_usage} {credential.type_name} credential is a {credential_title}:", None, ) ) @@ -295,8 +293,7 @@ async def _show_credential( if credential.is_no_staking: props.append( ( - "%s address - no staking rewards." - % ADDRESS_TYPE_NAMES[credential.address_type], + f"{ADDRESS_TYPE_NAMES[credential.address_type]} address - no staking rewards.", None, ) ) @@ -350,7 +347,7 @@ async def confirm_witness_request( "confirm_total", title="Confirm transaction", data=address_n_to_str(witness_path), - description="Sign transaction with %s:" % path_title, + description=f"Sign transaction with {path_title}:", br_code=ButtonRequestType.Other, ) @@ -368,14 +365,10 @@ async def confirm_transaction( ] if is_network_id_verifiable: - props.append( - ("Network: %s" % protocol_magics.to_ui_string(protocol_magic), None) - ) + props.append((f"Network: {protocol_magics.to_ui_string(protocol_magic)}", None)) - props.append( - ("Valid since: %s" % format_optional_int(validity_interval_start), None) - ) - props.append(("TTL: %s" % format_optional_int(ttl), None)) + props.append((f"Valid since: {format_optional_int(validity_interval_start)}", None)) + props.append((f"TTL: {format_optional_int(ttl)}", None)) await confirm_properties( ctx, @@ -401,7 +394,7 @@ async def confirm_certificate( if certificate.path: props.append( ( - "for account %s:" % format_account_number(certificate.path), + f"for account {format_account_number(certificate.path)}:", address_n_to_str(to_account_path(certificate.path)), ), ) @@ -428,7 +421,7 @@ async def confirm_stake_pool_parameters( margin_percentage = ( 100.0 * pool_parameters.margin_numerator / pool_parameters.margin_denominator ) - percentage_formatted = ("%f" % margin_percentage).rstrip("0").rstrip(".") + percentage_formatted = str(float(margin_percentage)).rstrip("0").rstrip(".") await confirm_properties( ctx, "confirm_pool_registration", @@ -559,7 +552,7 @@ async def confirm_withdrawal( if withdrawal.path: props.append( ( - "for account %s:" % format_account_number(withdrawal.path), + f"for account {format_account_number(withdrawal.path)}:", address_n_to_str(to_account_path(withdrawal.path)), ) ) @@ -593,7 +586,7 @@ async def confirm_catalyst_registration( ("Catalyst voting key registration", None), ("Voting public key:", public_key), ( - "Staking key for account %s:" % format_account_number(staking_path), + f"Staking key for account {format_account_number(staking_path)}:", address_n_to_str(staking_path), ), ("Rewards go to:", reward_address), @@ -630,8 +623,6 @@ async def confirm_token_minting( ctx: wire.Context, policy_id: bytes, token: CardanoToken ) -> None: assert token.mint_amount is not None # _validate_token - is_minting = token.mint_amount >= 0 - await confirm_properties( ctx, "confirm_mint", @@ -645,7 +636,7 @@ async def confirm_token_minting( ), ), ( - "Amount %s:" % ("minted" if is_minting else "burned"), + "Amount minted:" if token.mint_amount >= 0 else "Amount burned:", format_amount(token.mint_amount, 0), ), ], @@ -674,7 +665,7 @@ async def show_cardano_address( if not protocol_magics.is_mainnet(protocol_magic): network_name = protocol_magics.to_ui_string(protocol_magic) - title = "%s address" % ADDRESS_TYPE_NAMES[address_parameters.address_type] + title = f"{ADDRESS_TYPE_NAMES[address_parameters.address_type]} address" address_extra = None title_qr = title if address_parameters.address_type in ( diff --git a/core/src/apps/cardano/sign_tx.py b/core/src/apps/cardano/sign_tx.py index b99cbffdd..2ce7f568d 100644 --- a/core/src/apps/cardano/sign_tx.py +++ b/core/src/apps/cardano/sign_tx.py @@ -1033,7 +1033,7 @@ async def _fail_or_warn_path( ctx: wire.Context, path: list[int], path_name: str ) -> None: if safety_checks.is_strict(): - raise wire.DataError("Invalid %s" % path_name.lower()) + raise wire.DataError(f"Invalid {path_name.lower()}") else: await show_warning_path(ctx, path, path_name) @@ -1045,7 +1045,7 @@ def _fail_if_strict_and_unusual( return if Credential.payment_credential(address_parameters).is_unusual_path: - raise wire.DataError("Invalid %s" % CHANGE_OUTPUT_PATH_NAME.lower()) + raise wire.DataError(f"Invalid {CHANGE_OUTPUT_PATH_NAME.lower()}") if Credential.stake_credential(address_parameters).is_unusual_path: - raise wire.DataError("Invalid %s" % CHANGE_OUTPUT_STAKING_PATH_NAME.lower()) + raise wire.DataError(f"Invalid {CHANGE_OUTPUT_STAKING_PATH_NAME.lower()}") diff --git a/core/src/apps/common/cbor.py b/core/src/apps/common/cbor.py index 75495d98a..2d275abf7 100644 --- a/core/src/apps/common/cbor.py +++ b/core/src/apps/common/cbor.py @@ -58,7 +58,7 @@ def _header(typ: int, l: int) -> bytes: elif l < 2 ** 64: return struct.pack(">BQ", typ + 27, l) else: - raise NotImplementedError("Length %d not supported" % l) + raise NotImplementedError # Length not supported def _cbor_encode(value: Value) -> Iterator[bytes]: @@ -128,7 +128,7 @@ def _read_length(r: utils.BufferReader, aux: int) -> int: elif aux == _CBOR_UINT64_FOLLOWS: return readers.read_uint64_be(r) else: - raise NotImplementedError("Length %d not supported" % aux) + raise NotImplementedError # Length not supported def _cbor_decode(r: utils.BufferReader) -> Value: diff --git a/core/src/apps/common/coininfo.py b/core/src/apps/common/coininfo.py index ae44575cb..1e9f2d923 100644 --- a/core/src/apps/common/coininfo.py +++ b/core/src/apps/common/coininfo.py @@ -1830,4 +1830,4 @@ def by_name(name: str) -> CoinInfo: overwintered=True, confidential_assets=None, ) - raise ValueError('Unknown coin name "%s"' % name) + raise ValueError # Unknown coin name diff --git a/core/src/apps/common/coininfo.py.mako b/core/src/apps/common/coininfo.py.mako index bd88e2df1..795d0fabc 100644 --- a/core/src/apps/common/coininfo.py.mako +++ b/core/src/apps/common/coininfo.py.mako @@ -159,4 +159,4 @@ def by_name(name: str) -> CoinInfo: % endfor ) % endfor - raise ValueError('Unknown coin name "%s"' % name) + raise ValueError # Unknown coin name diff --git a/core/src/apps/common/passphrase.py b/core/src/apps/common/passphrase.py index 1accd899c..a00199b7c 100644 --- a/core/src/apps/common/passphrase.py +++ b/core/src/apps/common/passphrase.py @@ -27,7 +27,7 @@ async def _request_from_user(ctx: wire.Context) -> str: passphrase = await _request_on_host(ctx) if len(passphrase.encode()) > _MAX_PASSPHRASE_LEN: raise wire.DataError( - "Maximum passphrase length is %d bytes" % _MAX_PASSPHRASE_LEN + f"Maximum passphrase length is {_MAX_PASSPHRASE_LEN} bytes" ) return passphrase diff --git a/core/src/apps/common/signverify.py b/core/src/apps/common/signverify.py index 2b39db78f..0bfadd3f8 100644 --- a/core/src/apps/common/signverify.py +++ b/core/src/apps/common/signverify.py @@ -30,4 +30,4 @@ def decode_message(message: bytes) -> str: try: return bytes(message).decode() except UnicodeError: - return "hex(%s)" % hexlify(message).decode() + return f"hex({hexlify(message).decode()})" diff --git a/core/src/apps/debug/__init__.py b/core/src/apps/debug/__init__.py index 8d3609684..95ff6b1db 100644 --- a/core/src/apps/debug/__init__.py +++ b/core/src/apps/debug/__init__.py @@ -110,9 +110,7 @@ if __debug__: layout_change_chan.putters.clear() await ui.wait_until_layout_is_running() storage.watch_layout_changes = bool(msg.watch) - log.debug( - __name__, "Watch layout changes: {}".format(storage.watch_layout_changes) - ) + log.debug(__name__, "Watch layout changes: %s", storage.watch_layout_changes) return Success() async def dispatch_DebugLinkDecision( diff --git a/core/src/apps/eos/actions/layout.py b/core/src/apps/eos/actions/layout.py index 4cbfeb248..6ea62cc58 100644 --- a/core/src/apps/eos/actions/layout.py +++ b/core/src/apps/eos/actions/layout.py @@ -149,8 +149,8 @@ async def confirm_action_voteproducer( "confirm_voteproducer", title="Vote for producers", props=( - ("{:2d}. {}".format(wi + 1, helpers.eos_name_to_string(producer)), None) - for wi, producer in enumerate(msg.producers) + (f"{wi:2d}. {helpers.eos_name_to_string(producer)}", None) + for wi, producer in enumerate(msg.producers, 1) ), icon=ui.ICON_CONFIRM, br_code=ButtonRequestType.ConfirmOutput, @@ -300,35 +300,35 @@ def authorization_fields(auth: EosAuthorization) -> list[tuple[str, str | None]] fields = [] fields.append(("Threshold:", str(auth.threshold))) - for i, key in enumerate(auth.keys): + for i, key in enumerate(auth.keys, 1): _key = helpers.public_key_to_wif(bytes(key.key)) _weight = str(key.weight) - header = "Key #{}:".format(i + 1) - w_header = "Key #{} Weight:".format(i + 1) + header = f"Key #{i}:" + w_header = f"Key #{i} Weight:" fields.append((header, _key)) fields.append((w_header, _weight)) - for i, account in enumerate(auth.accounts): + for i, account in enumerate(auth.accounts, 1): _account = helpers.eos_name_to_string(account.account.actor) _permission = helpers.eos_name_to_string(account.account.permission) - a_header = "Account #{}:".format(i + 1) - p_header = "Acc Permission #{}:".format(i + 1) - w_header = "Account #{} weight:".format(i + 1) + a_header = f"Account #{i}:" + p_header = f"Acc Permission #{i}:" + w_header = f"Account #{i} weight:" fields.append((a_header, _account)) fields.append((p_header, _permission)) fields.append((w_header, str(account.weight))) - for i, wait in enumerate(auth.waits): + for i, wait in enumerate(auth.waits, 1): _wait = str(wait.wait_sec) _weight = str(wait.weight) - header = "Delay #{}".format(i + 1) - w_header = "Delay #{} weight:".format(i + 1) - fields.append((header, "{} sec".format(_wait))) + header = f"Delay #{i}" + w_header = f"Delay #{i} weight:" + fields.append((header, f"{_wait} sec")) fields.append((w_header, _weight)) return fields diff --git a/core/src/apps/eos/helpers.py b/core/src/apps/eos/helpers.py index 6afe9f075..84708b198 100644 --- a/core/src/apps/eos/helpers.py +++ b/core/src/apps/eos/helpers.py @@ -35,9 +35,9 @@ def eos_asset_to_string(asset: EosAsset) -> str: integer = "0" fraction = amount_digits[-precision:] - return "{}.{} {}".format(integer, fraction, symbol) + return f"{integer}.{fraction} {symbol}" else: - return "{} {}".format(amount_digits, symbol) + return f"{amount_digits} {symbol}" def public_key_to_wif(pub_key: bytes) -> str: diff --git a/core/src/apps/ethereum/layout.py b/core/src/apps/ethereum/layout.py index 98b62eabd..37fa2e4d2 100644 --- a/core/src/apps/ethereum/layout.py +++ b/core/src/apps/ethereum/layout.py @@ -100,7 +100,7 @@ def require_confirm_data(ctx: Context, data: bytes, data_total: int) -> Awaitabl ctx, "confirm_data", title="Confirm data", - description="Size: %d bytes" % data_total, + description=f"Size: {data_total} bytes", data=data, br_code=ButtonRequestType.SignTx, ) @@ -121,4 +121,4 @@ def format_ethereum_amount( suffix = "Wei " + suffix decimals = 0 - return "%s %s" % (format_amount(value, decimals), suffix) + return f"{format_amount(value, decimals)} {suffix}" diff --git a/core/src/apps/management/apply_settings.py b/core/src/apps/management/apply_settings.py index 022d5489b..d16d0021d 100644 --- a/core/src/apps/management/apply_settings.py +++ b/core/src/apps/management/apply_settings.py @@ -18,9 +18,7 @@ def validate_homescreen(homescreen: bytes) -> None: if len(homescreen) > storage.device.HOMESCREEN_MAXSIZE: raise wire.DataError( - "Homescreen is too large, maximum size is {} bytes".format( - storage.device.HOMESCREEN_MAXSIZE - ) + f"Homescreen is too large, maximum size is {storage.device.HOMESCREEN_MAXSIZE} bytes" ) try: diff --git a/core/src/apps/management/recovery_device/__init__.py b/core/src/apps/management/recovery_device/__init__.py index e522a02c6..ce63b3701 100644 --- a/core/src/apps/management/recovery_device/__init__.py +++ b/core/src/apps/management/recovery_device/__init__.py @@ -82,9 +82,7 @@ def _validate(msg: RecoveryDevice) -> None: # check that only allowed fields are set for key, value in msg.__dict__.items(): if key not in DRY_RUN_ALLOWED_FIELDS and value is not None: - raise wire.ProcessError( - "Forbidden field set in dry-run: {}".format(key) - ) + raise wire.ProcessError(f"Forbidden field set in dry-run: {key}") async def _continue_dialog(ctx: wire.Context, msg: RecoveryDevice) -> None: diff --git a/core/src/apps/management/recovery_device/homescreen.py b/core/src/apps/management/recovery_device/homescreen.py index 1e22ce699..24f35bf5e 100644 --- a/core/src/apps/management/recovery_device/homescreen.py +++ b/core/src/apps/management/recovery_device/homescreen.py @@ -187,11 +187,11 @@ async def _request_share_first_screen( await _request_share_next_screen(ctx) else: await layout.homescreen_dialog( - ctx, "Enter share", "Enter any share", "(%d words)" % word_count + ctx, "Enter share", "Enter any share", f"({word_count} words)" ) else: # BIP-39 await layout.homescreen_dialog( - ctx, "Enter seed", "Enter recovery seed", "(%d words)" % word_count + ctx, "Enter seed", "Enter recovery seed", f"({word_count} words)" ) diff --git a/core/src/apps/management/reset_device/layout.py b/core/src/apps/management/reset_device/layout.py index a50691eea..68aa8ac3c 100644 --- a/core/src/apps/management/reset_device/layout.py +++ b/core/src/apps/management/reset_device/layout.py @@ -61,21 +61,15 @@ async def _show_confirmation_success( if group_index is None: subheader = "You have finished\nverifying your\nrecovery shares." else: - subheader = ( - "You have finished\nverifying your\nrecovery shares\nfor group %s." - % (group_index + 1) - ) + subheader = f"You have finished\nverifying your\nrecovery shares\nfor group {group_index + 1}." text = "" else: if group_index is None: - subheader = "Recovery share #%s\nchecked successfully." % (share_index + 1) - text = "Continue with share #%s." % (share_index + 2) + subheader = f"Recovery share #{share_index + 1}\nchecked successfully." + text = f"Continue with share #{share_index + 2}." else: - subheader = "Group %s - Share %s\nchecked successfully." % ( - (group_index + 1), - (share_index + 1), - ) + subheader = f"Group {group_index + 1} - Share {share_index + 1}\nchecked successfully." text = "Continue with the next\nshare." return await show_success(ctx, "success_recovery", text, subheader=subheader) @@ -87,7 +81,7 @@ async def _show_confirmation_failure( if share_index is None: header = "Recovery seed" else: - header = "Recovery share #%s" % (share_index + 1) + header = f"Recovery share #{share_index + 1}" await show_warning( ctx, "warning_backup_check", diff --git a/core/src/apps/misc/get_ecdh_session_key.py b/core/src/apps/misc/get_ecdh_session_key.py index 7bcef6ea9..f4e16bbb1 100644 --- a/core/src/apps/misc/get_ecdh_session_key.py +++ b/core/src/apps/misc/get_ecdh_session_key.py @@ -47,7 +47,7 @@ async def require_confirm_ecdh_session_key( proto = identity.proto.upper() if identity.proto else "identity" await confirm_address( ctx, - "Decrypt %s" % proto, + f"Decrypt {proto}", serialize_identity_without_proto(identity), description=None, icon=ui.ICON_DEFAULT, diff --git a/core/src/apps/monero/diag.py b/core/src/apps/monero/diag.py index 18ccb2f00..5bc05fd1c 100644 --- a/core/src/apps/monero/diag.py +++ b/core/src/apps/monero/diag.py @@ -26,9 +26,7 @@ if __debug__: diff = PREV_MEM - free log.debug( __name__, - "======= {} {} Diff: {} Free: {} Allocated: {}".format( - CUR_MES, x, diff, free, gc.mem_alloc() - ), + f"======= {CUR_MES} {x} Diff: {diff} Free: {free} Allocated: {gc.mem_alloc()}", ) micropython.mem_info() gc.collect() diff --git a/core/src/apps/monero/layout.py b/core/src/apps/monero/layout.py index bf245e91c..29e31cbc6 100644 --- a/core/src/apps/monero/layout.py +++ b/core/src/apps/monero/layout.py @@ -20,7 +20,7 @@ if False: def _format_amount(value): - return "%s XMR" % strings.format_amount(value, 12) + return f"{strings.format_amount(value, 12)} XMR" async def require_confirm_watchkey(ctx): @@ -209,7 +209,7 @@ class LiveRefreshStep(ui.Component): p = (1000 * current // 8) % 1000 ui.display.loader(p, True, 18, ui.WHITE, ui.BG) ui.display.text_center( - ui.WIDTH // 2, 145, "%d" % current, ui.NORMAL, ui.FG, ui.BG + ui.WIDTH // 2, 145, str(current), ui.NORMAL, ui.FG, ui.BG ) @@ -217,19 +217,19 @@ async def transaction_step(state: State, step: int, sub_step: int | None = None) if step == 0: info = ["Signing..."] elif step == state.STEP_INP: - info = ["Processing inputs", "%d/%d" % (sub_step + 1, state.input_count)] + info = ["Processing inputs", f"{sub_step + 1}/{state.input_count}"] elif step == state.STEP_PERM: info = ["Sorting..."] elif step == state.STEP_VINI: - info = ["Hashing inputs", "%d/%d" % (sub_step + 1, state.input_count)] + info = ["Hashing inputs", f"{sub_step + 1}/{state.input_count}"] elif step == state.STEP_ALL_IN: info = ["Processing..."] elif step == state.STEP_OUT: - info = ["Processing outputs", "%d/%d" % (sub_step + 1, state.output_count)] + info = ["Processing outputs", f"{sub_step + 1}/{state.output_count}"] elif step == state.STEP_ALL_OUT: info = ["Postprocessing..."] elif step == state.STEP_SIGN: - info = ["Signing inputs", "%d/%d" % (sub_step + 1, state.input_count)] + info = ["Signing inputs", f"{sub_step + 1}/{state.input_count}"] else: info = ["Processing..."] diff --git a/core/src/apps/monero/signing/step_02_set_input.py b/core/src/apps/monero/signing/step_02_set_input.py index 4b13fa718..911f6c11a 100644 --- a/core/src/apps/monero/signing/step_02_set_input.py +++ b/core/src/apps/monero/signing/step_02_set_input.py @@ -41,8 +41,7 @@ async def set_input( # real_output denotes which output in outputs is the real one (ours) if src_entr.real_output >= len(src_entr.outputs): raise ValueError( - "real_output index %s bigger than output_keys.size() %s" - % (src_entr.real_output, len(src_entr.outputs)) + f"real_output index {src_entr.real_output} bigger than output_keys.size() {len(src_entr.outputs)}" ) state.summary_inputs_money += src_entr.amount diff --git a/core/src/apps/monero/signing/step_06_set_output.py b/core/src/apps/monero/signing/step_06_set_output.py index 0d9f8e7d3..f7bd60f22 100644 --- a/core/src/apps/monero/signing/step_06_set_output.py +++ b/core/src/apps/monero/signing/step_06_set_output.py @@ -312,7 +312,7 @@ def _rsig_bp(state: State) -> bytes: rsig = _dump_rsig_bp(rsig) state.mem_trace( - "post-bp-ser, size: %s" % len(rsig) if __debug__ else None, collect=True + f"post-bp-ser, size: {len(rsig)}" if __debug__ else None, collect=True ) # state cleanup diff --git a/core/src/apps/monero/signing/step_07_all_outputs_set.py b/core/src/apps/monero/signing/step_07_all_outputs_set.py index 48871cdcb..adaaf5046 100644 --- a/core/src/apps/monero/signing/step_07_all_outputs_set.py +++ b/core/src/apps/monero/signing/step_07_all_outputs_set.py @@ -87,18 +87,12 @@ def _validate(state: State): # Fee test if state.fee != (state.summary_inputs_money - state.summary_outs_money): raise ValueError( - "Fee invalid %s vs %s, out: %s" - % ( - state.fee, - state.summary_inputs_money - state.summary_outs_money, - state.summary_outs_money, - ) + f"Fee invalid {state.fee} vs {state.summary_inputs_money - state.summary_outs_money}, out: {state.summary_outs_money}" ) if state.summary_outs_money > state.summary_inputs_money: raise ValueError( - "Transaction inputs money (%s) less than outputs money (%s)" - % (state.summary_inputs_money, state.summary_outs_money) + f"Transaction inputs money ({state.summary_inputs_money}) less than outputs money ({state.summary_outs_money})" ) diff --git a/core/src/apps/monero/xmr/bulletproof.py b/core/src/apps/monero/xmr/bulletproof.py index a4ed2795c..fa62caa14 100644 --- a/core/src/apps/monero/xmr/bulletproof.py +++ b/core/src/apps/monero/xmr/bulletproof.py @@ -654,7 +654,7 @@ class KeyVPowers(KeyVBase): else crypto.sc_mul_into(self.cur, self.cur, self.x) ) else: - raise IndexError("Only linear scan allowed: %s, %s" % (prev, item)) + raise IndexError(f"Only linear scan allowed: {prev}, {item}") def set_state(self, idx, val): self.last_idx = idx diff --git a/core/src/apps/monero/xmr/networks.py b/core/src/apps/monero/xmr/networks.py index e9f5faefa..e9ad42c87 100644 --- a/core/src/apps/monero/xmr/networks.py +++ b/core/src/apps/monero/xmr/networks.py @@ -40,7 +40,7 @@ def net_version( elif network_type == NetworkTypes.STAGENET: c_net = StageNet else: - raise ValueError("Unknown network type: %s" % network_type) + raise ValueError(f"Unknown network type: {network_type}") prefix = c_net.PUBLIC_ADDRESS_BASE58_PREFIX if is_subaddr: diff --git a/core/src/apps/monero/xmr/serialize/message_types.py b/core/src/apps/monero/xmr/serialize/message_types.py index f5cbbd5bf..ad18d6df5 100644 --- a/core/src/apps/monero/xmr/serialize/message_types.py +++ b/core/src/apps/monero/xmr/serialize/message_types.py @@ -106,7 +106,7 @@ class VariantType(XmrType): if isinstance(elem, ftype): break else: - raise ValueError("Unrecognized variant: %s" % elem) + raise ValueError(f"Unrecognized variant: {elem}") dump_uint(writer, ftype.VARIANT_CODE, 1) ftype.dump(writer, elem) @@ -120,7 +120,7 @@ class VariantType(XmrType): fvalue = ftype.load(reader) break else: - raise ValueError("Unknown tag: %s" % tag) + raise ValueError(f"Unknown tag: {tag}") return fvalue @classmethod diff --git a/core/src/apps/nem/layout.py b/core/src/apps/nem/layout.py index 7d4ae5eff..b680bd89c 100644 --- a/core/src/apps/nem/layout.py +++ b/core/src/apps/nem/layout.py @@ -22,7 +22,7 @@ async def require_confirm_fee(ctx, action: str, fee: int): "confirm_fee", title="Confirm fee", content=action + "\n{}", - param="{} XEM".format(format_amount(fee, NEM_MAX_DIVISIBILITY)), + param=f"{format_amount(fee, NEM_MAX_DIVISIBILITY)} XEM", hide_continue=True, br_code=ButtonRequestType.ConfirmOutput, ) @@ -44,7 +44,7 @@ async def require_confirm_final(ctx, fee: int): "confirm_final", title="Final confirm", content="Sign this transaction\n{}\nfor network fee?", - param="and pay {} XEM".format(format_amount(fee, NEM_MAX_DIVISIBILITY)), + param=f"and pay {format_amount(fee, NEM_MAX_DIVISIBILITY)} XEM", hide_continue=True, hold=True, ) diff --git a/core/src/apps/nem/transfer/layout.py b/core/src/apps/nem/transfer/layout.py index ba276bdfc..d4c4d034e 100644 --- a/core/src/apps/nem/transfer/layout.py +++ b/core/src/apps/nem/transfer/layout.py @@ -90,8 +90,8 @@ async def ask_transfer_mosaic( "confirm_mosaic_transfer", title="Confirm mosaic", props=[ - ("Confirm transfer of", "%s raw units" % mosaic_quantity), - ("of", "%s.%s" % (mosaic.namespace, mosaic.mosaic)), + ("Confirm transfer of", f"{mosaic_quantity} raw units"), + ("of", f"{mosaic.namespace}.{mosaic.mosaic}"), ], ) @@ -139,7 +139,7 @@ async def _require_confirm_transfer(ctx, recipient, value): await confirm_output( ctx, recipient, - amount="Send {} XEM".format(format_amount(value, NEM_MAX_DIVISIBILITY)), + amount=f"Send {format_amount(value, NEM_MAX_DIVISIBILITY)} XEM", font_amount=ui.BOLD, title="Confirm transfer", to_str="\nto\n", diff --git a/core/src/apps/nem/validators.py b/core/src/apps/nem/validators.py index 419b95de1..e2d218504 100644 --- a/core/src/apps/nem/validators.py +++ b/core/src/apps/nem/validators.py @@ -96,9 +96,9 @@ def _validate_common(common: NEMTransactionCommon, inner: bool = False): if err: if inner: - raise ProcessError("No %s provided in inner transaction" % err) + raise ProcessError(f"No {err} provided in inner transaction") else: - raise ProcessError("No %s provided" % err) + raise ProcessError(f"No {err} provided") if common.signer is not None: _validate_public_key( @@ -108,9 +108,9 @@ def _validate_common(common: NEMTransactionCommon, inner: bool = False): def _validate_public_key(public_key: bytes, err_msg: str): if not public_key: - raise ProcessError("%s (none provided)" % err_msg) + raise ProcessError(f"{err_msg} (none provided)") if len(public_key) != NEM_PUBLIC_KEY_SIZE: - raise ProcessError("%s (invalid length)" % err_msg) + raise ProcessError(f"{err_msg} (invalid length)") def _validate_importance_transfer(importance_transfer: NEMImportanceTransfer): diff --git a/core/src/apps/stellar/operations/layout.py b/core/src/apps/stellar/operations/layout.py index b048f56ba..2a80c4c01 100644 --- a/core/src/apps/stellar/operations/layout.py +++ b/core/src/apps/stellar/operations/layout.py @@ -114,7 +114,7 @@ async def confirm_manage_offer_op(ctx: Context, op: StellarManageOfferOp) -> Non text = "Delete" else: text = "Update" - text += " #%d" % op.offer_id + text += f" #{op.offer_id}" await _confirm_offer(ctx, text, op) @@ -131,7 +131,7 @@ async def _confirm_offer( ("Selling:", format_amount(op.amount, op.selling_asset)), ("Buying:", format_asset(op.buying_asset)), ( - "Price per {}:".format(format_asset(op.buying_asset)), + f"Price per {format_asset(op.buying_asset)}:", str(op.price_n / op.price_d), ), ), @@ -279,6 +279,6 @@ async def confirm_asset_issuer(ctx: Context, asset: StellarAsset) -> None: ctx, "Confirm Issuer", asset.issuer, - description="{} issuer:".format(asset.code), + description=f"{asset.code} issuer:", br_type="confirm_asset_issuer", ) diff --git a/core/src/apps/webauthn/credential.py b/core/src/apps/webauthn/credential.py index fb3d5f7f7..fb196ca99 100644 --- a/core/src/apps/webauthn/credential.py +++ b/core/src/apps/webauthn/credential.py @@ -412,10 +412,9 @@ class U2fCredential(Credential): if app is not None: return app.label - return "%s...%s" % ( - hexlify(self.rp_id_hash[:4]).decode(), - hexlify(self.rp_id_hash[-4:]).decode(), - ) + start = hexlify(self.rp_id_hash[:4]).decode() + end = hexlify(self.rp_id_hash[-4:]).decode() + return f"{start}...{end}" @staticmethod def from_key_handle(key_handle: bytes, rp_id_hash: bytes) -> "U2fCredential": diff --git a/core/src/apps/webauthn/fido2.py b/core/src/apps/webauthn/fido2.py index 86b53bd31..8526def7f 100644 --- a/core/src/apps/webauthn/fido2.py +++ b/core/src/apps/webauthn/fido2.py @@ -334,7 +334,7 @@ def resp_cmd_authenticate(siglen: int) -> dict: def overlay_struct(buf: bytearray, desc: dict) -> Any: desc_size = uctypes.sizeof(desc, uctypes.BIG_ENDIAN) # type: ignore if desc_size > len(buf): - raise ValueError("desc is too big (%d > %d)" % (desc_size, len(buf))) + raise ValueError(f"desc is too big ({desc_size} > {len(buf)})") return uctypes.struct(uctypes.addressof(buf), desc, uctypes.BIG_ENDIAN) diff --git a/core/src/storage/cache.py b/core/src/storage/cache.py index 3be662743..1ad340985 100644 --- a/core/src/storage/cache.py +++ b/core/src/storage/cache.py @@ -68,7 +68,7 @@ class DataCache: ... def get(self, key: int, default: T | None = None) -> bytes | T | None: # noqa: F811 - utils.ensure(key < len(self.fields), "failed to load key %d" % key) + utils.ensure(key < len(self.fields), f"failed to load key {key}") if self.data[key][0] != 1: return default return bytes(self.data[key][1:]) diff --git a/core/src/storage/sd_salt.py b/core/src/storage/sd_salt.py index bccd8b5bc..e339abe01 100644 --- a/core/src/storage/sd_salt.py +++ b/core/src/storage/sd_salt.py @@ -31,7 +31,7 @@ def compute_auth_tag(salt: bytes, auth_key: bytes) -> bytes: def _get_device_dir() -> str: - return "/trezor/device_{}".format(storage.device.get_device_id().lower()) + return f"/trezor/device_{storage.device.get_device_id().lower()}" def _get_salt_path(new: bool = False) -> str: diff --git a/core/src/trezor/crypto/slip39.py b/core/src/trezor/crypto/slip39.py index af861b5ef..79bffb0df 100644 --- a/core/src/trezor/crypto/slip39.py +++ b/core/src/trezor/crypto/slip39.py @@ -213,9 +213,7 @@ def split_ems( if group_threshold > len(groups): raise ValueError( - "The requested group threshold ({}) must not exceed the number of groups ({}).".format( - group_threshold, len(groups) - ) + f"The requested group threshold ({group_threshold}) must not exceed the number of groups ({len(groups)})." ) if any( @@ -273,17 +271,13 @@ def recover_ems(mnemonics: list[str]) -> tuple[int, int, bytes]: if len(groups) != group_threshold: raise MnemonicError( - "Wrong number of mnemonic groups. Expected {} groups, but {} were provided.".format( - group_threshold, len(groups) - ) + f"Wrong number of mnemonic groups. Expected {group_threshold} groups, but {len(groups)} were provided." ) for group_index, group in groups.items(): if len(group[1]) != group[0]: # group[0] is threshold raise MnemonicError( - "Wrong number of mnemonics. Expected {} mnemonics, but {} were provided.".format( - group[0], len(group[1]) - ) + f"Wrong number of mnemonics. Expected {group[0]} mnemonics, but {len(group[1])} were provided." ) group_shares = [ @@ -302,9 +296,7 @@ def decode_mnemonic(mnemonic: str) -> Share: if len(mnemonic_data) < _MIN_MNEMONIC_LENGTH_WORDS: raise MnemonicError( - "Invalid mnemonic length. The length of each mnemonic must be at least {} words.".format( - _MIN_MNEMONIC_LENGTH_WORDS - ) + f"Invalid mnemonic length. The length of each mnemonic must be at least {_MIN_MNEMONIC_LENGTH_WORDS} words." ) padding_len = (_RADIX_BITS * (len(mnemonic_data) - _METADATA_LENGTH_WORDS)) % 16 @@ -487,21 +479,17 @@ def _split_secret( ) -> list[tuple[int, bytes]]: if threshold < 1: raise ValueError( - "The requested threshold ({}) must be a positive integer.".format(threshold) + f"The requested threshold ({threshold}) must be a positive integer." ) if threshold > share_count: raise ValueError( - "The requested threshold ({}) must not exceed the number of shares ({}).".format( - threshold, share_count - ) + f"The requested threshold ({threshold}) must not exceed the number of shares ({share_count})." ) if share_count > MAX_SHARE_COUNT: raise ValueError( - "The requested number of shares ({}) must not exceed {}.".format( - share_count, MAX_SHARE_COUNT - ) + f"The requested number of shares ({share_count}) must not exceed {MAX_SHARE_COUNT}." ) # If the threshold is 1, then the digest of the shared secret is not used. @@ -615,9 +603,7 @@ def _decode_mnemonics( if len(identifiers) != 1 or len(iteration_exponents) != 1: raise MnemonicError( - "Invalid set of mnemonics. All mnemonics must begin with the same {} words.".format( - _ID_EXP_LENGTH_WORDS - ) + f"Invalid set of mnemonics. All mnemonics must begin with the same {_ID_EXP_LENGTH_WORDS} words." ) if len(group_thresholds) != 1: diff --git a/core/src/trezor/loop.py b/core/src/trezor/loop.py index fe6a766de..55fd08928 100644 --- a/core/src/trezor/loop.py +++ b/core/src/trezor/loop.py @@ -231,7 +231,7 @@ class sleep(Syscall): Example: >>> planned = await loop.sleep(1000) # sleep for 1s - >>> print('missed by %d ms', utime.ticks_diff(utime.ticks_ms(), planned)) + >>> print(f"missed by {utime.ticks_diff(utime.ticks_ms(), planned)} ms") """ def __init__(self, delay_ms: int) -> None: diff --git a/core/src/trezor/pin.py b/core/src/trezor/pin.py index 7fbb9c125..c904fa3ed 100644 --- a/core/src/trezor/pin.py +++ b/core/src/trezor/pin.py @@ -34,7 +34,7 @@ def show_pin_timeout(seconds: int, progress: int, message: str) -> bool: elif seconds == 1: remaining = "1 second left" else: - remaining = "%d seconds left" % seconds + remaining = f"{seconds} seconds left" ui.display.bar(0, ui.HEIGHT - 42, ui.WIDTH, 25, ui.BG) ui.display.text_center( ui.WIDTH // 2, ui.HEIGHT - 22, remaining, ui.BOLD, ui.FG, ui.BG diff --git a/core/src/trezor/strings.py b/core/src/trezor/strings.py index 48de22705..9b57df8b7 100644 --- a/core/src/trezor/strings.py +++ b/core/src/trezor/strings.py @@ -5,11 +5,7 @@ def format_amount(amount: int, decimals: int) -> str: else: sign = "" d = pow(10, decimals) - s = ( - ("%s%d.%0*d" % (sign, amount // d, decimals, amount % d)) - .rstrip("0") - .rstrip(".") - ) + s = f"{sign}{amount // d}.{amount % d:0{decimals}}".rstrip("0").rstrip(".") return s diff --git a/core/src/trezor/ui/components/tt/button.py b/core/src/trezor/ui/components/tt/button.py index ed0656a5b..a8aab4c40 100644 --- a/core/src/trezor/ui/components/tt/button.py +++ b/core/src/trezor/ui/components/tt/button.py @@ -251,4 +251,4 @@ class Button(ui.Component): if __debug__: def read_content(self) -> list[str]: - return ["".format(self.text)] + return [f""] diff --git a/core/src/trezor/ui/components/tt/reset.py b/core/src/trezor/ui/components/tt/reset.py index bf61f7b66..ad9e8d418 100644 --- a/core/src/trezor/ui/components/tt/reset.py +++ b/core/src/trezor/ui/components/tt/reset.py @@ -59,11 +59,11 @@ class Slip39NumInput(ui.Component): first_line_text = "Only one share will" second_line_text = "be created." else: - first_line_text = "%s people or locations" % count + first_line_text = f"{count} people or locations" second_line_text = "will each hold one share." else: first_line_text = "Set the total number of" - second_line_text = "shares in Group %s." % (self.group_id + 1) + second_line_text = f"shares in Group {self.group_id + 1}." ui.display.bar(0, 110, ui.WIDTH, 52, ui.BG) ui.display.text(12, 130, first_line_text, ui.NORMAL, ui.FG, ui.BG) ui.display.text(12, 156, second_line_text, ui.NORMAL, ui.FG, ui.BG) @@ -73,12 +73,12 @@ class Slip39NumInput(ui.Component): if count == 1: second_line_text = "1 share." elif count == self.input.max_count: - second_line_text = "all %s of the shares." % count + second_line_text = f"all {count} of the shares." else: - second_line_text = "any %s of the shares." % count + second_line_text = f"any {count} of the shares." else: first_line_text = "The required number of " - second_line_text = "shares to form Group %s." % (self.group_id + 1) + second_line_text = f"shares to form Group {self.group_id + 1}." ui.display.bar(0, 110, ui.WIDTH, 52, ui.BG) ui.display.text(12, 130, first_line_text, ui.NORMAL, ui.FG, ui.BG) ui.display.text(12, 156, second_line_text, ui.NORMAL, ui.FG, ui.BG) @@ -127,12 +127,10 @@ class MnemonicWordSelect(ui.Layout): if share_index is None: self.text: ui.Component = Text("Check seed") elif group_index is None: - self.text = Text("Check share #%s" % (share_index + 1)) + self.text = Text(f"Check share #{share_index + 1}") else: - self.text = Text( - "Check G%s - Share %s" % ((group_index + 1), (share_index + 1)) - ) - self.text.normal("Select word %d of %d:" % (word_index + 1, count)) + self.text = Text(f"Check G{group_index + 1} - Share {share_index + 1}") + self.text.normal(f"Select word {word_index + 1} of {count}:") def dispatch(self, event: int, x: int, y: int) -> None: for btn in self.buttons: diff --git a/core/src/trezor/ui/layouts/common.py b/core/src/trezor/ui/layouts/common.py index edbd8095e..afa58120b 100644 --- a/core/src/trezor/ui/layouts/common.py +++ b/core/src/trezor/ui/layouts/common.py @@ -19,7 +19,8 @@ async def button_request( br_type: str, code: ButtonRequestType = ButtonRequestType.Other, ) -> None: - log.debug(__name__, "ButtonRequest.type={}".format(br_type)) + if __debug__: + log.debug(__name__, "ButtonRequest.type=%s", br_type) workflow.close_others() await ctx.call(ButtonRequest(code=code), ButtonAck) diff --git a/core/src/trezor/ui/layouts/tt/__init__.py b/core/src/trezor/ui/layouts/tt/__init__.py index 4b0202586..55ca58f9e 100644 --- a/core/src/trezor/ui/layouts/tt/__init__.py +++ b/core/src/trezor/ui/layouts/tt/__init__.py @@ -248,7 +248,7 @@ def _show_address( network: str | None = None, extra: str | None = None, ) -> ui.Layout: - para = [(ui.NORMAL, "%s network" % network)] if network is not None else [] + para = [(ui.NORMAL, f"{network} network")] if network is not None else [] if extra is not None: para.append((ui.BOLD, extra)) para.extend( @@ -340,7 +340,7 @@ async def show_address( if is_multisig: for i, xpub in enumerate(xpubs): cancel = "Next" if i < len(xpubs) - 1 else "Address" - title_xpub = "XPUB #%d" % (i + 1) + title_xpub = f"XPUB #{i + 1}" title_xpub += " (yours)" if i == multisig_index else " (cosigner)" if is_confirmed( await interact( @@ -864,7 +864,7 @@ async def confirm_coinjoin( text = Text("Authorize CoinJoin", ui.ICON_RECOVERY, new_lines=False) if fee_per_anonymity is not None: text.normal("Fee per anonymity set:\n") - text.bold("{} %\n".format(fee_per_anonymity)) + text.bold(f"{fee_per_anonymity} %\n") text.normal("Maximum total fees:\n") text.bold(total_fee) await raise_if_cancelled( @@ -876,7 +876,7 @@ async def confirm_coinjoin( async def confirm_sign_identity( ctx: wire.GenericContext, proto: str, identity: str, challenge_visual: str | None ) -> None: - text = Text("Sign %s" % proto, new_lines=False) + text = Text(f"Sign {proto}", new_lines=False) if challenge_visual: text.normal(challenge_visual) text.br() @@ -890,7 +890,7 @@ async def confirm_signverify( ctx: wire.GenericContext, coin: str, message: str, address: str | None = None ) -> None: if address: - header = "Verify {} message".format(coin) + header = f"Verify {coin} message" font = ui.MONO br_type = "verify_message" @@ -901,7 +901,7 @@ async def confirm_signverify( interact(ctx, Confirm(text), br_type, ButtonRequestType.Other) ) else: - header = "Sign {} message".format(coin) + header = f"Sign {coin} message" font = ui.NORMAL br_type = "sign_message" @@ -963,7 +963,7 @@ async def request_pin_on_device( elif attempts_remaining == 1: subprompt = "This is your last attempt" else: - subprompt = "%s attempts remaining" % attempts_remaining + subprompt = f"{attempts_remaining} attempts remaining" dialog = pin.PinDialog(prompt, subprompt, allow_cancel) while True: diff --git a/core/src/trezor/ui/layouts/tt/altcoin.py b/core/src/trezor/ui/layouts/tt/altcoin.py index 0aee048f9..ebbf4d849 100644 --- a/core/src/trezor/ui/layouts/tt/altcoin.py +++ b/core/src/trezor/ui/layouts/tt/altcoin.py @@ -34,7 +34,7 @@ async def confirm_total_ripple( ) -> None: title = "Confirm sending" text = Text(title, ui.ICON_SEND, ui.GREEN, new_lines=False) - text.bold("{} XRP\n".format(amount)) + text.bold(f"{amount} XRP\n") text.normal("to\n") text.mono(*chunks_intersperse(address, MONO_ADDR_PER_LINE)) diff --git a/core/src/trezor/ui/layouts/tt/recovery.py b/core/src/trezor/ui/layouts/tt/recovery.py index b4789e9e2..73affd792 100644 --- a/core/src/trezor/ui/layouts/tt/recovery.py +++ b/core/src/trezor/ui/layouts/tt/recovery.py @@ -41,10 +41,10 @@ async def request_word( ) -> str: if is_slip39: keyboard: Slip39Keyboard | Bip39Keyboard = Slip39Keyboard( - "Type word %s of %s:" % (word_index + 1, word_count) + f"Type word {word_index + 1} of {word_count}:" ) else: - keyboard = Bip39Keyboard("Type word %s of %s:" % (word_index + 1, word_count)) + keyboard = Bip39Keyboard(f"Type word {word_index + 1} of {word_count}:") word: str = await ctx.wait(keyboard) return word @@ -93,9 +93,9 @@ async def show_group_share_success( ) -> None: text = Text("Success", ui.ICON_CONFIRM) text.bold("You have entered") - text.bold("Share %s" % (share_index + 1)) + text.bold(f"Share {share_index + 1}") text.normal("from") - text.bold("Group %s" % (group_index + 1)) + text.bold(f"Group {group_index + 1}") await raise_if_cancelled( interact( diff --git a/core/src/trezor/ui/layouts/tt/reset.py b/core/src/trezor/ui/layouts/tt/reset.py index 92d217c2a..18a078c9f 100644 --- a/core/src/trezor/ui/layouts/tt/reset.py +++ b/core/src/trezor/ui/layouts/tt/reset.py @@ -32,9 +32,9 @@ async def show_share_words( if share_index is None: header_title = "Recovery seed" elif group_index is None: - header_title = "Recovery share #%s" % (share_index + 1) + header_title = f"Recovery share #{share_index + 1}" else: - header_title = "Group %s - Share %s" % ((group_index + 1), (share_index + 1)) + header_title = f"Group {group_index + 1} - Share {share_index + 1}" header_icon = ui.ICON_RESET pages: list[ui.Component] = [] # ui page components shares_words_check = [] # check we display correct data @@ -42,10 +42,10 @@ async def show_share_words( # first page text = Text(header_title, header_icon) text.bold("Write down these") - text.bold("%s words:" % len(share_words)) + text.bold(f"{len(share_words)} words:") text.br_half() for index, word in first: - text.mono("%s. %s" % (index + 1, word)) + text.mono(f"{index + 1}. {word}") shares_words_check.append(word) pages.append(text) @@ -53,17 +53,17 @@ async def show_share_words( for chunk in chunks: text = Text(header_title, header_icon) for index, word in chunk: - text.mono("%s. %s" % (index + 1, word)) + text.mono(f"{index + 1}. {word}") shares_words_check.append(word) pages.append(text) # last page text = Text(header_title, header_icon) for index, word in last: - text.mono("%s. %s" % (index + 1, word)) + text.mono(f"{index + 1}. {word}") shares_words_check.append(word) text.br_half() - text.bold("I wrote down all %s" % len(share_words)) + text.bold(f"I wrote down all {len(share_words)}") text.bold("words in order.") pages.append(text) @@ -208,23 +208,23 @@ async def slip39_prompt_threshold( text = "The threshold sets the number of shares " if group_id is None: text += "needed to recover your wallet. " - text += "Set it to %s and you will need " % count + text += f"Set it to {count} and you will need " if num_of_shares == 1: text += "1 share." elif num_of_shares == count: - text += "all %s of your %s shares." % (count, num_of_shares) + text += f"all {count} of your {num_of_shares} shares." else: - text += "any %s of your %s shares." % (count, num_of_shares) + text += f"any {count} of your {num_of_shares} shares." else: text += "needed to form a group. " - text += "Set it to %s and you will " % count + text += f"Set it to {count} and you will " if num_of_shares == 1: text += "need 1 share " elif num_of_shares == count: - text += "need all %s of %s shares " % (count, num_of_shares) + text += f"need all {count} of {num_of_shares} shares " else: - text += "need any %s of %s shares " % (count, num_of_shares) - text += "to form Group %s." % (group_id + 1) + text += f"need any {count} of {num_of_shares} shares " + text += f"to form Group {group_id + 1}." info = InfoConfirm(text) await info @@ -276,7 +276,7 @@ async def slip39_prompt_number_of_shares( "Next you will choose " "the threshold number of " "shares needed to form " - "Group %s." % (group_id + 1) + f"Group {group_id + 1}." ) await info diff --git a/core/src/trezor/utils.py b/core/src/trezor/utils.py index fe407287b..3f0c7a53b 100644 --- a/core/src/trezor/utils.py +++ b/core/src/trezor/utils.py @@ -93,9 +93,9 @@ def presize_module(modname: str, size: int) -> None: """ module = sys.modules[modname] for i in range(size): - setattr(module, "___PRESIZE_MODULE_%d" % i, None) + setattr(module, f"___PRESIZE_MODULE_{i}", None) for i in range(size): - delattr(module, "___PRESIZE_MODULE_%d" % i) + delattr(module, f"___PRESIZE_MODULE_{i}") if __debug__: @@ -103,7 +103,7 @@ if __debug__: def mem_dump(filename: str) -> None: from micropython import mem_info - print("### sysmodules (%d):" % len(sys.modules)) + print(f"### sysmodules ({len(sys.modules)}):") for mod in sys.modules: print("*", mod) if EMULATOR: @@ -321,7 +321,7 @@ def obj_repr(o: object) -> str: d = {attr: getattr(o, attr, None) for attr in o.__slots__} else: d = o.__dict__ - return "<%s: %s>" % (o.__class__.__name__, d) + return f"<{o.__class__.__name__}: {d}>" def truncate_utf8(string: str, max_bytes: int) -> str: @@ -373,14 +373,14 @@ if __debug__: yield " " + subline elif val and isinstance(val, list) and type(val[0]) == type(msg): # non-empty list of protobuf messages - yield " {}: [".format(key) + yield f" {key}: [" for subval in val: sublines = dump_protobuf_lines(subval) for subline in sublines: yield " " + subline yield " ]" else: - yield " {}: {!r}".format(key, val) + yield f" {key}: {repr(val)}" yield "}" diff --git a/core/src/trezor/wire/__init__.py b/core/src/trezor/wire/__init__.py index d7311b7ae..d304b68cb 100644 --- a/core/src/trezor/wire/__init__.py +++ b/core/src/trezor/wire/__init__.py @@ -297,7 +297,7 @@ async def _handle_single_message( try: msg_type = protobuf.type_for_wire(msg.type).MESSAGE_NAME except Exception: - msg_type = "%d - unknown message type" % msg.type + msg_type = f"{msg.type} - unknown message type" log.debug( __name__, "%s:%x receive: <%s>", @@ -364,7 +364,7 @@ async def _handle_single_message( # - something canceled the workflow from the outside if __debug__: if isinstance(exc, ActionCancelled): - log.debug(__name__, "cancelled: {}".format(exc.message)) + log.debug(__name__, "cancelled: %s", exc.message) elif isinstance(exc, loop.TaskClosed): log.debug(__name__, "cancelled: loop task was closed") else: diff --git a/core/tests/production_tests/main.py b/core/tests/production_tests/main.py index f185c5b1f..90f106e74 100644 --- a/core/tests/production_tests/main.py +++ b/core/tests/production_tests/main.py @@ -72,7 +72,7 @@ def test_touch(v): touch = True else: if io.poll([io.TOUCH], r, 10000) and r[0] == io.TOUCH and r[1][0] == io.TOUCH_END: - print('OK %d %d' % (r[1][1], r[1][2])) + print(f'OK {r[1][1]} {r[1][2]}') break if utime.ticks_us() > deadline: print('ERROR TIMEOUT') diff --git a/core/tests/test_apps.common.paths.py b/core/tests/test_apps.common.paths.py index dde5149dd..fef408428 100644 --- a/core/tests/test_apps.common.paths.py +++ b/core/tests/test_apps.common.paths.py @@ -26,17 +26,13 @@ class TestPathSchemas(unittest.TestCase): def assertMatch(self, schema, path): self.assertTrue( schema.match(path), - "Expected schema {!r} to match path {}".format( - schema, address_n_to_str(path) - ), + f"Expected schema {repr(schema)} to match path {address_n_to_str(path)}", ) def assertMismatch(self, schema, path): self.assertFalse( schema.match(path), - "Expected schema {!r} to not match path {}".format( - schema, address_n_to_str(path) - ), + f"Expected schema {repr(schema)} to not match path {address_n_to_str(path)}", ) def assertEqualSchema(self, schema_a, schema_b): @@ -48,7 +44,7 @@ class TestPathSchemas(unittest.TestCase): ensure( all(is_equal(a, b) for a, b in zip(schema_a.schema, schema_b.schema)) and is_equal(schema_a.trailing_components, schema_b.trailing_components), - "Schemas differ:\nA = {!r}\nB = {!r}".format(schema_a, schema_b), + f"Schemas differ:\nA = {repr(schema_a)}\nB = {repr(schema_b)}" ) def test_always_never_matching(self): diff --git a/core/tests/test_trezor.io.fatfs.py b/core/tests/test_trezor.io.fatfs.py index 5c216c178..63b82db96 100644 --- a/core/tests/test_trezor.io.fatfs.py +++ b/core/tests/test_trezor.io.fatfs.py @@ -14,90 +14,90 @@ class TestTrezorIoFatfs(unittest.TestCase): sdcard.power_off() def _filename(self, suffix=""): - return "FILE%s.TXT" % suffix + return f"FILE{suffix}.TXT" def _dirname(self, suffix=""): - return "TREZOR%s" % suffix + return f"TREZOR{suffix}" def test_basic(self): # test just the stuff in setup and teardown pass def test_mkdir(self): - fatfs.mkdir("/%s" % self._dirname()) - s = fatfs.stat("/%s" % self._dirname()) + fatfs.mkdir(f"/{self._dirname()}") + s = fatfs.stat(f"/{self._dirname()}") self.assertEqual(s, (0, "---d-", self._dirname())) def test_listdir(self): - fatfs.mkdir("/%s" % self._dirname()) - with fatfs.open("/%s" % self._filename(), "w") as f: + fatfs.mkdir(f"/{self._dirname()}") + with fatfs.open(f"{self._filename()}", "w") as f: f.write(bytearray(b"test")) - with fatfs.open("/%s/%s" % (self._dirname(), self._filename("2")), "w") as f: + with fatfs.open(f"/{self._dirname()}/{self._filename('2')}", "w") as f: f.write(bytearray(b"testtest")) l = [e for e in fatfs.listdir("/")] self.assertEqual( l, [(0, "---d-", self._dirname()), (4, "----a", self._filename())] ) - l = [e for e in fatfs.listdir("/%s" % self._dirname())] + l = [e for e in fatfs.listdir(f"/{self._dirname()}")] self.assertEqual(l, [(8, "----a", self._filename("2"))]) def test_unlink(self): - fatfs.mkdir("/%s" % self._dirname()) - with fatfs.open("/%s" % self._filename(), "w") as f: + fatfs.mkdir(f"/{self._dirname()}") + with fatfs.open(f"/{self._filename()}", "w") as f: f.write(bytearray(b"test")) - s = fatfs.stat("/%s" % self._dirname()) + s = fatfs.stat(f"/{self._dirname()}") self.assertEqual(s, (0, "---d-", self._dirname())) - s = fatfs.stat("/%s" % self._filename()) + s = fatfs.stat(f"/{self._filename()}") self.assertEqual(s, (4, "----a", self._filename())) - fatfs.unlink("/%s" % self._dirname()) - fatfs.unlink("/%s" % self._filename()) + fatfs.unlink(f"/{self._dirname()}") + fatfs.unlink(f"/{self._filename()}") with self.assertRaises(fatfs.FatFSError): - fatfs.stat("/%s" % self._dirname()) + fatfs.stat(f"/{self._dirname()}") with self.assertRaises(fatfs.FatFSError): - self.assertRaises(fatfs.stat("/%s" % self._filename())) + self.assertRaises(fatfs.stat(f"/{self._filename()}")) def test_rename(self): - fatfs.mkdir("/%s" % self._dirname()) - with fatfs.open("/%s" % self._filename(), "w") as f: + fatfs.mkdir(f"/{self._dirname()}") + with fatfs.open(f"/{self._filename()}", "w") as f: f.write(bytearray(b"test")) - s = fatfs.stat("/%s" % self._dirname()) + s = fatfs.stat(f"/{self._dirname()}") self.assertEqual(s, (0, "---d-", self._dirname())) - s = fatfs.stat("/%s" % self._filename()) + s = fatfs.stat(f"/{self._filename()}") self.assertEqual(s, (4, "----a", self._filename())) - fatfs.rename("/%s" % self._dirname(), "/%s" % self._dirname("2")) - fatfs.rename("/%s" % self._filename(), "/%s" % self._filename("2")) + fatfs.rename(f"/{self._dirname()}", f"/{self._dirname('2')}") + fatfs.rename(f"/{self._filename()}", f"/{self._filename('2')}") with self.assertRaises(fatfs.FatFSError): - fatfs.stat("/%s" % self._dirname()) + fatfs.stat(f"/{self._dirname()}") with self.assertRaises(fatfs.FatFSError): - self.assertRaises(fatfs.stat("/%s" % self._filename())) - s = fatfs.stat("/%s" % self._dirname("2")) + self.assertRaises(fatfs.stat(f"/{self._filename()}")) + s = fatfs.stat(f"/{self._dirname('2')}") self.assertEqual(s, (0, "---d-", self._dirname("2"))) - s = fatfs.stat("/%s" % self._filename("2")) + s = fatfs.stat(f"/{self._filename('2')}") self.assertEqual(s, (4, "----a", self._filename("2"))) def test_open_rw(self): - with fatfs.open("/%s" % self._filename(), "w") as f: + with fatfs.open(f"/{self._filename()}", "w") as f: f.write(bytearray(b"test")) - with fatfs.open("/%s" % self._filename(), "r") as f: + with fatfs.open(f"/{self._filename()}", "r") as f: b = bytearray(100) r = f.read(b) self.assertEqual(r, 4) self.assertEqual(bytes(b[:4]), b"test") def test_open_a(self): - with fatfs.open("/%s" % self._filename(), "w") as f: + with fatfs.open(f"/{self._filename()}", "w") as f: f.write(bytearray(b"test" * 200)) - with fatfs.open("/%s" % self._filename(), "a") as f: + with fatfs.open(f"{self._filename()}", "a") as f: f.seek(800) f.write(bytearray(b"TEST" * 200)) - with fatfs.open("/%s" % self._filename(), "r") as f: + with fatfs.open(f"/{self._filename()}", "r") as f: b = bytearray(2000) r = f.read(b) self.assertEqual(r, 1600) self.assertEqual(bytes(b[:1600]), b"test" * 200 + b"TEST" * 200) def test_seek(self): - with fatfs.open("/%s" % self._filename(), "w+") as f: + with fatfs.open(f"/{self._filename()}", "w+") as f: f.write(bytearray(b"test" * 10)) f.seek(2) b = bytearray(8) @@ -106,23 +106,23 @@ class TestTrezorIoFatfs(unittest.TestCase): self.assertEqual(bytes(b[:8]), b"sttestte") def test_truncate(self): - with fatfs.open("/%s" % self._filename(), "w") as f: + with fatfs.open(f"/{self._filename()}", "w") as f: f.write(bytearray(b"test" * 100)) - s = fatfs.stat("/%s" % self._filename()) + s = fatfs.stat(f"/{self._filename()}") self.assertEqual(s, (400, "----a", self._filename())) - with fatfs.open("/%s" % self._filename(), "a") as f: + with fatfs.open(f"/{self._filename()}", "a") as f: f.seek(111) f.truncate() - s = fatfs.stat("/%s" % self._filename()) + s = fatfs.stat(f"/{self._filename()}") self.assertEqual(s, (111, "----a", self._filename())) class TestTrezorIoFatfsLfn(TestTrezorIoFatfs): def _filename(self, suffix=""): - return "reallylongfilename%s.textfile" % suffix + return f"reallylongfilename{suffix}.textfile" def _dirname(self, suffix=""): - return "reallylongdirname%s" % suffix + return f"reallylongdirname{suffix}" class TestTrezorIoFatfsMounting(unittest.TestCase): diff --git a/core/tests/unittest.py b/core/tests/unittest.py index 8121c4271..368175fd6 100644 --- a/core/tests/unittest.py +++ b/core/tests/unittest.py @@ -18,7 +18,7 @@ class AssertRaisesContext: def __exit__(self, exc_type, exc_value, tb): if exc_type is None: - ensure(False, "%r not raised" % self.expected) + ensure(False, f"{repr(self.expected)} not raised") if issubclass(exc_type, self.expected): self.value = exc_value return True @@ -32,7 +32,7 @@ class TestCase: def assertEqual(self, x, y, msg=''): if not msg: - msg = "%r vs (expected) %r" % (x, y) + msg = f"{repr(x)} vs (expected) {repr(y)}" if x.__class__ == y.__class__ and x.__class__.__name__ == "Msg": self.assertMessageEqual(x, y) @@ -41,7 +41,7 @@ class TestCase: def assertNotEqual(self, x, y, msg=''): if not msg: - msg = "%r not expected to be equal %r" % (x, y) + msg = f"{repr(x)} not expected to be equal {repr(y)}" ensure(x != y, msg) def assertAlmostEqual(self, x, y, places=None, msg='', delta=None): @@ -54,14 +54,14 @@ class TestCase: if abs(x - y) <= delta: return if not msg: - msg = '%r != %r within %r delta' % (x, y, delta) + msg = f'{repr(x)} != {repr(y)} within {repr(delta)} delta' else: if places is None: places = 7 if round(abs(y - x), places) == 0: return if not msg: - msg = '%r != %r within %r places' % (x, y, places) + msg = f'{repr(x)} != {repr(y)} within {repr(places)} places' ensure(False, msg) @@ -73,50 +73,50 @@ class TestCase: if not (x == y) and abs(x - y) > delta: return if not msg: - msg = '%r == %r within %r delta' % (x, y, delta) + msg = f'{repr(x)} == {repr(y)} within {repr(delta)} delta' else: if places is None: places = 7 if not (x == y) and round(abs(y - x), places) != 0: return if not msg: - msg = '%r == %r within %r places' % (x, y, places) + msg = f'{repr(x)} == {repr(y)} within {repr(places)} places' ensure(False, msg) def assertIs(self, x, y, msg=''): if not msg: - msg = "%r is not %r" % (x, y) + msg = f"{repr(x)} is not {repr(y)}" ensure(x is y, msg) def assertIsNot(self, x, y, msg=''): if not msg: - msg = "%r is %r" % (x, y) + msg = f"{repr(x)} is {repr(y)}" ensure(x is not y, msg) def assertIsNone(self, x, msg=''): if not msg: - msg = "%r is not None" % x + msg = f"{repr(x)} is not None" ensure(x is None, msg) def assertIsNotNone(self, x, msg=''): if not msg: - msg = "%r is None" % x + msg = f"{repr(x)} is None" ensure(x is not None, msg) def assertTrue(self, x, msg=''): if not msg: - msg = "Expected %r to be True" % x + msg = f"Expected {repr(x)} to be True" ensure(x, msg) def assertFalse(self, x, msg=''): if not msg: - msg = "Expected %r to be False" % x + msg = f"Expected {repr(x)} to be False" ensure(not x, msg) def assertIn(self, x, y, msg=''): if not msg: - msg = "Expected %r to be in %r" % (x, y) + msg = f"Expected {repr(x)} to be in {repr(y)}" ensure(x in y, msg) def assertIsInstance(self, x, y, msg=''): @@ -132,7 +132,7 @@ class TestCase: return raise else: - ensure(False, "%r not raised" % exc) + ensure(False, f"{repr(exc)} not raised") def assertListEqual(self, x, y, msg=''): if len(x) != len(y): @@ -160,7 +160,7 @@ class TestCase: self.assertEqual( x.MESSAGE_NAME, y.MESSAGE_NAME, - "Expected {}, found {}".format(x.MESSAGE_NAME, y.MESSAGE_NAME) + f"Expected {x.MESSAGE_NAME}, found {y.MESSAGE_NAME}" ) xdict = x.__dict__ ydict = y.__dict__ @@ -169,7 +169,7 @@ class TestCase: self.assertEqual( xdict[key], ydict[key], - "At {}.{} expected {}, found {}".format(x.MESSAGE_NAME, key, xdict[key], ydict[key]) + f"At {x.MESSAGE_NAME}.{key} expected {xdict[key]}, found {ydict[key]}" ) @@ -236,9 +236,9 @@ def run_class(c, test_result): test_result.testsRun += 1 retval = m() if isinstance(retval, generator_type): - raise RuntimeError("{} must not be a generator (it is async, uses yield or await).".format(name)) + raise RuntimeError(f"{name} must not be a generator (it is async, uses yield or await).") elif retval is not None: - raise RuntimeError("{} should not return a result.".format(name)) + raise RuntimeError(f"{name} should not return a result.") finally: tear_down() print(" ok") @@ -268,14 +268,14 @@ def main(module="__main__"): suite.addTest(c) runner = TestRunner() result = runner.run(suite) - msg = "Ran %d tests" % result.testsRun + msg = f"Ran {result.testsRun} tests" result_strs = [] if result.skippedNum > 0: - result_strs.append("{} skipped".format(result.skippedNum)) + result_strs.append(f"{result.skippedNum} skipped") if result.failuresNum > 0: - result_strs.append("{} failed".format(result.failuresNum)) + result_strs.append(f"{result.failuresNum} failed") if result.errorsNum > 0: - result_strs.append("{} errored".format(result.errorsNum)) + result_strs.append(f"{result.errorsNum} errored") if result_strs: msg += " (" + ", ".join(result_strs) + ")" print(msg) diff --git a/core/tools/alloc.py b/core/tools/alloc.py index 896105a66..daade603d 100755 --- a/core/tools/alloc.py +++ b/core/tools/alloc.py @@ -48,7 +48,7 @@ def annotate(obj, filename): if obj.type == "total": alloc_str = lambda line: str(line["total_allocs"]) else: - alloc_str = lambda line: "{:.2f}".format(line["avg_allocs"]) + alloc_str = lambda line: f"{line['avg_allocs']:.2f}" filedata = obj.data[filename] @@ -83,10 +83,10 @@ def _list(obj, sort_by="avg_allocs", reverse=False): def list(obj, reverse): if obj.type == "total": field = "total_allocs" - format_num = lambda l: "{}".format(l[2]) + format_num = lambda l: f"{l[2]}" else: field = "avg_allocs" - format_num = lambda l: "{:.2f}".format(l[1]) + format_num = lambda l: f"{l[1]:.2f}" file_sums = _list(obj, field, reverse) @@ -112,7 +112,7 @@ class HtmlTable: self.f.write("") for td in tds: if isinstance(td, tuple): - self.f.write("{}".format(td[0], td[1])) + self.f.write(f"{td[1]}") else: self.f.write(f"{td}") self.f.write("") @@ -129,9 +129,7 @@ def html(obj, htmldir): with open(f"{htmldir}/index.html", "w") as f: f.write("") f.write( - "

Total allocations: {}

".format( - sum(total_sum for _, _, total_sum in file_sums) - ) + f"

Total allocations: {sum(total_sum for _, _, total_sum in file_sums)}

" ) with HtmlTable(f) as table: table.tr((style_right, "avg"), (style_right, "total"), "") diff --git a/core/tools/build_mocks b/core/tools/build_mocks index 50225967a..871958f65 100755 --- a/core/tools/build_mocks +++ b/core/tools/build_mocks @@ -68,8 +68,8 @@ def store_to_file(dest, parts): if os.path.isdir(os.path.join(dest, package)): if not line.strip(): continue - print("Package exists: {}".format(package)) - print("You should set 'package:' in {}".format(line.strip())) + print(f"Package exists: {package}") + print(f"You should set 'package:' in {line.strip()}") sys.exit(1) if not os.path.exists(filepath): diff --git a/core/tools/headertool.py b/core/tools/headertool.py index 5a2b9678a..0e0112e7b 100755 --- a/core/tools/headertool.py +++ b/core/tools/headertool.py @@ -50,7 +50,7 @@ def parse_privkey_args(privkey_data: List[str]) -> Tuple[int, List[bytes]]: privkeys.append(bytes.fromhex(key_hex)) sigmask |= 1 << (int(idx) - 1) except ValueError: - click.echo("Could not parse key: {}".format(key)) + click.echo(f"Could not parse key: {key}") click.echo("Keys must be in the format: :") raise click.ClickException("Unrecognized key format.") return sigmask, privkeys @@ -59,30 +59,28 @@ def parse_privkey_args(privkey_data: List[str]) -> Tuple[int, List[bytes]]: def process_remote_signers(fw, addrs: List[str]) -> Tuple[int, List[bytes]]: if len(addrs) < fw.sigs_required: raise click.ClickException( - "Not enough signers (need at least {})".format(fw.sigs_required) + f"Not enough signers (need at least {fw.sigs_required})" ) digest = fw.digest() name = fw.NAME def mkproxy(addr): - return Pyro4.Proxy("PYRO:keyctl@{}:{}".format(addr, PORT)) + return Pyro4.Proxy(f"PYRO:keyctl@{addr}:{PORT}") sigmask = 0 pks, Rs = [], [] for addr in addrs: - click.echo("Connecting to {}...".format(addr)) + click.echo(f"Connecting to {addr}...") with mkproxy(addr) as proxy: pk, R = proxy.get_commit(name, digest) if pk not in fw.public_keys: raise click.ClickException( - "Signer at {} commits with unknown public key {}".format(addr, pk.hex()) + f"Signer at {addr} commits with unknown public key {pk.hex()}" ) idx = fw.public_keys.index(pk) click.echo( - "Signer at {} commits with public key #{}: {}".format( - addr, idx + 1, pk.hex() - ) + f"Signer at {addr} commits with public key #{idx + 1}: {pk.hex()}" ) sigmask |= 1 << idx pks.append(pk) @@ -95,7 +93,7 @@ def process_remote_signers(fw, addrs: List[str]) -> Tuple[int, List[bytes]]: # collect signatures sigs = [] for addr in addrs: - click.echo("Waiting for {} to sign... ".format(addr), nl=False) + click.echo(f"Waiting for {addr} to sign... ", nl=False) with mkproxy(addr) as proxy: sig = proxy.get_signature(name, digest, global_R, global_pk) sigs.append(sig) @@ -259,8 +257,8 @@ def cli( if remote: if Pyro4 is None: raise click.ClickException("Please install Pyro4 for remote signing.") - click.echo(fw.format()) - click.echo("Signing with {} remote participants.".format(len(remote))) + click.echo(fw) + click.echo(f"Signing with {len(remote)} remote participants.") sigmask, signature = process_remote_signers(fw, remote) if signature: diff --git a/core/tools/hid-bridge/hid_interface.py b/core/tools/hid-bridge/hid_interface.py index 217ba7193..0f1c696f5 100644 --- a/core/tools/hid-bridge/hid_interface.py +++ b/core/tools/hid-bridge/hid_interface.py @@ -17,13 +17,13 @@ class HIDInterface: def __uhid_read(self, length): data = os.read(self.file_descriptor, length) - logger.log_raw("{} >".format(HIDInterface.uhid_device), data.hex()) + logger.log_raw(f"{HIDInterface.uhid_device} >", data.hex()) return data def __uhid_write(self, data): bytes_written = os.write(self.file_descriptor, data) assert bytes_written == len(data) - logger.log_raw("{} <".format(HIDInterface.uhid_device), data.hex()) + logger.log_raw(f"{HIDInterface.uhid_device} <", data.hex()) def create_device(self): name = b"Virtual Trezor" @@ -61,33 +61,31 @@ class HIDInterface: self.__uhid_write(buf) logger.log_uhid_event( "UHID_CREATE2", - "name='{}' phys='{}' uniq=0x{} rd_size={} bus=0x{:04x} vendor=0x{:04x} product=0x{:04x} version=0x{:04x} country=0x{:04x} rd_data=0x{}".format( - name.decode("ascii"), - phys.decode("ascii"), - uniq.hex(), - len(rd_data), - bus, - vendor, - product, - version, - country, - rd_data.hex(), - ), + f"name='{name.decode()}' " + f"phys='{phys.decode()}' " + f"uniq=0x{uniq.hex()} " + f"rd_size={len(rd_data)} " + f"bus=0x{bus:04x} " + f"vendor=0x{vendor:04x} " + f"product=0x{product:04x} " + f"version=0x{version:04x} " + f"country=0x{country:04x} " + f"rd_data=0x{rd_data.hex()}", ) def write_data(self, data): buf = uhid.create_input2_event(data) self.__uhid_write(buf) logger.log_uhid_event( - "UHID_INPUT2", "data=0x{} size={}".format(data.hex(), len(data)) + "UHID_INPUT2", f"data=0x{data.hex()} size={len(data)}" ) - logger.log_hid_packet("DEVICE_OUTPUT", "0x{}".format(data.hex())) + logger.log_hid_packet("DEVICE_OUTPUT", f"0x{data.hex()}") def process_event(self): ev_type, request = uhid.parse_event(self.__uhid_read(uhid.EVENT_LENGTH)) if ev_type == uhid.EVENT_TYPE_START: dev_flags, = request - logger.log_uhid_event("UHID_START", "dev_flags=0b{:08b}".format(dev_flags)) + logger.log_uhid_event("UHID_START", f"dev_flags=0b{dev_flags:08b}") elif ev_type == uhid.EVENT_TYPE_STOP: logger.log_uhid_event("UHID_STOP") elif ev_type == uhid.EVENT_TYPE_OPEN: @@ -98,12 +96,12 @@ class HIDInterface: data, size, rtype = request logger.log_uhid_event( "UHID_OUTPUT", - "data=0x{} size={} rtype={}".format(data.hex(), size, rtype), + f"data=0x{data.hex()} size={size} rtype={rtype}", ) - logger.log_hid_packet("DEVICE_INPUT", "0x{}".format(data[1:].hex())) + logger.log_hid_packet("DEVICE_INPUT", f"0x{data[1:].hex()}") return data[1:] else: logger.log_uhid_event( "UNKNOWN_EVENT", - "ev_type={} request=0x{}".format(ev_type, request.hex()), + f"ev_type={ev_type} request=0x{request.hex()}", ) diff --git a/core/tools/hid-bridge/logger.py b/core/tools/hid-bridge/logger.py index 84df2ac90..d6d6732d4 100644 --- a/core/tools/hid-bridge/logger.py +++ b/core/tools/hid-bridge/logger.py @@ -10,7 +10,7 @@ def __get_timestamp(): def __log_message(message): if log_timestamps == True: - print("{}\t{}".format(__get_timestamp(), message)) + print(f"{__get_timestamp()}\t{message}") else: print(message) @@ -18,16 +18,16 @@ def __log_message(message): def log_uhid_event(event_name, params=None): if log_level == "uhid-event": if params: - __log_message("{}\t{}".format(event_name, params)) + __log_message(f"{event_name}\t{params}") else: __log_message(event_name) def log_hid_packet(packet_name, payload): if log_level == "hid-packet": - __log_message("{}\t{}".format(packet_name, payload)) + __log_message(f"{packet_name}\t{payload}") def log_raw(direction, payload): if log_level == "raw": - __log_message("{}\t{}".format(direction, payload)) + __log_message(f"{direction}\t{payload}") diff --git a/core/tools/hid-bridge/udp_interface.py b/core/tools/hid-bridge/udp_interface.py index 7ef98d870..dbc360d89 100644 --- a/core/tools/hid-bridge/udp_interface.py +++ b/core/tools/hid-bridge/udp_interface.py @@ -22,18 +22,14 @@ class UDPInterface: ) assert bytes_sent == len(data) logger.log_raw( - "{}:{} < {}:{}".format( - self.destination_ip, self.destination_port, self.bind_ip, self.bind_port - ), + f"{self.destination_ip}:{self.destination_port} < {self.bind_ip}:{self.bind_port}", data.hex(), ) def read(self, length): data, address = self.socket.recvfrom(length) logger.log_raw( - "{}:{} < {}:{}".format( - self.bind_ip, self.bind_port, address[0], address[1] - ), + f"{self.bind_ip}:{self.bind_port} < {address[0]}:{address[1]}", data.hex(), ) return data diff --git a/core/tools/hid-bridge/uhid.py b/core/tools/hid-bridge/uhid.py index 99236152e..4e1213742 100644 --- a/core/tools/hid-bridge/uhid.py +++ b/core/tools/hid-bridge/uhid.py @@ -11,10 +11,10 @@ EVENT_TYPE_INTPUT2 = 12 DATA_MAX = 4096 EVENT_LENGTH = 4380 -INPUT2_REQ_FMT = "< H {}s".format(DATA_MAX) -CREATE2_REQ_FMT = "< 128s 64s 64s H H L L L L {}s".format(DATA_MAX) +INPUT2_REQ_FMT = f"< H {DATA_MAX}s" +CREATE2_REQ_FMT = f"< 128s 64s 64s H H L L L L {DATA_MAX}s" START_REQ_FMT = "< Q" -OUTPUT_REQ_FMT = "< {}s H B".format(DATA_MAX) +OUTPUT_REQ_FMT = f"< {DATA_MAX}s H B" def pack_event(ev_type, request): diff --git a/legacy/bootloader/combine/prepare.py b/legacy/bootloader/combine/prepare.py index f2b3e952d..b74a48219 100755 --- a/legacy/bootloader/combine/prepare.py +++ b/legacy/bootloader/combine/prepare.py @@ -6,6 +6,6 @@ combined = bl + 32768 * b"\xff" + fw open("combined.bin", "wb").write(combined) -print("bootloader : %d bytes" % len(bl)) -print("firmware : %d bytes" % len(fw)) -print("combined : %d bytes" % len(combined)) +print(f"bootloader : {len(bl)} bytes") +print(f"firmware : {len(fw)} bytes") +print(f"combined : {len(combined)} bytes") diff --git a/legacy/bootloader/firmware_align.py b/legacy/bootloader/firmware_align.py index 0866593f5..80be7cd0e 100755 --- a/legacy/bootloader/firmware_align.py +++ b/legacy/bootloader/firmware_align.py @@ -9,8 +9,7 @@ fn = sys.argv[1] fs = os.stat(fn).st_size if fs > MAXSIZE: raise Exception( - "bootloader has to be smaller than %d bytes (current size is %d)" - % (MAXSIZE, fs) + f"bootloader has to be smaller than {MAXSIZE} bytes (current size is {fs})" ) with open(fn, "ab") as f: f.write(b"\x00" * (TOTALSIZE - fs)) diff --git a/legacy/bootloader/firmware_sign.py b/legacy/bootloader/firmware_sign.py index 408fdd058..a19e73e92 100755 --- a/legacy/bootloader/firmware_sign.py +++ b/legacy/bootloader/firmware_sign.py @@ -126,7 +126,7 @@ def check_signatures(data): signature = data[SIGNATURES_START + 64 * x : SIGNATURES_START + 64 * x + 64] if indexes[x] == 0: - print("Slot #%d" % (x + 1), "is empty") + print(f"Slot #{x + 1}", "is empty") else: pk = pubkeys[indexes[x]] verify = ecdsa.VerifyingKey.from_string( @@ -139,13 +139,13 @@ def check_signatures(data): verify.verify(signature, to_sign, hashfunc=hashlib.sha256) if indexes[x] in used: - print("Slot #%d signature: DUPLICATE" % (x + 1), signature.hex()) + print(f"Slot #{x + 1} signature: DUPLICATE", signature.hex()) else: used.append(indexes[x]) - print("Slot #%d signature: VALID" % (x + 1), signature.hex()) + print(f"Slot #{x + 1} signature: VALID", signature.hex()) except Exception: - print("Slot #%d signature: INVALID" % (x + 1), signature.hex()) + print(f"Slot #{x + 1} signature: INVALID", signature.hex()) def modify(data, slot, index, signature): @@ -160,7 +160,7 @@ def modify(data, slot, index, signature): def sign(data, is_pem): # Ask for index and private key and signs the firmware - slot = int(input("Enter signature slot (1-%d): " % SLOTS)) + slot = int(input(f"Enter signature slot (1-{SLOTS}): ")) if slot < 1 or slot > SLOTS: raise Exception("Invalid slot") @@ -236,7 +236,7 @@ def main(args): data = update_hashes_in_header(data) - print("Firmware size %d bytes" % len(data)) + print(f"Firmware size {len(data)} bytes") check_size(data) check_signatures(data) diff --git a/legacy/firmware/bl_data.py b/legacy/firmware/bl_data.py index 3734825f1..6d0207f2b 100755 --- a/legacy/firmware/bl_data.py +++ b/legacy/firmware/bl_data.py @@ -15,8 +15,8 @@ bl_hash = ", ".join("0x%02x" % x for x in bytearray(bh)) bl_data = ", ".join("0x%02x" % x for x in bytearray(data)) with open("bl_data.h", "wt") as f: - f.write("static const uint8_t bl_hash[32] = {%s};\n" % bl_hash) - f.write("static const uint8_t bl_data[32768] = {%s};\n" % bl_data) + f.write(f"static const uint8_t bl_hash[32] = {{{bl_hash}}};\n") + f.write(f"static const uint8_t bl_data[32768] = {{{bl_data}}};\n") # make sure the last item listed in known_bootloader function # is our bootloader diff --git a/legacy/firmware/protob/messages_map.py b/legacy/firmware/protob/messages_map.py index 8d490929a..f6f9a3a2b 100755 --- a/legacy/firmware/protob/messages_map.py +++ b/legacy/firmware/protob/messages_map.py @@ -58,26 +58,26 @@ def handle_message(fh, fl, skipped, message): no_fsm = options.Extensions[wire_no_fsm] if getattr(options, "deprecated", None): - fh.write("\t// Message %s is deprecated\n" % short_name) + fh.write(f"\t// Message {short_name} is deprecated\n") return if bootloader: - fh.write("\t// Message %s is used in bootloader mode only\n" % short_name) + fh.write(f"\t// Message {short_name} is used in bootloader mode only\n") return if no_fsm: - fh.write("\t// Message %s is not used in FSM\n" % short_name) + fh.write(f"\t// Message {short_name} is not used in FSM\n") return if direction == "i": - process_func = "(void (*)(const void *))fsm_msg%s" % short_name + process_func = f"(void (*)(const void *))fsm_msg{short_name}" else: process_func = "0" fh.write( TEMPLATE.format( - type="'%c'," % interface, - dir="'%c'," % direction, - msg_id="MessageType_%s," % name, - fields="%s_fields," % short_name, + type=f"'{interface}',", + dir=f"'{direction}',", + msg_id=f"MessageType_{name},", + fields=f"{short_name}_fields,", process_func=process_func, ) ) @@ -97,14 +97,12 @@ def handle_message(fh, fl, skipped, message): if encoded_size: fl.write( - '_Static_assert(%s >= sizeof(%s_size), "msg buffer too small");\n' - % (encoded_size, short_name) + f'_Static_assert({encoded_size} >= sizeof({short_name}_size), "msg buffer too small");\n' ) if decoded_size: fl.write( - '_Static_assert(%s >= sizeof(%s), "msg buffer too small");\n' - % (decoded_size, short_name) + f'_Static_assert({decoded_size} >= sizeof({short_name}), "msg buffer too small");\n' ) @@ -130,7 +128,7 @@ for extension in (wire_in, wire_out, wire_debug_in, wire_debug_out): fh.write("\n#if DEBUG_LINK\n") fl.write("\n#if DEBUG_LINK\n") - fh.write("\n\t// {label}\n\n".format(label=LABELS[extension])) + fh.write(f"\n\t// {LABELS[extension]}\n\n") for message in messages[extension]: if message.name in SPECIAL_DEBUG_MESSAGES: diff --git a/legacy/gen/bitmaps/generate.py b/legacy/gen/bitmaps/generate.py index bbe7963de..34a1e5456 100755 --- a/legacy/gen/bitmaps/generate.py +++ b/legacy/gen/bitmaps/generate.py @@ -25,11 +25,11 @@ for fn in sorted(glob.glob("*.png")): name = os.path.splitext(fn)[0] w, h = im.size if w % 8 != 0: - raise Exception("Width must be divisible by 8! (%s is %dx%d)" % (fn, w, h)) + raise Exception(f"Width must be divisible by 8! ({fn} is {w}x{h})") img = list(im.getdata()) - hdrs.append("extern const BITMAP bmp_%s;\n" % name) - imgs.append("const BITMAP bmp_%s = {%d, %d, bmp_%s_data};\n" % (name, w, h, name)) - data.append("const uint8_t bmp_%s_data[] = { %s};\n" % (name, encode_pixels(img))) + hdrs.append(f"extern const BITMAP bmp_{name};\n") + imgs.append(f"const BITMAP bmp_{name} = {{{w}, {h}, bmp_{name}_data}};\n") + data.append(f"const uint8_t bmp_{name}_data[] = {{ {encode_pixels(img)}}};\n") cnt += 1 with open("../bitmaps.c", "wt") as f: diff --git a/legacy/gen/handlers/handlers.py b/legacy/gen/handlers/handlers.py index 7d5802af0..7e7e0c25f 100755 --- a/legacy/gen/handlers/handlers.py +++ b/legacy/gen/handlers/handlers.py @@ -93,11 +93,10 @@ with open("handlers.c", "wt") as f: f.write('#include "layout.h"\n') f.write('#include "oled.h"\n\n') for i in handlers: - f.write("void __attribute__((noreturn)) %s(void)\n" % i) + f.write(f"void __attribute__((noreturn)) {i}(void)\n") f.write("{\n") f.write( - '\tlayoutDialog(DIALOG_ICON_ERROR, NULL, NULL, NULL, "Encountered", NULL, "%s", NULL, "Please restart", "the device.");\n' - % i.upper() + f'\tlayoutDialog(DIALOG_ICON_ERROR, NULL, NULL, NULL, "Encountered", NULL, "{i.upper()}", NULL, "Please restart", "the device.");\n' ) f.write("\tfor (;;) {} // loop forever\n") f.write("}\n\n") diff --git a/legacy/script/fingerprint b/legacy/script/fingerprint index de9d90ed5..6d1cfcc53 100755 --- a/legacy/script/fingerprint +++ b/legacy/script/fingerprint @@ -37,5 +37,4 @@ if __name__ == "__main__": print("Filename :", args.file.name) print("Fingerprint :", fingerprint) - print("Size : {} bytes (out of {} maximum)" - .format(size, args.max_size)) + print(f"Size : {size} bytes (out of {args.max_size} maximum)") diff --git a/legacy/script/wait_for_emulator.py b/legacy/script/wait_for_emulator.py index 035104b15..893019888 100755 --- a/legacy/script/wait_for_emulator.py +++ b/legacy/script/wait_for_emulator.py @@ -28,4 +28,4 @@ while True: except Exception: time.sleep(0.05) end = time.monotonic() -print("waited for {:.3f}s".format(end - start)) +print(f"waited for {end - start:.3f}s") diff --git a/python/setup.py b/python/setup.py index 24be2253d..3c49b9ada 100755 --- a/python/setup.py +++ b/python/setup.py @@ -52,7 +52,7 @@ setup( author_email="info@trezor.io", license="LGPLv3", description="Python library for communicating with Trezor Hardware Wallet", - long_description="{}\n\n{}".format(read("README.md"), read("CHANGELOG.md")), + long_description=read("README.md") + "\n\n" + read("CHANGELOG.md"), long_description_content_type="text/markdown", url="https://github.com/trezor/trezor-firmware/tree/master/python", packages=find_packages("src"), diff --git a/python/src/trezorlib/_internal/emulator.py b/python/src/trezorlib/_internal/emulator.py index 74c7eeb72..7293e7122 100644 --- a/python/src/trezorlib/_internal/emulator.py +++ b/python/src/trezorlib/_internal/emulator.py @@ -47,13 +47,11 @@ class Emulator: storage=None, headless=False, debug=True, - extra_args=() + extra_args=(), ): self.executable = Path(executable).resolve() if not executable.exists(): - raise ValueError( - "emulator executable not found: {}".format(self.executable) - ) + raise ValueError(f"emulator executable not found: {self.executable}") self.profile_dir = Path(profile_dir).resolve() if not self.profile_dir.exists(): @@ -87,7 +85,7 @@ class Emulator: return os.environ.copy() def _get_transport(self): - return UdpTransport("127.0.0.1:{}".format(self.port)) + return UdpTransport(f"127.0.0.1:{self.port}") def wait_until_ready(self, timeout=EMULATOR_WAIT_TIME): transport = self._get_transport() @@ -109,7 +107,7 @@ class Emulator: finally: transport.close() - LOG.info("Emulator ready after {:.3f} seconds".format(time.monotonic() - start)) + LOG.info(f"Emulator ready after {time.monotonic() - start:.3f} seconds") def wait(self, timeout=None): ret = self.process.wait(timeout=timeout) @@ -149,9 +147,7 @@ class Emulator: self.wait_until_ready() except TimeoutError: # Assuming that after the default 60-second timeout, the process is stuck - LOG.warning( - "Emulator did not come up after {} seconds".format(EMULATOR_WAIT_TIME) - ) + LOG.warning(f"Emulator did not come up after {EMULATOR_WAIT_TIME} seconds") self.process.kill() raise @@ -175,7 +171,7 @@ class Emulator: try: self.process.wait(EMULATOR_WAIT_TIME) end = time.monotonic() - LOG.info("Emulator shut down after {:.3f} seconds".format(end - start)) + LOG.info(f"Emulator shut down after {end - start:.3f} seconds") except subprocess.TimeoutExpired: LOG.info("Emulator seems stuck. Sending kill signal.") self.process.kill() @@ -210,7 +206,7 @@ class CoreEmulator(Emulator): sdcard=None, disable_animation=True, heap_size="20M", - **kwargs + **kwargs, ): super().__init__(*args, **kwargs) if workdir is not None: @@ -244,7 +240,7 @@ class CoreEmulator(Emulator): def make_args(self): pyopt = "-O0" if self.debug else "-O1" return ( - [pyopt, "-X", "heapsize={}".format(self.heap_size)] + [pyopt, "-X", f"heapsize={self.heap_size}"] + self.main_args + self.extra_args ) diff --git a/python/src/trezorlib/_internal/firmware_headers.py b/python/src/trezorlib/_internal/firmware_headers.py index 92b15b747..db78da240 100644 --- a/python/src/trezorlib/_internal/firmware_headers.py +++ b/python/src/trezorlib/_internal/firmware_headers.py @@ -137,7 +137,7 @@ def _format_container( output = repr(value) else: output = value.hex() - return "{} bytes {}{}".format(length, output, suffix) + return f"{length} bytes {output}{suffix}" if isinstance(value, Enum): return str(value) @@ -152,7 +152,7 @@ def _format_version(version: c.Container) -> str: str(version[k]) for k in ("major", "minor", "patch") if k in version ) if "build" in version: - version_str += " build {}".format(version.build) + version_str += f" build {version.build}" return version_str @@ -212,7 +212,7 @@ class VendorHeader(SignableImage): vhash = compute_vhash(vh) output = [ "Vendor Header " + _format_container(vh), - "Pubkey bundle hash: {}".format(vhash.hex()), + f"Pubkey bundle hash: {vhash.hex()}", ] else: output = [ @@ -226,13 +226,11 @@ class VendorHeader(SignableImage): fingerprint = firmware.header_digest(vh) if not terse: - output.append( - "Fingerprint: {}".format(click.style(fingerprint.hex(), bold=True)) - ) + output.append(f"Fingerprint: {click.style(fingerprint.hex(), bold=True)}") sig_status = self.check_signature() sym = SYM_OK if sig_status.is_ok() else SYM_FAIL - output.append("{} Signature is {}".format(sym, sig_status.value)) + output.append(f"{sym} Signature is {sig_status.value}") return "\n".join(output) @@ -278,7 +276,7 @@ class BinImage(SignableImage): hashes_out = [] for expected, actual in zip(self.header.hashes, self.code_hashes): status = SYM_OK if expected == actual else SYM_FAIL - hashes_out.append(LiteralStr("{} {}".format(status, expected.hex()))) + hashes_out.append(LiteralStr(f"{status} {expected.hex()}")) if all(all_zero(h) for h in self.header.hashes): hash_status = Status.MISSING @@ -294,10 +292,8 @@ class BinImage(SignableImage): output = [ "Firmware Header " + _format_container(header_out), - "Fingerprint: {}".format(click.style(self.digest().hex(), bold=True)), - "{} Signature is {}, hashes are {}".format( - all_ok, sig_status.value, hash_status.value - ), + f"Fingerprint: {click.style(self.digest().hex(), bold=True)}", + f"{all_ok} Signature is {sig_status.value}, hashes are {hash_status.value}", ] return "\n".join(output) diff --git a/python/src/trezorlib/btc.py b/python/src/trezorlib/btc.py index 775dcf767..8b65d3fc0 100644 --- a/python/src/trezorlib/btc.py +++ b/python/src/trezorlib/btc.py @@ -271,7 +271,7 @@ def sign_tx( idx = res.serialized.signature_index sig = res.serialized.signature if signatures[idx] is not None: - raise ValueError("Signature for index %d already filled" % idx) + raise ValueError(f"Signature for index {idx} already filled") signatures[idx] = sig if res.request_type == R.TXFINISHED: diff --git a/python/src/trezorlib/cli/__init__.py b/python/src/trezorlib/cli/__init__.py index 11dedce7e..fd315325a 100644 --- a/python/src/trezorlib/cli/__init__.py +++ b/python/src/trezorlib/cli/__init__.py @@ -78,7 +78,7 @@ class TrezorConnection: except Exception: click.echo("Failed to find a Trezor device.") if self.path is not None: - click.echo("Using path: {}".format(self.path)) + click.echo(f"Using path: {self.path}") sys.exit(1) try: diff --git a/python/src/trezorlib/cli/debug.py b/python/src/trezorlib/cli/debug.py index 8c579716d..c5d2e0a87 100644 --- a/python/src/trezorlib/cli/debug.py +++ b/python/src/trezorlib/cli/debug.py @@ -58,12 +58,12 @@ def send_bytes(obj, message_name_or_type, hex_data): response_type, response_data = transport.read() transport.end_session() - click.echo("Response type: {}".format(response_type)) - click.echo("Response data: {}".format(response_data.hex())) + click.echo(f"Response type: {response_type}") + click.echo(f"Response data: {response_data.hex()}") try: msg = mapping.decode(response_type, response_data) click.echo("Parsed message:") click.echo(protobuf.format_message(msg)) except Exception as e: - click.echo("Could not parse response: {}".format(e)) + click.echo(f"Could not parse response: {e}") diff --git a/python/src/trezorlib/cli/eos.py b/python/src/trezorlib/cli/eos.py index 5164c3adb..7b60673e3 100644 --- a/python/src/trezorlib/cli/eos.py +++ b/python/src/trezorlib/cli/eos.py @@ -37,7 +37,7 @@ def get_public_key(client, address, show_display): """Get Eos public key in base58 encoding.""" address_n = tools.parse_path(address) res = eos.get_public_key(client, address_n, show_display) - return "WIF: {}\nRaw: {}".format(res.wif_public_key, res.raw_public_key.hex()) + return f"WIF: {res.wif_public_key}\nRaw: {res.raw_public_key.hex()}" @cli.command() diff --git a/python/src/trezorlib/cli/ethereum.py b/python/src/trezorlib/cli/ethereum.py index 2f88a8d43..1a1e4ed74 100644 --- a/python/src/trezorlib/cli/ethereum.py +++ b/python/src/trezorlib/cli/ethereum.py @@ -303,7 +303,7 @@ def sign_tx( "to": to_address, "from": from_address, "value": amount, - "data": "0x%s" % data.hex(), + "data": f"0x{data.hex()}", } ) @@ -361,16 +361,17 @@ def sign_tx( transaction = rlp.encode( (tx_type, nonce, gas_price, gas_limit, to, amount, data) + sig ) - tx_hex = "0x%s%s" % ( - str(eip2718_type).zfill(2) if eip2718_type is not None else "", - transaction.hex(), - ) + if eip2718_type is not None: + eip2718_prefix = f"{eip2718_type:02x}" + else: + eip2718_prefix = "" + tx_hex = f"0x{eip2718_prefix}{transaction.hex()}" if publish: tx_hash = w3.eth.sendRawTransaction(tx_hex).hex() - return "Transaction published with ID: %s" % tx_hash + return f"Transaction published with ID: {tx_hash}" else: - return "Signed raw transaction:\n%s" % tx_hex + return f"Signed raw transaction:\n{tx_hex}" @cli.command() @@ -384,7 +385,7 @@ def sign_message(client, address, message): output = { "message": message, "address": ret.address, - "signature": "0x%s" % ret.signature.hex(), + "signature": f"0x{ret.signature.hex()}", } return output diff --git a/python/src/trezorlib/cli/fido.py b/python/src/trezorlib/cli/fido.py index 49ed41bd4..5ec819d5a 100644 --- a/python/src/trezorlib/cli/fido.py +++ b/python/src/trezorlib/cli/fido.py @@ -41,30 +41,30 @@ def credentials_list(client): creds = fido.list_credentials(client) for cred in creds: click.echo("") - click.echo("WebAuthn credential at index {}:".format(cred.index)) + click.echo(f"WebAuthn credential at index {cred.index}:") if cred.rp_id is not None: - click.echo(" Relying party ID: {}".format(cred.rp_id)) + click.echo(f" Relying party ID: {cred.rp_id}") if cred.rp_name is not None: - click.echo(" Relying party name: {}".format(cred.rp_name)) + click.echo(f" Relying party name: {cred.rp_name}") if cred.user_id is not None: - click.echo(" User ID: {}".format(cred.user_id.hex())) + click.echo(f" User ID: {cred.user_id.hex()}") if cred.user_name is not None: - click.echo(" User name: {}".format(cred.user_name)) + click.echo(f" User name: {cred.user_name}") if cred.user_display_name is not None: - click.echo(" User display name: {}".format(cred.user_display_name)) + click.echo(f" User display name: {cred.user_display_name}") if cred.creation_time is not None: - click.echo(" Creation time: {}".format(cred.creation_time)) + click.echo(f" Creation time: {cred.creation_time}") if cred.hmac_secret is not None: - click.echo(" hmac-secret enabled: {}".format(cred.hmac_secret)) + click.echo(f" hmac-secret enabled: {cred.hmac_secret}") if cred.use_sign_count is not None: - click.echo(" Use signature counter: {}".format(cred.use_sign_count)) + click.echo(f" Use signature counter: {cred.use_sign_count}") if cred.algorithm is not None: algorithm = ALGORITHM_NAME.get(cred.algorithm, cred.algorithm) - click.echo(" Algorithm: {}".format(algorithm)) + click.echo(f" Algorithm: {algorithm}") if cred.curve is not None: curve = CURVE_NAME.get(cred.curve, cred.curve) - click.echo(" Curve: {}".format(curve)) - click.echo(" Credential ID: {}".format(cred.id.hex())) + click.echo(f" Curve: {curve}") + click.echo(f" Credential ID: {cred.id.hex()}") if not creds: click.echo("There are no resident credentials stored on the device.") diff --git a/python/src/trezorlib/cli/nem.py b/python/src/trezorlib/cli/nem.py index cff0bd7a1..4664faec0 100644 --- a/python/src/trezorlib/cli/nem.py +++ b/python/src/trezorlib/cli/nem.py @@ -58,8 +58,6 @@ def sign_tx(client, address, file, broadcast): payload = {"data": transaction.data.hex(), "signature": transaction.signature.hex()} if broadcast: - return requests.post( - "{}/transaction/announce".format(broadcast), json=payload - ).json() + return requests.post(f"{broadcast}/transaction/announce", json=payload).json() else: return payload diff --git a/python/src/trezorlib/cli/trezorctl.py b/python/src/trezorlib/cli/trezorctl.py index 601c84186..5b07a273c 100755 --- a/python/src/trezorlib/cli/trezorctl.py +++ b/python/src/trezorlib/cli/trezorctl.py @@ -165,7 +165,7 @@ def cli(ctx, path, verbose, is_json, passphrase_on_host, session_id): try: session_id = bytes.fromhex(session_id) except ValueError: - raise click.ClickException("Not a valid session id: {}".format(session_id)) + raise click.ClickException(f"Not a valid session id: {session_id}") ctx.obj = TrezorConnection(path, session_id, passphrase_on_host) @@ -185,9 +185,9 @@ def print_result(res, is_json, **kwargs): for k, v in res.items(): if isinstance(v, dict): for kk, vv in v.items(): - click.echo("%s.%s: %s" % (k, kk, vv)) + click.echo(f"{k}.{kk}: {vv}") else: - click.echo("%s: %s" % (k, v)) + click.echo(f"{k}: {v}") elif isinstance(res, protobuf.MessageType): click.echo(protobuf.format_message(res)) elif res is not None: @@ -197,10 +197,10 @@ def print_result(res, is_json, **kwargs): def format_device_name(features): model = features.model or "1" if features.bootloader_mode: - return "Trezor {} bootloader".format(model) + return f"Trezor {model} bootloader" label = features.label or "(unnamed)" - return "{} [Trezor {}, {}]".format(label, model, features.device_id) + return f"{label} [Trezor {model}, {features.device_id}]" # @@ -217,7 +217,7 @@ def list_devices(no_resolve): for transport in enumerate_devices(): client = TrezorClient(transport, ui=ui.ClickUI()) - click.echo("{} - {}".format(transport, format_device_name(client.features))) + click.echo(f"{transport} - {format_device_name(client.features)}") client.end_session() @@ -308,14 +308,14 @@ def wait_for_emulator(obj, timeout): path = obj.path if path: if not path.startswith("udp:"): - raise click.ClickException("You must use UDP path, not {}".format(path)) + raise click.ClickException(f"You must use UDP path, not {path}") path = path.replace("udp:", "") start = time.monotonic() UdpTransport(path).wait_until_ready(timeout) end = time.monotonic() - LOG.info("Waited for {:.3f} seconds".format(end - start)) + LOG.info(f"Waited for {end - start:.3f} seconds") # diff --git a/python/src/trezorlib/client.py b/python/src/trezorlib/client.py index ef0753d6e..bddec6fba 100644 --- a/python/src/trezorlib/client.py +++ b/python/src/trezorlib/client.py @@ -89,7 +89,7 @@ class TrezorClient: ui, session_id=None, ): - LOG.info("creating client instance for device: {}".format(transport.get_path())) + LOG.info(f"creating client instance for device: {transport.get_path()}") self.transport = transport self.ui = ui self.session_counter = 0 @@ -118,15 +118,13 @@ class TrezorClient: def _raw_write(self, msg): __tracebackhide__ = True # for pytest # pylint: disable=W0612 LOG.debug( - "sending message: {}".format(msg.__class__.__name__), + f"sending message: {msg.__class__.__name__}", extra={"protobuf": msg}, ) msg_type, msg_bytes = mapping.encode(msg) LOG.log( DUMP_BYTES, - "encoded as type {} ({} bytes): {}".format( - msg_type, len(msg_bytes), msg_bytes.hex() - ), + f"encoded as type {msg_type} ({len(msg_bytes)} bytes): {msg_bytes.hex()}", ) self.transport.write(msg_type, msg_bytes) @@ -135,13 +133,11 @@ class TrezorClient: msg_type, msg_bytes = self.transport.read() LOG.log( DUMP_BYTES, - "received type {} ({} bytes): {}".format( - msg_type, len(msg_bytes), msg_bytes.hex() - ), + f"received type {msg_type} ({len(msg_bytes)} bytes): {msg_bytes.hex()}", ) msg = mapping.decode(msg_type, msg_bytes) LOG.debug( - "received message: {}".format(msg.__class__.__name__), + f"received message: {msg.__class__.__name__}", extra={"protobuf": msg}, ) return msg diff --git a/python/src/trezorlib/debuglink.py b/python/src/trezorlib/debuglink.py index 37ce1e679..1fa205190 100644 --- a/python/src/trezorlib/debuglink.py +++ b/python/src/trezorlib/debuglink.py @@ -53,15 +53,13 @@ class DebugLink: def _call(self, msg, nowait=False): LOG.debug( - "sending message: {}".format(msg.__class__.__name__), + f"sending message: {msg.__class__.__name__}", extra={"protobuf": msg}, ) msg_type, msg_bytes = mapping.encode(msg) LOG.log( DUMP_BYTES, - "encoded as type {} ({} bytes): {}".format( - msg_type, len(msg_bytes), msg_bytes.hex() - ), + f"encoded as type {msg_type} ({len(msg_bytes)} bytes): {msg_bytes.hex()}", ) self.transport.write(msg_type, msg_bytes) if nowait: @@ -70,13 +68,11 @@ class DebugLink: ret_type, ret_bytes = self.transport.read() LOG.log( DUMP_BYTES, - "received type {} ({} bytes): {}".format( - msg_type, len(msg_bytes), msg_bytes.hex() - ), + f"received type {msg_type} ({len(msg_bytes)} bytes): {msg_bytes.hex()}", ) msg = mapping.decode(ret_type, ret_bytes) LOG.debug( - "received message: {}".format(msg.__class__.__name__), + f"received message: {msg.__class__.__name__}", extra={"protobuf": msg}, ) return msg @@ -328,15 +324,15 @@ class MessageFilter: field_str = textwrap.indent(field_str, " ").lstrip() fields.append((field.name, field_str)) - pairs = ["{}={}".format(k, v) for k, v in fields] + pairs = [f"{k}={v}" for k, v in fields] oneline_str = ", ".join(pairs) if len(oneline_str) < maxwidth: - return "{}({})".format(self.message_type.__name__, oneline_str) + return f"{self.message_type.__name__}({oneline_str})" else: item = [] - item.append("{}(".format(self.message_type.__name__)) + item.append(f"{self.message_type.__name__}(") for pair in pairs: - item.append(" {}".format(pair)) + item.append(f" {pair}") item.append(")") return "\n".join(item) @@ -567,7 +563,7 @@ class TrezorClientDebugLink(TrezorClient): for i in range(start_at, stop_at): exp = expected[i] prefix = " " if i != current else ">>> " - output.append(textwrap.indent(exp.format(), prefix)) + output.append(textwrap.indent(exp, prefix)) if stop_at < len(expected): omitted = len(expected) - stop_at output.append(f" (...{omitted} following responses omitted)") diff --git a/python/src/trezorlib/eos.py b/python/src/trezorlib/eos.py index 55d3be7fb..9aa4c92e9 100644 --- a/python/src/trezorlib/eos.py +++ b/python/src/trezorlib/eos.py @@ -344,7 +344,7 @@ def sign_tx(client, address, transaction, chain_id): if not isinstance(response, messages.EosSignedTx): raise exceptions.TrezorException( - "Unexpected message: {}".format(response.__class__.__name__) + f"Unexpected message: {response.__class__.__name__}" ) return response diff --git a/python/src/trezorlib/exceptions.py b/python/src/trezorlib/exceptions.py index a2aa9bc71..aadd99ae8 100644 --- a/python/src/trezorlib/exceptions.py +++ b/python/src/trezorlib/exceptions.py @@ -35,7 +35,7 @@ class TrezorFailure(TrezorException): if not name.startswith("_") } if self.message is not None: - return "{}: {}".format(types[self.code], self.message) + return f"{types[self.code]}: {self.message}" else: return types[self.failure.code] diff --git a/python/src/trezorlib/firmware.py b/python/src/trezorlib/firmware.py index bab446d05..64d958308 100644 --- a/python/src/trezorlib/firmware.py +++ b/python/src/trezorlib/firmware.py @@ -304,9 +304,7 @@ def check_sig_v1( if len(distinct_key_indexes) < len(key_indexes): raise InvalidSignatureError( - "Not enough distinct signatures (found {}, need {})".format( - len(distinct_key_indexes), len(key_indexes) - ) + f"Not enough distinct signatures (found {len(distinct_key_indexes)}, need {len(key_indexes)})" ) for i in range(len(key_indexes)): @@ -315,14 +313,14 @@ def check_sig_v1( if key_idx >= len(V1_BOOTLOADER_KEYS): # unknown pubkey - raise InvalidSignatureError("Unknown key in slot {}".format(i)) + raise InvalidSignatureError(f"Unknown key in slot {i}") pubkey = V1_BOOTLOADER_KEYS[key_idx][1:] verify = ecdsa.VerifyingKey.from_string(pubkey, curve=ecdsa.curves.SECP256k1) try: verify.verify_digest(signature, digest) except ecdsa.BadSignatureError as e: - raise InvalidSignatureError("Invalid signature in slot {}".format(i)) from e + raise InvalidSignatureError(f"Invalid signature in slot {i}") from e def header_digest(header: c.Container, hash_function: Callable = blake2s) -> bytes: @@ -498,7 +496,7 @@ def update(client, data): if isinstance(resp, messages.Success): return else: - raise RuntimeError("Unexpected result %s" % resp) + raise RuntimeError(f"Unexpected result {resp}") # TREZORv2 method while isinstance(resp, messages.FirmwareRequest): @@ -509,4 +507,4 @@ def update(client, data): if isinstance(resp, messages.Success): return else: - raise RuntimeError("Unexpected message %s" % resp) + raise RuntimeError(f"Unexpected message {resp}") diff --git a/python/src/trezorlib/log.py b/python/src/trezorlib/log.py index 696a150c3..c60a7152f 100644 --- a/python/src/trezorlib/log.py +++ b/python/src/trezorlib/log.py @@ -39,7 +39,7 @@ class PrettyProtobufFormatter(logging.Formatter): ) if hasattr(record, "protobuf"): if type(record.protobuf) in OMITTED_MESSAGES: - message += " ({} bytes)".format(record.protobuf.ByteSize()) + message += f" ({record.protobuf.ByteSize()} bytes)" else: message += "\n" + protobuf.format_message(record.protobuf) return message diff --git a/python/src/trezorlib/mapping.py b/python/src/trezorlib/mapping.py index 7fb47fa9b..43010f8f6 100644 --- a/python/src/trezorlib/mapping.py +++ b/python/src/trezorlib/mapping.py @@ -42,8 +42,7 @@ def build_map(): def register_message(msg_class): if msg_class.MESSAGE_WIRE_TYPE in map_type_to_class: raise Exception( - "Message for wire type %s is already registered by %s" - % (msg_class.MESSAGE_WIRE_TYPE, get_class(msg_class.MESSAGE_WIRE_TYPE)) + f"Message for wire type {msg_class.MESSAGE_WIRE_TYPE} is already registered by {get_class(msg_class.MESSAGE_WIRE_TYPE)}" ) map_class_to_type[msg_class] = msg_class.MESSAGE_WIRE_TYPE diff --git a/python/src/trezorlib/protobuf.py b/python/src/trezorlib/protobuf.py index bb0bb1ab0..e2dd2aa71 100644 --- a/python/src/trezorlib/protobuf.py +++ b/python/src/trezorlib/protobuf.py @@ -238,7 +238,7 @@ class MessageType(metaclass=_MessageTypeMeta): if value is None or value == []: continue d[key] = value - return "<%s: %s>" % (self.__class__.__name__, d) + return f"<{self.__class__.__name__}: {d}>" def ByteSize(self) -> int: data = BytesIO() @@ -527,11 +527,11 @@ def format_message( output = repr(value) else: output = "0x" + value.hex() - return "{} bytes {}{}".format(length, output, suffix) + return f"{length} bytes {output}{suffix}" if isinstance(value, int) and safe_issubclass(field.type, IntEnum): try: - return "{} ({})".format(field.type(value).name, value) + return f"{field.type(value).name} ({value})" except ValueError: return str(value) diff --git a/python/src/trezorlib/stellar.py b/python/src/trezorlib/stellar.py index 74e3a0585..b664e55d0 100644 --- a/python/src/trezorlib/stellar.py +++ b/python/src/trezorlib/stellar.py @@ -294,7 +294,7 @@ def sign_tx( if not isinstance(resp, messages.StellarSignedTx): raise exceptions.TrezorException( - "Unexpected message: {}".format(resp.__class__.__name__) + f"Unexpected message: {resp.__class__.__name__}" ) if operations: diff --git a/python/src/trezorlib/toif.py b/python/src/trezorlib/toif.py index fd464bed5..49ff8f810 100644 --- a/python/src/trezorlib/toif.py +++ b/python/src/trezorlib/toif.py @@ -77,9 +77,7 @@ class Toif: uncompressed = _decompress(self.data) if len(uncompressed) != expected_size: raise ValueError( - "Uncompressed data is {} bytes, expected {}".format( - len(uncompressed), expected_size - ) + f"Uncompressed data is {len(uncompressed)} bytes, expected {expected_size}" ) def to_image(self) -> "Image": @@ -138,7 +136,7 @@ def from_image(image: "Image", background=(0, 0, 0, 255)) -> Toif: toif_mode = firmware.ToifMode.full_color toif_data = _from_pil_rgb(image.getdata()) else: - raise ValueError("Unsupported image mode: {}".format(image.mode)) + raise ValueError(f"Unsupported image mode: {image.mode}") data = _compress(toif_data) return Toif(toif_mode, image.size, data) diff --git a/python/src/trezorlib/tools.py b/python/src/trezorlib/tools.py index 35fc09f96..8faf143f1 100644 --- a/python/src/trezorlib/tools.py +++ b/python/src/trezorlib/tools.py @@ -209,9 +209,7 @@ class expect: __tracebackhide__ = True # for pytest # pylint: disable=W0612 ret = f(*args, **kwargs) if not isinstance(ret, self.expected): - raise RuntimeError( - "Got %s, expected %s" % (ret.__class__, self.expected) - ) + raise RuntimeError(f"Got {ret.__class__}, expected {self.expected}") if self.field is not None: return getattr(ret, self.field) else: diff --git a/python/src/trezorlib/transport/__init__.py b/python/src/trezorlib/transport/__init__.py index 6e1e6f178..ff7072fad 100644 --- a/python/src/trezorlib/transport/__init__.py +++ b/python/src/trezorlib/transport/__init__.py @@ -93,9 +93,7 @@ class Transport: ): return device - raise TransportException( - "{} device not found: {}".format(cls.PATH_PREFIX, path) - ) + raise TransportException(f"{cls.PATH_PREFIX} device not found: {path}") def all_transports() -> Iterable[Type[Transport]]: @@ -117,13 +115,13 @@ def enumerate_devices() -> Iterable[Transport]: name = transport.__name__ try: found = list(transport.enumerate()) - LOG.info("Enumerating {}: found {} devices".format(name, len(found))) + LOG.info(f"Enumerating {name}: found {len(found)} devices") devices.extend(found) except NotImplementedError: - LOG.error("{} does not implement device enumeration".format(name)) + LOG.error(f"{name} does not implement device enumeration") except Exception as e: excname = e.__class__.__name__ - LOG.error("Failed to enumerate {}. {}: {}".format(name, excname, e)) + LOG.error(f"Failed to enumerate {name}. {excname}: {e}") return devices @@ -149,4 +147,4 @@ def get_transport(path: str = None, prefix_search: bool = False) -> Transport: if transports: return transports[0].find_by_path(path, prefix_search=prefix_search) - raise TransportException("Could not find device by path: {}".format(path)) + raise TransportException(f"Could not find device by path: {path}") diff --git a/python/src/trezorlib/transport/bridge.py b/python/src/trezorlib/transport/bridge.py index df3136f3a..9fc7e0750 100644 --- a/python/src/trezorlib/transport/bridge.py +++ b/python/src/trezorlib/transport/bridge.py @@ -38,8 +38,8 @@ def call_bridge(uri: str, data=None) -> requests.Response: url = TREZORD_HOST + "/" + uri r = CONNECTION.post(url, data=data) if r.status_code != 200: - error_str = "trezord: {} failed with code {}: {}".format( - uri, r.status_code, r.json()["error"] + error_str = ( + f"trezord: {uri} failed with code {r.status_code}: {r.json()['error']}" ) raise TransportException(error_str) return r @@ -64,12 +64,12 @@ class BridgeHandle: class BridgeHandleModern(BridgeHandle): def write_buf(self, buf: bytes) -> None: - LOG.log(DUMP_PACKETS, "sending message: {}".format(buf.hex())) + LOG.log(DUMP_PACKETS, f"sending message: {buf.hex()}") self.transport._call("post", data=buf.hex()) def read_buf(self) -> bytes: data = self.transport._call("read") - LOG.log(DUMP_PACKETS, "received message: {}".format(data.text)) + LOG.log(DUMP_PACKETS, f"received message: {data.text}") return bytes.fromhex(data.text) @@ -87,9 +87,9 @@ class BridgeHandleLegacy(BridgeHandle): if self.request is None: raise TransportException("Can't read without write on legacy Bridge") try: - LOG.log(DUMP_PACKETS, "calling with message: {}".format(self.request)) + LOG.log(DUMP_PACKETS, f"calling with message: {self.request}") data = self.transport._call("call", data=self.request) - LOG.log(DUMP_PACKETS, "received response: {}".format(data.text)) + LOG.log(DUMP_PACKETS, f"received response: {data.text}") return bytes.fromhex(data.text) finally: self.request = None @@ -120,7 +120,7 @@ class BridgeTransport(Transport): self.handle = BridgeHandleModern(self) def get_path(self) -> str: - return "%s:%s" % (self.PATH_PREFIX, self.device["path"]) + return f"{self.PATH_PREFIX}:{self.device['path']}" def find_debug(self) -> "BridgeTransport": if not self.device.get("debug"): diff --git a/python/src/trezorlib/transport/hid.py b/python/src/trezorlib/transport/hid.py index 4dd120a50..e3b41762e 100644 --- a/python/src/trezorlib/transport/hid.py +++ b/python/src/trezorlib/transport/hid.py @@ -28,7 +28,7 @@ LOG = logging.getLogger(__name__) try: import hid except Exception as e: - LOG.info("HID transport is disabled: {}".format(e)) + LOG.info(f"HID transport is disabled: {e}") hid = None @@ -63,7 +63,7 @@ class HidHandle: self.handle.close() self.handle = None raise TransportException( - "Unexpected device {} on path {}".format(serial, self.path.decode()) + f"Unexpected device {serial} on path {self.path.decode()}" ) self.handle.set_nonblocking(True) @@ -80,12 +80,12 @@ class HidHandle: def write_chunk(self, chunk: bytes) -> None: if len(chunk) != 64: - raise TransportException("Unexpected chunk size: %d" % len(chunk)) + raise TransportException(f"Unexpected chunk size: {len(chunk)}") if self.hid_version == 2: chunk = b"\x00" + chunk - LOG.log(DUMP_PACKETS, "writing packet: {}".format(chunk.hex())) + LOG.log(DUMP_PACKETS, f"writing packet: {chunk.hex()}") self.handle.write(chunk) def read_chunk(self) -> bytes: @@ -97,9 +97,9 @@ class HidHandle: else: time.sleep(0.001) - LOG.log(DUMP_PACKETS, "read packet: {}".format(chunk.hex())) + LOG.log(DUMP_PACKETS, f"read packet: {chunk.hex()}") if len(chunk) != 64: - raise TransportException("Unexpected chunk size: %d" % len(chunk)) + raise TransportException(f"Unexpected chunk size: {len(chunk)}") return bytes(chunk) def probe_hid_version(self) -> int: @@ -127,7 +127,7 @@ class HidTransport(ProtocolBasedTransport): super().__init__(protocol=ProtocolV1(self.handle)) def get_path(self) -> str: - return "%s:%s" % (self.PATH_PREFIX, self.device["path"].decode()) + return f"{self.PATH_PREFIX}:{self.device['path'].decode()}" @classmethod def enumerate(cls, debug: bool = False) -> Iterable["HidTransport"]: diff --git a/python/src/trezorlib/transport/udp.py b/python/src/trezorlib/transport/udp.py index 335e19434..fbd7283fc 100644 --- a/python/src/trezorlib/transport/udp.py +++ b/python/src/trezorlib/transport/udp.py @@ -53,7 +53,7 @@ class UdpTransport(ProtocolBasedTransport): def find_debug(self) -> "UdpTransport": host, port = self.device - return UdpTransport("{}:{}".format(host, port + 1)) + return UdpTransport(f"{host}:{port + 1}") @classmethod def _try_path(cls, path: str) -> "UdpTransport": @@ -64,14 +64,14 @@ class UdpTransport(ProtocolBasedTransport): return d else: raise TransportException( - "No Trezor device found at address {}".format(d.get_path()) + f"No Trezor device found at address {d.get_path()}" ) finally: d.close() @classmethod def enumerate(cls) -> Iterable["UdpTransport"]: - default_path = "{}:{}".format(cls.DEFAULT_HOST, cls.DEFAULT_PORT) + default_path = f"{cls.DEFAULT_HOST}:{cls.DEFAULT_PORT}" try: return [cls._try_path(default_path)] except TransportException: @@ -85,7 +85,7 @@ class UdpTransport(ProtocolBasedTransport): # the same type from which `cls` comes from. # Mypy can't handle that though, so here we are. else: - path = path.replace("{}:".format(cls.PATH_PREFIX), "") + path = path.replace(f"{cls.PATH_PREFIX}:", "") return cls._try_path(path) def wait_until_ready(self, timeout: float = 10) -> None: @@ -128,7 +128,7 @@ class UdpTransport(ProtocolBasedTransport): assert self.socket is not None if len(chunk) != 64: raise TransportException("Unexpected data length") - LOG.log(DUMP_PACKETS, "sending packet: {}".format(chunk.hex())) + LOG.log(DUMP_PACKETS, f"sending packet: {chunk.hex()}") self.socket.sendall(chunk) def read_chunk(self) -> bytes: @@ -139,7 +139,7 @@ class UdpTransport(ProtocolBasedTransport): break except socket.timeout: continue - LOG.log(DUMP_PACKETS, "received packet: {}".format(chunk.hex())) + LOG.log(DUMP_PACKETS, f"received packet: {chunk.hex()}") if len(chunk) != 64: - raise TransportException("Unexpected chunk size: %d" % len(chunk)) + raise TransportException(f"Unexpected chunk size: {len(chunk)}") return bytearray(chunk) diff --git a/python/src/trezorlib/transport/webusb.py b/python/src/trezorlib/transport/webusb.py index ba6db9dc3..9873773d8 100644 --- a/python/src/trezorlib/transport/webusb.py +++ b/python/src/trezorlib/transport/webusb.py @@ -29,7 +29,7 @@ LOG = logging.getLogger(__name__) try: import usb1 except Exception as e: - LOG.warning("WebUSB transport is disabled: {}".format(e)) + LOG.warning(f"WebUSB transport is disabled: {e}") usb1 = None INTERFACE = 0 @@ -65,8 +65,8 @@ class WebUsbHandle: def write_chunk(self, chunk: bytes) -> None: assert self.handle is not None if len(chunk) != 64: - raise TransportException("Unexpected chunk size: %d" % len(chunk)) - LOG.log(DUMP_PACKETS, "writing packet: {}".format(chunk.hex())) + raise TransportException(f"Unexpected chunk size: {len(chunk)}") + LOG.log(DUMP_PACKETS, f"writing packet: {chunk.hex()}") self.handle.interruptWrite(self.endpoint, chunk) def read_chunk(self) -> bytes: @@ -78,9 +78,9 @@ class WebUsbHandle: break else: time.sleep(0.001) - LOG.log(DUMP_PACKETS, "read packet: {}".format(chunk.hex())) + LOG.log(DUMP_PACKETS, f"read packet: {chunk.hex()}") if len(chunk) != 64: - raise TransportException("Unexpected chunk size: %d" % len(chunk)) + raise TransportException(f"Unexpected chunk size: {len(chunk)}") return chunk @@ -106,7 +106,7 @@ class WebUsbTransport(ProtocolBasedTransport): super().__init__(protocol=ProtocolV1(handle)) def get_path(self) -> str: - return "%s:%s" % (self.PATH_PREFIX, dev_to_str(self.device)) + return f"{self.PATH_PREFIX}:{dev_to_str(self.device)}" @classmethod def enumerate(cls, usb_reset=False) -> Iterable["WebUsbTransport"]: diff --git a/python/src/trezorlib/ui.py b/python/src/trezorlib/ui.py index f6e26fa80..4b4a05ea0 100644 --- a/python/src/trezorlib/ui.py +++ b/python/src/trezorlib/ui.py @@ -95,7 +95,7 @@ class ClickUI: while True: try: - pin = prompt("Please enter {}".format(desc), hide_input=True) + pin = prompt(f"Please enter {desc}", hide_input=True) except click.Abort: raise Cancelled from None @@ -108,11 +108,7 @@ class ClickUI: "The value may only consist of digits 1 to 9 or letters cvbdfgert." ) elif len(pin) > MAX_PIN_LENGTH: - echo( - "The value must be at most {} digits in length.".format( - MAX_PIN_LENGTH - ) - ) + echo(f"The value must be at most {MAX_PIN_LENGTH} digits in length.") else: return pin diff --git a/python/tools/build_tx.py b/python/tools/build_tx.py index 03ab1dbd6..9e1103428 100755 --- a/python/tools/build_tx.py +++ b/python/tools/build_tx.py @@ -80,7 +80,7 @@ def _get_inputs_interactive(blockbook_url): tx = btc.from_json(tx_json) txes[txhash] = tx amount = tx.bin_outputs[prev_index].amount - echo("Input amount: {}".format(amount)) + echo(f"Input amount: {amount}") sequence = prompt( "Sequence Number to use (RBF opt-in enabled by default)", diff --git a/python/tools/encfs_aes_getpass.py b/python/tools/encfs_aes_getpass.py index 3c654bf79..1c00a6520 100755 --- a/python/tools/encfs_aes_getpass.py +++ b/python/tools/encfs_aes_getpass.py @@ -56,9 +56,9 @@ def choose_device(devices): continue if client.features.label: - sys.stderr.write("[%d] %s\n" % (i, client.features.label)) + sys.stderr.write(f"[{i}] {client.features.label}\n") else: - sys.stderr.write("[%d] \n" % i) + sys.stderr.write(f"[{i}] \n") client.close() i += 1 diff --git a/python/tools/pwd_reader.py b/python/tools/pwd_reader.py index d0b1bee23..07d9e95bf 100755 --- a/python/tools/pwd_reader.py +++ b/python/tools/pwd_reader.py @@ -97,7 +97,7 @@ def getDecryptedNonce(client, entry): if pr.scheme and pr.netloc: item = pr.netloc - ENC_KEY = 'Unlock %s for user %s?' % (item, entry['username']) + ENC_KEY = f"Unlock {item} for user {entry['username']}?" ENC_VALUE = entry['nonce'] decrypted_nonce = misc.decrypt_keyvalue( client, @@ -116,7 +116,7 @@ def printEntries(entries): print('================') print() for k, v in entries.items(): - print('Entry id: #%s' % k) + print(f'Entry id: #{k}') print('-------------') for kk, vv in v.items(): if kk in ['nonce', 'safe_note', 'password']: diff --git a/storage/tests/python/src/storage.py b/storage/tests/python/src/storage.py index bc6e940e5..6fde424e6 100644 --- a/storage/tests/python/src/storage.py +++ b/storage/tests/python/src/storage.py @@ -169,7 +169,7 @@ class Storage: base = int.from_bytes(current[:4], sys.byteorder) tail = helpers.to_int_by_words(current[4:]) - tail_count = "{0:064b}".format(tail).count("0") + tail_count = f"{tail:064b}".count("0") increased_count = base + tail_count + 1 if increased_count > consts.UINT32_MAX: raise RuntimeError("Failed to set value in storage.") diff --git a/tests/burn_tests/burntest_t1.py b/tests/burn_tests/burntest_t1.py index b4b7a91a5..841ecf131 100755 --- a/tests/burn_tests/burntest_t1.py +++ b/tests/burn_tests/burntest_t1.py @@ -71,5 +71,5 @@ if __name__ == "__main__": device.apply_settings(client, label=label) assert client.features.label == label - print("iteration %d" % i) + print(f"iteration {i}") i = i + 1 diff --git a/tests/burn_tests/burntest_t2.py b/tests/burn_tests/burntest_t2.py index 58e7ab5cc..e4667e636 100755 --- a/tests/burn_tests/burntest_t2.py +++ b/tests/burn_tests/burntest_t2.py @@ -81,5 +81,5 @@ if __name__ == "__main__": client.set_input_flow(None) last_pin = new_pin - print("iteration %d" % i) + print(f"iteration {i}") i = i + 1 diff --git a/tests/click_tests/recovery.py b/tests/click_tests/recovery.py index d36285b45..3fc866ab9 100644 --- a/tests/click_tests/recovery.py +++ b/tests/click_tests/recovery.py @@ -51,7 +51,7 @@ def enter_shares(debug, shares: list): assert expected_text in layout.text layout = enter_share(debug, share) remaining -= 1 - expected_text = "RecoveryHomescreen {} more".format(remaining) + expected_text = f"RecoveryHomescreen {remaining} more" assert "You have successfully recovered your wallet" in layout.text diff --git a/tests/conftest.py b/tests/conftest.py index 923713e9c..7f1599a1a 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -38,7 +38,7 @@ def _raw_client(request): return TrezorClientDebugLink(transport, auto_interact=not interact) except Exception as e: request.session.shouldstop = "Failed to communicate with Trezor" - raise RuntimeError("Failed to open debuglink for {}".format(path)) from e + raise RuntimeError(f"Failed to open debuglink for {path}") from e else: devices = enumerate_devices() diff --git a/tests/device_tests/test_msg_getaddress.py b/tests/device_tests/test_msg_getaddress.py index 7eaf8d1c9..af1a9b81b 100644 --- a/tests/device_tests/test_msg_getaddress.py +++ b/tests/device_tests/test_msg_getaddress.py @@ -118,7 +118,7 @@ class TestMsgGetaddress: def test_multisig(self, client): xpubs = [] for n in range(1, 4): - node = btc.get_public_node(client, parse_path("44'/0'/%d'" % n)) + node = btc.get_public_node(client, parse_path(f"44'/0'/{n}'")) xpubs.append(node.xpub) for nr in range(1, 4): @@ -126,7 +126,7 @@ class TestMsgGetaddress: btc.get_address( client, "Bitcoin", - parse_path("44'/0'/%d'/0/0" % nr), + parse_path(f"44'/0'/{nr}'/0/0"), show_display=(nr == 1), multisig=getmultisig(0, 0, xpubs=xpubs), ) @@ -136,7 +136,7 @@ class TestMsgGetaddress: btc.get_address( client, "Bitcoin", - parse_path("44'/0'/%d'/1/0" % nr), + parse_path(f"44'/0'/{nr}'/1/0"), show_display=(nr == 1), multisig=getmultisig(1, 0, xpubs=xpubs), ) @@ -150,7 +150,7 @@ class TestMsgGetaddress: # Use account numbers 1, 2 and 3 to create a valid multisig, # but not containing the keys from account 0 used below. nodes = [ - btc.get_public_node(client, parse_path("44'/0'/%d'" % i)).node + btc.get_public_node(client, parse_path(f"44'/0'/{i}'")).node for i in range(1, 4) ] multisig1 = messages.MultisigRedeemScriptType( @@ -188,7 +188,7 @@ class TestMsgGetaddress: xpubs = [] for n in range(1, 4): node = btc.get_public_node( - client, parse_path("44'/145'/%d'" % n), coin_name="Bcash" + client, parse_path(f"44'/145'/{n}'"), coin_name="Bcash" ) xpubs.append(node.xpub) @@ -197,7 +197,7 @@ class TestMsgGetaddress: btc.get_address( client, "Bcash", - parse_path("44'/145'/%d'/0/0" % nr), + parse_path(f"44'/145'/{nr}'/0/0"), show_display=(nr == 1), multisig=getmultisig(0, 0, xpubs=xpubs), ) @@ -207,7 +207,7 @@ class TestMsgGetaddress: btc.get_address( client, "Bcash", - parse_path("44'/145'/%d'/1/0" % nr), + parse_path(f"44'/145'/{nr}'/1/0"), show_display=(nr == 1), multisig=getmultisig(1, 0, xpubs=xpubs), ) diff --git a/tests/device_tests/test_msg_getaddress_segwit.py b/tests/device_tests/test_msg_getaddress_segwit.py index 743523435..74d8f38d7 100644 --- a/tests/device_tests/test_msg_getaddress_segwit.py +++ b/tests/device_tests/test_msg_getaddress_segwit.py @@ -97,7 +97,7 @@ class TestMsgGetaddressSegwit: def test_show_multisig_3(self, client): nodes = [ btc.get_public_node( - client, parse_path("49'/1'/%d'" % i), coin_name="Testnet" + client, parse_path(f"49'/1'/{i}'"), coin_name="Testnet" ).node for i in range(1, 4) ] @@ -130,7 +130,7 @@ class TestMsgGetaddressSegwit: # Use account numbers 1, 2 and 3 to create a valid multisig, # but not containing the keys from account 0 used below. nodes = [ - btc.get_public_node(client, parse_path("49'/0'/%d'" % i)).node + btc.get_public_node(client, parse_path(f"49'/0'/{i}'")).node for i in range(1, 4) ] multisig1 = proto.MultisigRedeemScriptType( diff --git a/tests/device_tests/test_msg_getaddress_segwit_native.py b/tests/device_tests/test_msg_getaddress_segwit_native.py index 6611fd67a..9b567679d 100644 --- a/tests/device_tests/test_msg_getaddress_segwit_native.py +++ b/tests/device_tests/test_msg_getaddress_segwit_native.py @@ -82,7 +82,7 @@ def test_show_segwit(client, show_display, coin, path, script_type, address): def test_show_multisig_3(client): nodes = [ btc.get_public_node( - client, parse_path("84'/1'/%d'" % index), coin_name="Testnet" + client, parse_path(f"84'/1'/{index}'"), coin_name="Testnet" ).node for index in range(1, 4) ] @@ -97,7 +97,7 @@ def test_show_multisig_3(client): btc.get_address( client, "Testnet", - parse_path("84'/1'/%d'/0/1" % i), + parse_path(f"84'/1'/{i}'/0/1"), False, multisig2, script_type=proto.InputScriptType.SPENDWITNESS, @@ -108,7 +108,7 @@ def test_show_multisig_3(client): btc.get_address( client, "Testnet", - parse_path("84'/1'/%d'/0/0" % i), + parse_path(f"84'/1'/{i}'/0/0"), False, multisig1, script_type=proto.InputScriptType.SPENDWITNESS, @@ -124,7 +124,7 @@ def test_multisig_missing(client, show_display): # Use account numbers 1, 2 and 3 to create a valid multisig, # but not containing the keys from account 0 used below. nodes = [ - btc.get_public_node(client, parse_path("84'/0'/%d'" % i)).node + btc.get_public_node(client, parse_path(f"84'/0'/{i}'")).node for i in range(1, 4) ] multisig1 = proto.MultisigRedeemScriptType( diff --git a/tests/device_tests/test_msg_getentropy.py b/tests/device_tests/test_msg_getentropy.py index 6e8552e91..858ca1971 100644 --- a/tests/device_tests/test_msg_getentropy.py +++ b/tests/device_tests/test_msg_getentropy.py @@ -45,4 +45,4 @@ def test_entropy(client, entropy_length): ) ent = misc.get_entropy(client, entropy_length) assert len(ent) == entropy_length - print("{} bytes: entropy = {}".format(entropy_length, entropy(ent))) + print(f"{entropy_length} bytes: entropy = {entropy(ent)}") diff --git a/tests/device_tests/test_msg_getownershipproof.py b/tests/device_tests/test_msg_getownershipproof.py index 0eb90f44a..3e00beca1 100644 --- a/tests/device_tests/test_msg_getownershipproof.py +++ b/tests/device_tests/test_msg_getownershipproof.py @@ -41,7 +41,7 @@ def test_attack_ownership_id(client): # Use account numbers 1, 2 and 3 to create a valid multisig, # but not containing the keys from account 0 used below. nodes = [ - btc.get_public_node(client, parse_path("84'/0'/%d'" % i)).node + btc.get_public_node(client, parse_path(f"84'/0'/{i}'")).node for i in range(1, 4) ] multisig1 = messages.MultisigRedeemScriptType( diff --git a/tests/ui_tests/__init__.py b/tests/ui_tests/__init__.py index 013241f11..db3eb175a 100644 --- a/tests/ui_tests/__init__.py +++ b/tests/ui_tests/__init__.py @@ -84,9 +84,10 @@ def _process_tested(fixture_test_path, test_name): ) pytest.fail( - "Hash of {} differs.\nExpected: {}\nActual: {}\nDiff file: {}".format( - test_name, expected_hash, actual_hash, file_path - ) + f"Hash of {test_name} differs.\n" + f"Expected: {expected_hash}\n" + f"Actual: {actual_hash}\n" + f"Diff file: {file_path}" ) else: testreport.passed(fixture_test_path, test_name, actual_hash) diff --git a/tests/ui_tests/reporting/download.py b/tests/ui_tests/reporting/download.py index dbf0977ef..f78902c50 100644 --- a/tests/ui_tests/reporting/download.py +++ b/tests/ui_tests/reporting/download.py @@ -26,7 +26,7 @@ def fetch_recorded(hash, path): try: urllib.request.urlretrieve(zip_src, zip_dest) except urllib.error.HTTPError: - raise RuntimeError("No such recorded collection was found on '%s'." % zip_src) + raise RuntimeError(f"No such recorded collection was found on '{zip_src}'.") except urllib.error.URLError: _dns_failed = True raise RuntimeError( diff --git a/tests/upgrade_tests/test_firmware_upgrades.py b/tests/upgrade_tests/test_firmware_upgrades.py index 4fd870ef1..7b4fa888f 100644 --- a/tests/upgrade_tests/test_firmware_upgrades.py +++ b/tests/upgrade_tests/test_firmware_upgrades.py @@ -360,6 +360,6 @@ if __name__ == "__main__": if not ALL_TAGS: print("No versions found. Remember to run download_emulators.sh") for k, v in ALL_TAGS.items(): - print("Found versions for {}:".format(k), v) + print(f"Found versions for {k}: {v}") print() - print("Use `pytest {}` to run tests".format(__file__)) + print(f"Use `pytest {__file__}` to run tests") diff --git a/tools/bump-version.py b/tools/bump-version.py index 6ce24ce61..cfd974a74 100755 --- a/tools/bump-version.py +++ b/tools/bump-version.py @@ -18,7 +18,7 @@ def bump_header(filename, **kwargs): m = HEADER_LINE_RE.match(line) if m is not None and m[1] in kwargs: symbol = m[1] - result_lines.append("#define {0} {1}\n".format(symbol, kwargs[symbol])) + result_lines.append(f"#define {symbol} {kwargs[symbol]}\n") else: result_lines.append(line) diff --git a/tools/generate-changelog.py b/tools/generate-changelog.py index 966010a72..1f97edf9c 100755 --- a/tools/generate-changelog.py +++ b/tools/generate-changelog.py @@ -122,7 +122,7 @@ def cli(project, version, date, check): changelog = project / "CHANGELOG.md" if not changelog.exists(): - raise click.ClickException("{} not found".format(changelog)) + raise click.ClickException(f"{changelog} not found") if version is None: if not check: diff --git a/tools/github_issues_to_csv.py b/tools/github_issues_to_csv.py index e809d370f..015f17adb 100644 --- a/tools/github_issues_to_csv.py +++ b/tools/github_issues_to_csv.py @@ -71,14 +71,14 @@ def write_issues(r, csvout): def get_issues(name): """Requests issues from GitHub API and writes to CSV file.""" - url = "https://api.github.com/repos/{}/issues?state=all".format(name) + url = f"https://api.github.com/repos/{name}/issues?state=all" if token is not None: headers = {"Authorization": "token " + token} else: headers = None r = requests.get(url, headers=headers) - csvfilename = "{}-issues.csv".format(name.replace("/", "-")) + csvfilename = f"{name.replace('/', '-')}-issues.csv" with open(csvfilename, "w", newline="") as csvfile: csvout = csv.writer(csvfile) csvout.writerow(