From f4d27a43609b401317b8d07c082ac058a7e57219 Mon Sep 17 00:00:00 2001 From: PiRK Date: Thu, 12 Jan 2023 10:34:57 +0100 Subject: [PATCH 1/9] =?UTF-8?q?[flake8]=20fix=20E266=20errors=20(too=20man?= =?UTF-8?q?y=20leading=20=E2=80=98#=E2=80=99=20for=20block=20comment)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .pre-commit-config.yaml | 2 +- contrib/package_plugin.py | 4 ---- electrumabc/bitcoin.py | 8 ++++---- electrumabc/paymentrequest.py | 10 +++++----- electrumabc/ripemd.py | 16 ++++++++-------- electrumabc/schnorr.py | 5 +++-- electrumabc/slp/slp.py | 2 +- electrumabc_plugins/fusion/fusion.py | 17 +++++++++-------- electrumabc_plugins/fusion/protocol.py | 5 +++-- 9 files changed, 34 insertions(+), 35 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index ef30ea204f05..a010f81aef73 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -26,7 +26,7 @@ repos: args: - --max-line-length=88 - --select=E1,E2,E3,E4,E5,E7,E9,F4,F5,F6,F7,F8,W1,W2,W3,W504,W6 - - --ignore=E266,E501,E722,E731,E741 # FIXME + - --ignore=E501,E722,E731,E741 # FIXME - --extend-ignore=E203 # This one is incompatible with black additional_dependencies: - flake8-mutable diff --git a/contrib/package_plugin.py b/contrib/package_plugin.py index 14c707b66872..e1dbc4afaa26 100755 --- a/contrib/package_plugin.py +++ b/contrib/package_plugin.py @@ -46,14 +46,10 @@ from PyQt5.QtCore import Qt -## Start copied from .util def versiontuple(v): return tuple(map(int, (v.split(".")))) -## End copied from .util - - def write_plugin_archive(metadata, source_package_path, archive_file_path): suffixless_path = archive_file_path.strip() # Ensure we don't end up with .zip.zip, as `make_archive` adds the suffix as well. diff --git a/electrumabc/bitcoin.py b/electrumabc/bitcoin.py index 412e6528f014..ec0c2d84796a 100644 --- a/electrumabc/bitcoin.py +++ b/electrumabc/bitcoin.py @@ -75,7 +75,7 @@ do_monkey_patching_of_python_ecdsa_internals_with_libsecp256k1() -################################## transactions +# transactions FEE_STEP = 10000 @@ -486,7 +486,7 @@ def i2o_ECPublicKey(pubkey, compressed=False): # end pywallet openssl private key implementation -############ functions from pywallet ##################### +# functions from pywallet def hash_160(public_key: bytes) -> bytes: sha256_hash = sha256(public_key) try: @@ -749,7 +749,7 @@ def is_private_key(key, *, net=None): return False -########### end pywallet functions ####################### +# end pywallet functions def is_minikey(text): @@ -1027,7 +1027,7 @@ def decrypt_message(self, encrypted, magic=b"BIE1"): return aes_decrypt_with_iv(key_e, iv, ciphertext) -###################################### BIP32 ############################## +# BIP32 random_seed = lambda n: "%032x" % ecdsa.util.randrange(pow(2, n)) BIP32_PRIME = 0x80000000 diff --git a/electrumabc/paymentrequest.py b/electrumabc/paymentrequest.py index 37960820b1a7..bba173876b9f 100644 --- a/electrumabc/paymentrequest.py +++ b/electrumabc/paymentrequest.py @@ -223,7 +223,7 @@ def verify_x509(self, paymntreq): if not verify: self.error = "ERROR: Invalid Signature for Payment Request Data" return False - ### SIG Verified + # SIG Verified self.error = "Signed by Trusted CA: " + ca.get_common_name() return True @@ -934,10 +934,10 @@ def verify(self, contacts, *, timeout=10.0): self.print_error(self.error) return False - ### SIG Verified - self.error = ( - "Signed by: " + owner - ) # <--- This is not ideal because we re-use self.error for a *non-error* but the superclass API is this way. -Calin + # SIG Verified + # This is not ideal because we re-use self.error for a *non-error* but the + # superclass API is this way. -Calin + self.error = "Signed by: " + owner return True def verify_x509(self, paymntreq): diff --git a/electrumabc/ripemd.py b/electrumabc/ripemd.py index 8cfcbb63d4ae..000f0d986242 100644 --- a/electrumabc/ripemd.py +++ b/electrumabc/ripemd.py @@ -1,11 +1,11 @@ -## ripemd.py - pure Python implementation of the RIPEMD-160 algorithm. -## Bjorn Edstrom 16 december 2007. -## -## Copyrights -## ========== -## -## This code is a derived from an implementation by Markus Friedl which is -## subject to the following license. This Python implementation is not +# ripemd.py - pure Python implementation of the RIPEMD-160 algorithm. +# Bjorn Edstrom 16 december 2007. +# +# Copyrights +# ========== +# +# This code is a derived from an implementation by Markus Friedl which is +# subject to the following license. This Python implementation is not # subject to any other license. # # diff --git a/electrumabc/schnorr.py b/electrumabc/schnorr.py index d3fa8fa41df3..a93273175002 100644 --- a/electrumabc/schnorr.py +++ b/electrumabc/schnorr.py @@ -238,8 +238,9 @@ def verify(pubkey, signature, message_hash): raise ValueError("pubkey could not be parsed") rbytes = signature[:32] - ## these unnecessary since below we do bytes comparison and - ## R.x() is always < fieldsize. + # these unnecessary since below we do bytes comparison and + # R.x() is always < fieldsize. + # # r = int.from_bytes(rbytes, 'big') # if r >= fieldsize: # return False diff --git a/electrumabc/slp/slp.py b/electrumabc/slp/slp.py index f40be80fc88c..e1ac5cd3b126 100644 --- a/electrumabc/slp/slp.py +++ b/electrumabc/slp/slp.py @@ -460,7 +460,7 @@ def _is_valid_or_raise(self) -> bool: if self.decimals > 9: raise InvalidOutputMessage("Too many decimals") - ## handle baton for additional minting, but may be empty + # handle baton for additional minting, but may be empty v = self.mint_baton_vout if v is not None and v < 2: raise InvalidOutputMessage("Mint baton cannot be on vout=0 or 1") diff --git a/electrumabc_plugins/fusion/fusion.py b/electrumabc_plugins/fusion/fusion.py index 7d4a0bcff9b9..a33ed869d9a2 100644 --- a/electrumabc_plugins/fusion/fusion.py +++ b/electrumabc_plugins/fusion/fusion.py @@ -587,7 +587,7 @@ def recv(self, *expected_msg_names, timeout=None): def send(self, submsg, timeout=None): send_pb(self.connection, pb.ClientMessage, submsg, timeout=timeout) - ## Rough phases of protocol + # Rough phases of protocol def greet( self, @@ -673,7 +673,8 @@ def allocate_outputs( tier_outputs = {} excess_fees = {} for scale in self.available_tiers: - ### Fuzzing fee range selection ### + # Fuzzing fee range selection + # # To keep privacy at higher tiers, we need to randomize our input-output # linkage somehow, which means throwing away some sats as extra fees beyond # the minimum requirement. @@ -682,8 +683,8 @@ def allocate_outputs( # randomly overpaying fees of 0 to 1000 sats. fuzz_fee_max = scale // 1000000 - ### End fuzzing fee range selection ### - + # End fuzzing fee range selection + # # Now choose a random fuzz fee. Uniform random is best for obfuscation. # But before we do, there is a maximum fuzzing fee that is admitted by server, and # a safety maximum that we have ourselves. @@ -743,7 +744,7 @@ def register_and_wait( selffuse = Conf(wallet).self_fuse_players tags.append(pb.JoinPools.PoolTag(id=wallet.cashfusion_tag, limit=selffuse)) - ## Join waiting pools + # Join waiting pools self.check_stop(running=False) self.check_coins() self.send(pb.JoinPools(tiers=tiers_sorted, tags=tags)) @@ -1042,7 +1043,7 @@ def run_round(self, covert): covert.check_connected() self.check_coins() - ### Start covert component submissions + # Start covert component submissions self.print_error("starting covert component submission") self.status = ("running", "covert submission: components") @@ -1107,7 +1108,7 @@ def run_round(self, covert): if msg.HasField("session_hash") and msg.session_hash != session_hash: raise FusionError("Session hash mismatch (bug!)") - ### Start covert signature submissions (or skip) + # Start covert signature submissions (or skip) if not skip_signatures: self.print_error("starting covert signature submission") @@ -1248,7 +1249,7 @@ def update_wallet_label_in_main_thread_paranoia(wallets, txid, label): else: # skip_signatures True bad_components = set() - ### Blame phase ### + # Blame phase covert.set_stop_time(covert_T0 + Protocol.T_START_CLOSE_BLAME) self.print_error("sending proofs") diff --git a/electrumabc_plugins/fusion/protocol.py b/electrumabc_plugins/fusion/protocol.py index 8206b41ed7b7..543ec4c8f6a7 100644 --- a/electrumabc_plugins/fusion/protocol.py +++ b/electrumabc_plugins/fusion/protocol.py @@ -64,7 +64,8 @@ class Protocol: 5.0 # how much the server's time is allowed to differ from client ) - ### Critical timeline ### + # Critical timeline + # # (For early phases in a round) # For client privacy, it is critical that covert submissions happen within # very specific windows so that they know the server is not able to pull @@ -113,7 +114,7 @@ class Protocol: T_START_CLOSE = +45.0 # before conclusion T_START_CLOSE_BLAME = +80.0 # after conclusion, during blame phase. - ### (End critical timeline) ### + # (End critical timeline) # For non-critical messages like during blame phase, just regular relative timeouts are needed. # Note that when clients send a result and expect a 'gathered' response from server, they wait From 291a86a0f5fa94488eb5e095534c6c5f6dd86e37 Mon Sep 17 00:00:00 2001 From: PiRK Date: Thu, 12 Jan 2023 13:23:40 +0100 Subject: [PATCH 2/9] =?UTF-8?q?[flake8]=20fix=20E741=20errors=20(do=20not?= =?UTF-8?q?=20use=20variables=20named=20=E2=80=98l=E2=80=99,=20=E2=80=98O?= =?UTF-8?q?=E2=80=99,=20or=20=E2=80=98I=E2=80=99)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .pre-commit-config.yaml | 4 +- electrumabc/avalanche/delegation.py | 6 +-- electrumabc/bitcoin.py | 22 ++++----- electrumabc/blockchain.py | 6 +-- electrumabc/commands.py | 20 ++++---- electrumabc/consolidate.py | 3 +- electrumabc/contacts.py | 6 +-- electrumabc/interface.py | 12 ++--- electrumabc/network.py | 6 +-- electrumabc/paymentrequest.py | 12 ++--- electrumabc/plugins.py | 12 +++-- electrumabc/qrreaders/zbar.py | 10 ++-- electrumabc/utils/macos.py | 17 +++---- electrumabc/wallet.py | 59 ++++++++++++------------ electrumabc/websockets.py | 16 +++---- electrumabc_gui/qt/console.py | 4 +- electrumabc_gui/qt/exception_window.py | 12 ++--- electrumabc_gui/qt/main_window.py | 50 ++++++++++---------- electrumabc_gui/qt/scan_beyond_gap.py | 14 +++--- electrumabc_gui/qt/transaction_dialog.py | 24 +++++----- electrumabc_gui/qt/util.py | 10 ++-- electrumabc_gui/text.py | 6 +-- electrumabc_plugins/cosigner_pool/qt.py | 8 ++-- electrumabc_plugins/fusion/plugin.py | 2 +- electrumabc_plugins/hw_wallet/qt.py | 4 +- electrumabc_plugins/labels/qt.py | 26 ++++++----- electrumabc_plugins/ledger/qt.py | 4 +- electrumabc_plugins/trezor/trezor.py | 7 +-- 28 files changed, 193 insertions(+), 189 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index a010f81aef73..3dd0d1d03eb3 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -26,7 +26,7 @@ repos: args: - --max-line-length=88 - --select=E1,E2,E3,E4,E5,E7,E9,F4,F5,F6,F7,F8,W1,W2,W3,W504,W6 - - --ignore=E501,E722,E731,E741 # FIXME + - --ignore=E501,E722,E731 # FIXME - --extend-ignore=E203 # This one is incompatible with black additional_dependencies: - flake8-mutable @@ -34,7 +34,7 @@ repos: - id: flake8 args: - --max-line-length=88 - - --ignore=E203,E501,E731,E741,W503,SIM106,SIM119,FS002,FS003 + - --ignore=E203,E501,E731,W503,SIM106,SIM119,FS002,FS003 additional_dependencies: - flake8-comprehensions - flake8-mutable diff --git a/electrumabc/avalanche/delegation.py b/electrumabc/avalanche/delegation.py index 9977bd4127f6..913aacad679f 100644 --- a/electrumabc/avalanche/delegation.py +++ b/electrumabc/avalanche/delegation.py @@ -198,9 +198,9 @@ def from_proof(cls, p: Proof) -> DelegationBuilder: @classmethod def from_delegation(cls, dg: Delegation) -> DelegationBuilder: dg_builder = cls(dg.limited_proofid, dg.proof_master, dg.dgid) - for l in dg.levels: - dg_builder.levels[-1].sig = l.sig - dg_builder.levels.append(Level(l.pubkey, b"")) + for level in dg.levels: + dg_builder.levels[-1].sig = level.sig + dg_builder.levels.append(Level(level.pubkey, b"")) return dg_builder def add_level(self, delegator_key: Key, delegated_pubkey: PublicKey): diff --git a/electrumabc/bitcoin.py b/electrumabc/bitcoin.py index ec0c2d84796a..5b56967f84f1 100644 --- a/electrumabc/bitcoin.py +++ b/electrumabc/bitcoin.py @@ -825,10 +825,6 @@ def encrypt_message(message, pubkey, magic=b"BIE1"): return EC_KEY.encrypt_message(message, bfh(pubkey), magic) -def chunks(l, n): - return [l[i : i + n] for i in range(0, len(l), n)] - - def ECC_YfromX(x, curved=curve_secp256k1, odd=True): _p = curved.p() _a = curved.a() @@ -1060,11 +1056,11 @@ def _CKD_priv(k, c, s, is_prime): keypair = EC_KEY(k) cK = GetPubKey(keypair.pubkey, True) data = bytes([0]) + k + s if is_prime else cK + s - I = hmac.new(c, data, hashlib.sha512).digest() + I_ = hmac.new(c, data, hashlib.sha512).digest() k_n = number_to_string( - (string_to_number(I[0:32]) + string_to_number(k)) % order, order + (string_to_number(I_[0:32]) + string_to_number(k)) % order, order ) - c_n = I[32:] + c_n = I_[32:] return k_n, c_n @@ -1082,11 +1078,11 @@ def CKD_pub(cK, c, n): # helper function, callable with arbitrary string def _CKD_pub(cK, c, s): - I = hmac.new(c, cK + s, hashlib.sha512).digest() + I_ = hmac.new(c, cK + s, hashlib.sha512).digest() curve = SECP256k1 - pubkey_point = string_to_number(I[0:32]) * curve.generator + ser_to_point(cK) + pubkey_point = string_to_number(I_[0:32]) * curve.generator + ser_to_point(cK) public_key = ecdsa.VerifyingKey.from_public_point(pubkey_point, curve=SECP256k1) - c_n = I[32:] + c_n = I_[32:] cK_n = GetPubKey(public_key.pubkey, True) return cK_n, c_n @@ -1239,9 +1235,9 @@ def xpub_from_xprv(xprv, *, net=None): def bip32_root(seed, xtype, *, net=None): if net is None: net = networks.net - I = hmac.new(b"Bitcoin seed", seed, hashlib.sha512).digest() - master_k = I[0:32] - master_c = I[32:] + I_ = hmac.new(b"Bitcoin seed", seed, hashlib.sha512).digest() + master_k = I_[0:32] + master_c = I_[32:] K, cK = get_pubkeys_from_secret(master_k) xprv = serialize_xprv(xtype, master_c, master_k, net=net) xpub = serialize_xpub(xtype, master_c, cK, net=net) diff --git a/electrumabc/blockchain.py b/electrumabc/blockchain.py index de0c4c26746d..871a2834397c 100644 --- a/electrumabc/blockchain.py +++ b/electrumabc/blockchain.py @@ -173,9 +173,9 @@ def read_blockchains(config): fdir = os.path.join(util.get_headers_dir(config), "forks") if not os.path.exists(fdir): os.mkdir(fdir) - l = filter(lambda x: x.startswith("fork_"), os.listdir(fdir)) - l = sorted(l, key=lambda x: int(x.split("_")[1])) - for filename in l: + fork_filenames = filter(lambda x: x.startswith("fork_"), os.listdir(fdir)) + fork_filenames = sorted(fork_filenames, key=lambda x: int(x.split("_")[1])) + for filename in fork_filenames: parent_base_height = int(filename.split("_")[1]) base_height = int(filename.split("_")[2]) b = Blockchain(config, base_height, parent_base_height) diff --git a/electrumabc/commands.py b/electrumabc/commands.py index 9fab6fe423c1..67a4a4c44efc 100644 --- a/electrumabc/commands.py +++ b/electrumabc/commands.py @@ -171,10 +171,10 @@ def _EnsureDictNamedTuplesAreJSONSafe(d): See issue #638""" def DoChk(v): - def ChkList(l): - for i in range(0, len(l)): - l[i] = DoChk(l[i]) # recurse - return l + def ChkList(l_): + for i in range(0, len(l_)): + l_[i] = DoChk(l_[i]) # recurse + return l_ def EncodeNamedTupleObject(nt): if hasattr(nt, "to_ui_string"): @@ -386,12 +386,12 @@ def getaddresshistory(self, address): def listunspent(self): """List unspent outputs. Returns the list of unspent transaction outputs in your wallet.""" - l = self.wallet.get_utxos(exclude_frozen=False) - for i in l: - v = i["value"] - i["value"] = str(PyDecimal(v) / CASH) if v is not None else None - i["address"] = i["address"].to_ui_string() - return l + coins = self.wallet.get_utxos(exclude_frozen=False) + for coin in coins: + if coin["value"] is not None: + coin["value"] = str(PyDecimal(coin["value"]) / CASH) + coin["address"] = coin["address"].to_ui_string() + return coins @command("n") def getaddressunspent(self, address): diff --git a/electrumabc/consolidate.py b/electrumabc/consolidate.py index a71db193f36d..9bf057a336d0 100644 --- a/electrumabc/consolidate.py +++ b/electrumabc/consolidate.py @@ -89,8 +89,7 @@ def __init__( self.txin_type = wallet_instance.get_txin_type(address) self.received = {} for tx_hash, height in wallet_instance.get_address_history(address): - l = self.wallet.txo.get(tx_hash, {}).get(address, []) - for n, v, is_cb in l: + for n, v, is_cb in self.wallet.txo.get(tx_hash, {}).get(address, []): self.received[tx_hash + f":{n}"] = (height, v, is_cb) if isinstance(self.wallet, wallet.ImportedAddressWallet): diff --git a/electrumabc/contacts.py b/electrumabc/contacts.py index 765b260c2a6f..94af1e094820 100644 --- a/electrumabc/contacts.py +++ b/electrumabc/contacts.py @@ -68,8 +68,8 @@ def load(self): @staticmethod def _load_from_dict_like_object(storage) -> List[Contact]: assert callable(getattr(storage, "get", None)) - l = storage.get("contacts2") - v2_was_missing = not isinstance(l, list) + contacts_list = storage.get("contacts2") + v2_was_missing = not isinstance(contacts_list, list) # Check if v2 missing but v1 available. If so, load v1 data. # Next time save() is called, wallet storage will have v2 data # and this branch will be ignored. @@ -80,7 +80,7 @@ def _load_from_dict_like_object(storage) -> List[Contact]: # if we get here, neither v1 nor v2 was found, return empty list return [] - return Contacts._load_v2_list(l) + return Contacts._load_v2_list(contacts_list) @staticmethod def _load_v2_list(in_list): diff --git a/electrumabc/interface.py b/electrumabc/interface.py index 3688bf015de5..1d04dea4b981 100644 --- a/electrumabc/interface.py +++ b/electrumabc/interface.py @@ -98,7 +98,7 @@ def check_host_name(self, peercert, name) -> bool: def get_simple_socket(self): try: - l = socket.getaddrinfo( + addr_info = socket.getaddrinfo( self.host, self.port, socket.AF_UNSPEC, socket.SOCK_STREAM ) except OverflowError: @@ -112,7 +112,7 @@ def get_simple_socket(self): self.print_error("hostname cannot be decoded with 'idna' codec") return e = None - for res in l: + for res in addr_info: try: s = socket.socket(res[0], socket.SOCK_STREAM) s.settimeout(10) @@ -408,12 +408,12 @@ def get_req_throttle_params(cls, config): def set_req_throttle_params(cls, config, max=None, chunkSize=None): if not config: return - l = list(cls.get_req_throttle_params(config)) + l_ = list(cls.get_req_throttle_params(config)) if max is not None: - l[0] = max + l_[0] = max if chunkSize is not None: - l[1] = chunkSize - config.set_key("network_unanswered_requests_throttle", l) + l_[1] = chunkSize + config.set_key("network_unanswered_requests_throttle", l_) def num_requests(self): """If there are more than tup.max (default: 2000) unanswered requests, diff --git a/electrumabc/network.py b/electrumabc/network.py index 074d985b05e5..e338f40d990f 100644 --- a/electrumabc/network.py +++ b/electrumabc/network.py @@ -1073,9 +1073,9 @@ def process_pending_sends(self): if method.endswith(".subscribe"): k = self.get_index(method, params) # add callback to list - l = self.subscriptions[k] # <-- it's a defaultdict(list) - if callback not in l: - l.append(callback) + subsc = self.subscriptions[k] # <-- it's a defaultdict(list) + if callback not in subsc: + subsc.append(callback) # check cached response for subscriptions r = self.sub_cache.get(k) if r is not None: diff --git a/electrumabc/paymentrequest.py b/electrumabc/paymentrequest.py index bba173876b9f..70edc0ffed74 100644 --- a/electrumabc/paymentrequest.py +++ b/electrumabc/paymentrequest.py @@ -582,17 +582,17 @@ def import_file(self, path): self.save() def save(self): - l = {} + invoices = {} for k, pr in self.invoices.items(): - l[k] = { + invoices[k] = { "hex": bh2u(pr.serialize()), "requestor": pr.requestor, "txid": pr.tx, } - self.storage.put("invoices2", l) - self.storage.put( - "invoices", None - ) # delete old invoice format to save space; caveat: older EC versions will not see invoices saved by newer versions anymore. + self.storage.put("invoices2", invoices) + # delete old invoice format to save space; caveat: older EC versions will not + # see invoices saved by newer versions anymore. + self.storage.put("invoices", None) def get_status(self, key): pr = self.get(key) diff --git a/electrumabc/plugins.py b/electrumabc/plugins.py index 9c7c2e42ea1d..989bb2880fdc 100644 --- a/electrumabc/plugins.py +++ b/electrumabc/plugins.py @@ -757,14 +757,16 @@ def __str__(self): def close(self): # remove self from hooks for name, func in self._hooks_i_registered: - l = hooks.get(name, []) + hooks_for_name = hooks.get(name, []) try: - l.remove((self, func)) + hooks_for_name.remove((self, func)) except ValueError: - pass # this should never happen but it pays to be paranoid. - if not l: + # this should never happen but it pays to be paranoid. + pass + if not hooks_for_name: hooks.pop(name, None) - self._hooks_i_registered.clear() # just to kill strong refs to self ASAP, for GC + # just to kill strong refs to self ASAP, for GC + self._hooks_i_registered.clear() # remove registered daemon commands for cmdname in self._daemon_commands: self.parent.daemon_commands.pop(cmdname, None) diff --git a/electrumabc/qrreaders/zbar.py b/electrumabc/qrreaders/zbar.py index 54681efe9e05..9c621a637b09 100644 --- a/electrumabc/qrreaders/zbar.py +++ b/electrumabc/qrreaders/zbar.py @@ -190,23 +190,23 @@ def read_qr_code( symbol_data_bytes = ctypes.string_at(symbol_data_ptr, symbol_data_len) symbol_data = symbol_data_bytes.decode("utf-8") - symbol_loc = [] + symbol_locs = [] symbol_loc_len = LIBZBAR.zbar_symbol_get_loc_size(symbol) for i in range(0, symbol_loc_len): # Normalize the coordinates into 0..1 range by dividing by width / height symbol_loc_x = LIBZBAR.zbar_symbol_get_loc_x(symbol, i) symbol_loc_y = LIBZBAR.zbar_symbol_get_loc_y(symbol, i) - symbol_loc.append((symbol_loc_x, symbol_loc_y)) + symbol_locs.append((symbol_loc_x, symbol_loc_y)) # Find the center by getting the average values of the corners x and y coordinates - symbol_loc_sum_x = sum([l[0] for l in symbol_loc]) - symbol_loc_sum_y = sum([l[1] for l in symbol_loc]) + symbol_loc_sum_x = sum([loc[0] for loc in symbol_locs]) + symbol_loc_sum_y = sum([loc[1] for loc in symbol_locs]) symbol_loc_center = ( int(symbol_loc_sum_x / symbol_loc_len), int(symbol_loc_sum_y / symbol_loc_len), ) - res.append(QrCodeResult(symbol_data, symbol_loc_center, symbol_loc)) + res.append(QrCodeResult(symbol_data, symbol_loc_center, symbol_locs)) symbol = LIBZBAR.zbar_symbol_next(symbol) diff --git a/electrumabc/utils/macos.py b/electrumabc/utils/macos.py index f3858980a1d4..a2f077a6f070 100644 --- a/electrumabc/utils/macos.py +++ b/electrumabc/utils/macos.py @@ -179,18 +179,19 @@ class CFRange(Structure): def CFString2Str(cfstr: CFString_p) -> str: - l = cf.CFStringGetLength(cfstr) - if l <= 0: - return "" # short circuit out if empty string or other nonsense length - r = CFRange(0, l) + length = cf.CFStringGetLength(cfstr) + if length <= 0: + # short circuit out if empty string or other nonsense length + return "" + r = CFRange(0, length) blen = CFIndex(0) lossbyte = c_ubyte(ord(b"?")) + # find out length of utf8 string in bytes, sans nul cf.CFStringGetBytes( cfstr, r, kCFStringEncodingUTF8, lossbyte, False, c_char_p(0), 0, byref(blen) - ) # find out length of utf8 string in bytes, sans nul - buf = create_string_buffer( - (blen.value + 1) * sizeof(c_char) - ) # allocate buffer + nul + ) + # allocate buffer + nul + buf = create_string_buffer((blen.value + 1) * sizeof(c_char)) num_conv = cf.CFStringGetBytes( cfstr, r, diff --git a/electrumabc/wallet.py b/electrumabc/wallet.py index 4d52446f054e..4a7fc7b00abb 100644 --- a/electrumabc/wallet.py +++ b/electrumabc/wallet.py @@ -910,16 +910,16 @@ def _get_tx_info(self, tx, delta, *, ver=1) -> Union[TxInfo, TxInfo2]: ) def get_addr_io(self, address): - h = self.get_address_history(address) + history = self.get_address_history(address) received = {} sent = {} - for tx_hash, height in h: - l = self.txo.get(tx_hash, {}).get(address, []) - for n, v, is_cb in l: + for tx_hash, height in history: + coins = self.txo.get(tx_hash, {}).get(address, []) + for n, v, is_cb in coins: received[tx_hash + ":%d" % n] = (height, v, is_cb) - for tx_hash, height in h: - l = self.txi.get(tx_hash, {}).get(address, []) - for txi, v in l: + for tx_hash, height in history: + inputs = self.txi.get(tx_hash, {}).get(address, []) + for txi, v in inputs: sent[txi] = height return received, sent @@ -1351,10 +1351,10 @@ def add_to_self_txi(tx_hash, addr, ser, v): d = self.txi.get(tx_hash) if d is None: self.txi[tx_hash] = d = {} - l = d.get(addr) - if l is None: - d[addr] = l = [] - l.append((ser, v)) + txis = d.get(addr) + if txis is None: + d[addr] = txis = [] + txis.append((ser, v)) def find_in_self_txo(prevout_hash: str, prevout_n: int) -> tuple: """Returns a tuple of the (Address,value) for a given @@ -1456,12 +1456,13 @@ def pop_pruned_txo(ser): if self.is_mine(addr): # add coin to self.txo since it's mine. mine = True - l = d.get(addr) - if l is None: - d[addr] = l = [] - l.append((n, v, is_coinbase)) - del l - self._addr_bal_cache.pop(addr, None) # invalidate cache entry + coins = d.get(addr) + if coins is None: + d[addr] = coins = [] + coins.append((n, v, is_coinbase)) + del coins + # invalidate cache entry + self._addr_bal_cache.pop(addr, None) # give v to txi that spends me next_tx = pop_pruned_txo(ser) if next_tx is not None and mine: @@ -1490,8 +1491,8 @@ def remove_transaction(self, tx_hash): self.pruned_txo_values.discard(hh) # add tx to pruned_txo, and undo the txi addition for next_tx, dd in self.txi.items(): - for addr, l in list(dd.items()): - ll = l[:] + for addr, txis_for_addr in list(dd.items()): + ll = txis_for_addr[:] for item in ll: ser, v = item prev_hash, prev_n = ser.split(":") @@ -1499,13 +1500,13 @@ def remove_transaction(self, tx_hash): self._addr_bal_cache.pop( addr, None ) # invalidate cache entry - l.remove(item) + txis_for_addr.remove(item) self.pruned_txo[ser] = next_tx self.pruned_txo_values.add(next_tx) - if l == []: + if not txis_for_addr: dd.pop(addr) else: - dd[addr] = l + dd[addr] = txis_for_addr # invalidate addr_bal_cache for outputs involving this tx d = self.txo.get(tx_hash, {}) @@ -1781,13 +1782,13 @@ def fmt_amt(v, is_diff): return format_satoshis(v, decimal_point=decimal_point, is_diff=is_diff) # grab history - h = self.get_history(domain, reverse=True) + history = self.get_history(domain, reverse=True) out = [] - n, l = 0, max(1, float(len(h))) - for tx_hash, height, conf, timestamp, value, balance in h: + n, length = 0, max(1, float(len(history))) + for tx_hash, height, conf, timestamp, value, balance in history: if progress_callback: - progress_callback(n / l) + progress_callback(n / length) n += 1 timestamp_safe = timestamp if timestamp is None: @@ -2568,7 +2569,7 @@ def get_receiving_address(self, *, frozen_ok=True): def get_payment_status(self, address, amount): local_height = self.get_local_height() received, sent = self.get_addr_io(address) - l = [] + transactions = [] for txo, x in received.items(): h, v, is_cb = x txid, n = txo.split(":") @@ -2578,10 +2579,10 @@ def get_payment_status(self, address, amount): conf = max(local_height - tx_height + 1, 0) else: conf = 0 - l.append((conf, v, txid)) + transactions.append((conf, v, txid)) tx_hashes = [] vsum = 0 - for conf, v, tx_hash in reversed(sorted(l)): + for conf, v, tx_hash in reversed(sorted(transactions)): vsum += v tx_hashes.append(tx_hash) if vsum >= amount: diff --git a/electrumabc/websockets.py b/electrumabc/websockets.py index d480a79087d6..b5051dc8380f 100644 --- a/electrumabc/websockets.py +++ b/electrumabc/websockets.py @@ -95,14 +95,12 @@ def reading_thread(self): except Exception as e: self.print_error("Error parsing address", addr, repr(e)) continue - l = self.subscriptions[ - addr - ] # defaultdict will create empty list if not already there. - l.append((ws, amount)) + # defaultdict will create empty list if not already there. + subs = self.subscriptions[addr] + subs.append((ws, amount)) h = addr.to_scripthash_hex() - self.sh2addr[ - h - ] = addr # remember this scripthash_hex -> addr mapping since run() below needs it. + # remember this scripthash_hex -> addr mapping since run() below needs it. + self.sh2addr[h] = addr self.network.send( [("blockchain.scripthash.subscribe", [h])], self.response_queue.put ) @@ -131,8 +129,8 @@ def run(self): if addr is None: self.print_error("can't find address for scripthash:", h) continue - l = self.subscriptions.get(addr, []) - for ws, amount in l: + subs = self.subscriptions.get(addr, []) + for ws, amount in subs: if not ws.closed: if sum(result.values()) >= amount: ws.sendMessage("paid") diff --git a/electrumabc_gui/qt/console.py b/electrumabc_gui/qt/console.py index 67db5f4b06d3..ffbc3d5741ac 100644 --- a/electrumabc_gui/qt/console.py +++ b/electrumabc_gui/qt/console.py @@ -348,8 +348,8 @@ def hide_completions(self) -> bool: return False c = self.editor.textCursor() c.setPosition(self.completions_pos) - l = self.completions_end - self.completions_pos - for x in range(l): + length = self.completions_end - self.completions_pos + for x in range(length): c.deleteChar() self.editor.moveCursor(QtGui.QTextCursor.End) diff --git a/electrumabc_gui/qt/exception_window.py b/electrumabc_gui/qt/exception_window.py index d7a40fd2b423..0b37cd1c9c45 100644 --- a/electrumabc_gui/qt/exception_window.py +++ b/electrumabc_gui/qt/exception_window.py @@ -101,18 +101,18 @@ def __init__(self, config, exctype, value, tb): heading = QtWidgets.QLabel("

" + _("Sorry!") + "

") main_box.addWidget(heading) - l = QtWidgets.QLabel(_(f"Something went wrong running {PROJECT_NAME}.")) - l.setWordWrap(True) - main_box.addWidget(l) + label = QtWidgets.QLabel(_(f"Something went wrong running {PROJECT_NAME}.")) + label.setWordWrap(True) + main_box.addWidget(label) - l = QtWidgets.QLabel( + label = QtWidgets.QLabel( _( "To help us diagnose and fix the problem, you can send us" " a bug report that contains useful debug information:" ) ) - l.setWordWrap(True) - main_box.addWidget(l) + label.setWordWrap(True) + main_box.addWidget(label) self.report_textfield = QtWidgets.QTextEdit() self.report_textfield.setReadOnly(True) diff --git a/electrumabc_gui/qt/main_window.py b/electrumabc_gui/qt/main_window.py index 5915759f553b..58c1fc10cf83 100644 --- a/electrumabc_gui/qt/main_window.py +++ b/electrumabc_gui/qt/main_window.py @@ -2354,13 +2354,14 @@ def get_contact_payto(self, contact: Contact) -> str: return label + " " + "<" + contact.address + ">" def update_completions(self): - l = [] + contact_paytos = [] for contact in self.contact_list.get_full_contacts(): s = self.get_contact_payto(contact) if s is not None: - l.append(s) - l.sort(key=lambda x: x.lower()) # case-insensitive sort - self.completions.setStringList(l) + contact_paytos.append(s) + # case-insensitive sort + contact_paytos.sort(key=lambda x: x.lower()) + self.completions.setStringList(contact_paytos) def protected(func): """Password request wrapper. The password is passed to the function @@ -3097,21 +3098,20 @@ def convert_address(): return w - def create_list_tab(self, l, list_header=None): - w = QtWidgets.QWidget() - w.searchable_list = l + def create_list_tab(self, list_widget): + """Return a container widget wrapping the list widget. + The container widget has a monkey patched `searchable_list` attribute that + refers to `list_widget`. + FIXME: nothing in this method makes any sense + """ + widget = QtWidgets.QWidget() + widget.searchable_list = list_widget vbox = QtWidgets.QVBoxLayout() - w.setLayout(vbox) + widget.setLayout(vbox) vbox.setContentsMargins(0, 0, 0, 0) vbox.setSpacing(0) - if list_header: - hbox = QtWidgets.QHBoxLayout() - for b in list_header: - hbox.addWidget(b) - hbox.addStretch() - vbox.addLayout(hbox) - vbox.addWidget(l) - return w + vbox.addWidget(list_widget) + return widget def create_addresses_tab(self): self.address_list = AddressList(self) @@ -6094,12 +6094,12 @@ def _pick_address(self, *, title=None, icon=None) -> Address: hbox.addStretch(1) vbox.addLayout(hbox) vbox.addWidget(QtWidgets.QLabel(_("Choose an address") + ":")) - l = AddressList(self, picker=True) + addrlist = AddressList(self, picker=True) try: - l.setObjectName("AddressList - " + d.windowTitle()) - destroyed_print_error(l) # track object lifecycle - l.update() - vbox.addWidget(l) + addrlist.setObjectName("AddressList - " + d.windowTitle()) + destroyed_print_error(addrlist) # track object lifecycle + addrlist.update() + vbox.addWidget(addrlist) ok = OkButton(d) ok.setDisabled(True) @@ -6108,17 +6108,17 @@ def _pick_address(self, *, title=None, icon=None) -> Address: def on_item_changed(current, previous): nonlocal addr - addr = current and current.data(0, l.DataRoles.address) + addr = current and current.data(0, addrlist.DataRoles.address) ok.setEnabled(addr is not None) def on_selection_changed(): - items = l.selectedItems() + items = addrlist.selectedItems() if items: on_item_changed(items[0], None) else: on_item_changed(None, None) - l.currentItemChanged.connect(on_item_changed) + addrlist.currentItemChanged.connect(on_item_changed) cancel = CancelButton(d) @@ -6129,7 +6129,7 @@ def on_selection_changed(): return addr return None finally: - l.clean_up() # required to unregister network callback + addrlist.clean_up() # required to unregister network callback class TxUpdateMgr(QObject, PrintError): diff --git a/electrumabc_gui/qt/scan_beyond_gap.py b/electrumabc_gui/qt/scan_beyond_gap.py index b5b41f843aca..6464e316c91f 100644 --- a/electrumabc_gui/qt/scan_beyond_gap.py +++ b/electrumabc_gui/qt/scan_beyond_gap.py @@ -43,7 +43,7 @@ def __init__(self, main_window): self.resize(450, 400) self.main_window = main_window vbox = QtWidgets.QVBoxLayout(self) - l = QtWidgets.QLabel( + label = QtWidgets.QLabel( "

" + _("Scanning Beyond the Gap") + "

" @@ -61,13 +61,15 @@ def __init__(self, main_window): ) + "

" ) - l.setWordWrap(True) - l.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed) - vbox.addWidget(l) + label.setWordWrap(True) + label.setSizePolicy( + QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed + ) + vbox.addWidget(label) vbox.addStretch(1) hbox = QtWidgets.QHBoxLayout() - l = QtWidgets.QLabel(_("Number of addresses to scan:")) - hbox.addWidget(l) + label = QtWidgets.QLabel(_("Number of addresses to scan:")) + hbox.addWidget(label) self.num_sb = QtWidgets.QSpinBox() self.num_sb.setMinimum(1) self.num_sb.setMaximum(1000000) diff --git a/electrumabc_gui/qt/transaction_dialog.py b/electrumabc_gui/qt/transaction_dialog.py index 5b8896bf2973..ac2ad8dfc140 100644 --- a/electrumabc_gui/qt/transaction_dialog.py +++ b/electrumabc_gui/qt/transaction_dialog.py @@ -116,9 +116,9 @@ def __init__(self, tx, parent, desc, prompt_if_unsaved): self.setLayout(vbox) self.tx_hash_e = ButtonsLineEdit() - l = QtWidgets.QLabel(_("&Transaction ID:")) - l.setBuddy(self.tx_hash_e) - vbox.addWidget(l) + label = QtWidgets.QLabel(_("&Transaction ID:")) + label.setBuddy(self.tx_hash_e) + vbox.addWidget(label) self.tx_hash_e.addCopyButton() weakSelfRef = Weak.ref(self) qr_show = lambda: weakSelfRef() and weakSelfRef().main_window.show_qrcode( @@ -147,7 +147,7 @@ def __init__(self, tx, parent, desc, prompt_if_unsaved): self.fee_label = QtWidgets.QLabel() vbox.addWidget(self.fee_label) - for l in ( + for label in ( self.tx_desc, self.status_label, self.date_label, @@ -156,8 +156,8 @@ def __init__(self, tx, parent, desc, prompt_if_unsaved): self.fee_label, ): # make these labels selectable by mouse in case user wants to copy-paste things in tx dialog - l.setTextInteractionFlags( - l.textInteractionFlags() | Qt.TextSelectableByMouse + label.setTextInteractionFlags( + label.textInteractionFlags() | Qt.TextSelectableByMouse ) def open_be_url(link): @@ -688,9 +688,9 @@ def add_io(self, vbox): inputs_lbl_text = ngettext( "&Input", "&Inputs ({num_inputs})", num_inputs ).format(num_inputs=num_inputs) - l = QtWidgets.QLabel(inputs_lbl_text) - l.setBuddy(i_text) - hbox.addWidget(l) + label = QtWidgets.QLabel(inputs_lbl_text) + label.setBuddy(i_text) + hbox.addWidget(label) hbox.addSpacerItem(QtWidgets.QSpacerItem(20, 0)) # 20 px padding self.dl_input_chk = chk = QtWidgets.QCheckBox(_("&Download input data")) @@ -750,9 +750,9 @@ def set_i_text_has_selection(b): outputs_lbl_text = ngettext( "&Output", "&Outputs ({num_outputs})", num_outputs ).format(num_outputs=num_outputs) - l = QtWidgets.QLabel(outputs_lbl_text) - l.setBuddy(o_text) - hbox.addWidget(l) + label = QtWidgets.QLabel(outputs_lbl_text) + label.setBuddy(o_text) + hbox.addWidget(label) box_char = "█" self.recv_legend = QtWidgets.QLabel( diff --git a/electrumabc_gui/qt/util.py b/electrumabc_gui/qt/util.py index 152f608a1744..81f285b0592b 100644 --- a/electrumabc_gui/qt/util.py +++ b/electrumabc_gui/qt/util.py @@ -525,14 +525,14 @@ def text_dialog(parent, title, label, ok_label, default=None, allow_multi=False) dialog = WindowModalDialog(parent, title) dialog.setMinimumWidth(500) - l = QtWidgets.QVBoxLayout() - dialog.setLayout(l) - l.addWidget(QtWidgets.QLabel(label)) + layout = QtWidgets.QVBoxLayout() + dialog.setLayout(layout) + layout.addWidget(QtWidgets.QLabel(label)) txt = ScanQRTextEdit(allow_multi=allow_multi) if default: txt.setText(default) - l.addWidget(txt) - l.addLayout(Buttons(CancelButton(dialog), OkButton(dialog, ok_label))) + layout.addWidget(txt) + layout.addLayout(Buttons(CancelButton(dialog), OkButton(dialog, ok_label))) if dialog.exec_(): return txt.toPlainText() diff --git a/electrumabc_gui/text.py b/electrumabc_gui/text.py index bb77dba165f6..040aee7cc7a8 100644 --- a/electrumabc_gui/text.py +++ b/electrumabc_gui/text.py @@ -274,9 +274,9 @@ def print_qr(self, data): self.qr.print_ascii(out=s, invert=False) msg = s.getvalue() lines = msg.split("\n") - for i, l in enumerate(lines): - l = l.encode("utf-8") - self.stdscr.addstr(i + 5, 5, l, curses.color_pair(3)) + for i, line in enumerate(lines): + line = line.encode("utf-8") + self.stdscr.addstr(i + 5, 5, line, curses.color_pair(3)) def print_list(self, lst, firstline=None): lst = list(lst) diff --git a/electrumabc_plugins/cosigner_pool/qt.py b/electrumabc_plugins/cosigner_pool/qt.py index 1aab2b2310f0..52e8f398306d 100644 --- a/electrumabc_plugins/cosigner_pool/qt.py +++ b/electrumabc_plugins/cosigner_pool/qt.py @@ -47,8 +47,8 @@ # Workarounds to the fact that xmlrpc.client doesn't take a timeout= arg. class TimeoutTransport(Transport): - def __init__(self, timeout=2.0, *l, **kw): - super().__init__(*l, **kw) + def __init__(self, timeout=2.0, *args, **kw): + super().__init__(*args, **kw) self.timeout = timeout def make_connection(self, host): @@ -56,11 +56,11 @@ def make_connection(self, host): class TimeoutServerProxy(ServerProxy): - def __init__(self, uri, timeout=2.0, *l, **kw): + def __init__(self, uri, timeout=2.0, *args, **kw): kw["transport"] = TimeoutTransport( timeout=timeout, use_datetime=kw.get("use_datetime", False) ) - super().__init__(uri, *l, **kw) + super().__init__(uri, *args, **kw) # /end timeout= Workarounds diff --git a/electrumabc_plugins/fusion/plugin.py b/electrumabc_plugins/fusion/plugin.py index fe824ed14a66..e07cbef60f28 100644 --- a/electrumabc_plugins/fusion/plugin.py +++ b/electrumabc_plugins/fusion/plugin.py @@ -696,7 +696,7 @@ def run( # we don't have enough auto-fusions running, so start one fraction = get_target_params_2(wallet_conf, sum_value) chosen_buckets = select_random_coins(wallet, fraction, eligible) - coins = [c for l in chosen_buckets for c in l] + coins = [coin for bucket in chosen_buckets for coin in bucket] if not coins: self.print_error("auto-fusion skipped due to lack of coins") continue diff --git a/electrumabc_plugins/hw_wallet/qt.py b/electrumabc_plugins/hw_wallet/qt.py index 80af7dee4db4..76922eb83f78 100644 --- a/electrumabc_plugins/hw_wallet/qt.py +++ b/electrumabc_plugins/hw_wallet/qt.py @@ -186,9 +186,9 @@ def message_dialog(self, msg, on_cancel): self.clear_dialog() title = _("Please check your {} device").format(self.device) self.dialog = dialog = WindowModalDialog(self.top_level_window(), title) - l = QtWidgets.QLabel(msg) + label = QtWidgets.QLabel(msg) vbox = QtWidgets.QVBoxLayout(dialog) - vbox.addWidget(l) + vbox.addWidget(label) if on_cancel: dialog.rejected.connect(on_cancel) vbox.addLayout(Buttons(CancelButton(dialog))) diff --git a/electrumabc_plugins/labels/qt.py b/electrumabc_plugins/labels/qt.py index 9bf21ac7356c..485cc4f334ce 100644 --- a/electrumabc_plugins/labels/qt.py +++ b/electrumabc_plugins/labels/qt.py @@ -100,26 +100,30 @@ class MySigs(QObject): else: vbox = QtWidgets.QVBoxLayout(d) if wallet.network: - # has network, so the fact that the wallet isn't in the list means it's incompatible - l = QtWidgets.QLabel( + # has network, so the fact that the wallet isn't in the list means it's + # incompatible + label = QtWidgets.QLabel( "" + _("LabelSync not supported for this wallet type") + "" ) - l.setAlignment(Qt.AlignCenter) - vbox.addWidget(l) - l = QtWidgets.QLabel(_("(Only deterministic wallets are supported)")) - l.setAlignment(Qt.AlignCenter) - vbox.addWidget(l) + label.setAlignment(Qt.AlignCenter) + vbox.addWidget(label) + label = QtWidgets.QLabel( + _("(Only deterministic wallets are supported)") + ) + label.setAlignment(Qt.AlignCenter) + vbox.addWidget(label) else: - # Does not have network, so we won't speak of incompatibility, but instead remind user offline mode means OFFLINE! ;) - l = QtWidgets.QLabel( + # Does not have network, so we won't speak of incompatibility, but + # instead remind user offline mode means OFFLINE! ;) + label = QtWidgets.QLabel( _( f"You are using {PROJECT_NAME} in offline mode;" f" restart Electron Cash if you want to get " f"connected" ) ) - l.setWordWrap(True) - vbox.addWidget(l) + label.setWordWrap(True) + vbox.addWidget(label) vbox.addSpacing(20) vbox.addLayout(Buttons(d.ok_button)) return bool(d.exec_()) diff --git a/electrumabc_plugins/ledger/qt.py b/electrumabc_plugins/ledger/qt.py index 25e7d9cbeaf0..64025cd6e25f 100644 --- a/electrumabc_plugins/ledger/qt.py +++ b/electrumabc_plugins/ledger/qt.py @@ -59,9 +59,9 @@ def message_dialog(self, msg): self.dialog = dialog = WindowModalDialog( self.top_level_window(), _("Ledger Status") ) - l = QtWidgets.QLabel(msg) + label = QtWidgets.QLabel(msg) vbox = QtWidgets.QVBoxLayout(dialog) - vbox.addWidget(l) + vbox.addWidget(label) dialog.show() def auth_dialog(self, data): diff --git a/electrumabc_plugins/trezor/trezor.py b/electrumabc_plugins/trezor/trezor.py index 698baea948d7..c905fd822fd5 100644 --- a/electrumabc_plugins/trezor/trezor.py +++ b/electrumabc_plugins/trezor/trezor.py @@ -315,9 +315,10 @@ def _initialize_device_safe(self, settings, method, device_id, loops, errors): errors.append(e) exit_code = 1 finally: - l = loops.copy() # leverage the GIL here for thread safety. - if l: - l[0].exit(exit_code) + # leverage the GIL here for thread safety. + lc = loops.copy() + if lc: + lc[0].exit(exit_code) def _initialize_device(self, settings, method, device_id): item, label, pin_protection, passphrase_protection, recovery_type = settings From a2f076d7ae18ba6610c4cc71e2e533d0b5be1d9c Mon Sep 17 00:00:00 2001 From: PiRK Date: Thu, 12 Jan 2023 13:54:56 +0100 Subject: [PATCH 3/9] don't wrap widgets inside a blank widget just to add a monkey_patched attribute --- electrumabc_gui/qt/main_window.py | 87 ++++++++++++------------------- 1 file changed, 34 insertions(+), 53 deletions(-) diff --git a/electrumabc_gui/qt/main_window.py b/electrumabc_gui/qt/main_window.py index 58c1fc10cf83..d05e643b8322 100644 --- a/electrumabc_gui/qt/main_window.py +++ b/electrumabc_gui/qt/main_window.py @@ -276,14 +276,13 @@ def __init__(self, gui_object: ElectrumGui, wallet: Abstract_Wallet): self.tabs = tabs = QtWidgets.QTabWidget(self) self.send_tab = self.create_send_tab() self.receive_tab = self.create_receive_tab() - self.addresses_tab = self.create_addresses_tab() - self.utxo_tab = self.create_utxo_tab() + self.address_list = self.create_addresses_tab() + self.utxo_list = self.create_utxo_tab() self.console_tab = self.create_console_tab() - self.contacts_tab = self.create_contacts_tab() + self.contact_list = ContactList(self) self.converter_tab = self.create_converter_tab() - tabs.addTab( - self.create_history_tab(), QIcon(":icons/tab_history.png"), _("History") - ) + self.history_list = self.create_history_tab() + tabs.addTab(self.history_list, QIcon(":icons/tab_history.png"), _("History")) tabs.addTab(self.send_tab, QIcon(":icons/tab_send.png"), _("Send")) tabs.addTab(self.receive_tab, QIcon(":icons/tab_receive.png"), _("Receive")) # clears/inits the opreturn widgets @@ -299,17 +298,17 @@ def add_optional_tab(tabs, tab, icon, description, name, default=True): add_optional_tab( tabs, - self.addresses_tab, + self.address_list, QIcon(":icons/tab_addresses.png"), _("&Addresses"), "addresses", ) add_optional_tab( - tabs, self.utxo_tab, QIcon(":icons/tab_coins.png"), _("Co&ins"), "utxo" + tabs, self.utxo_list, QIcon(":icons/tab_coins.png"), _("Co&ins"), "utxo" ) add_optional_tab( tabs, - self.contacts_tab, + self.contact_list, QIcon(":icons/tab_contacts.png"), _("Con&tacts"), "contacts", @@ -903,9 +902,9 @@ def add_toggle_action(view_menu, tab): ) view_menu = menubar.addMenu(_("&View")) - add_toggle_action(view_menu, self.addresses_tab) - add_toggle_action(view_menu, self.utxo_tab) - add_toggle_action(view_menu, self.contacts_tab) + add_toggle_action(view_menu, self.address_list) + add_toggle_action(view_menu, self.utxo_list) + add_toggle_action(view_menu, self.contact_list) add_toggle_action(view_menu, self.converter_tab) add_toggle_action(view_menu, self.console_tab) @@ -1388,10 +1387,9 @@ def _update_labels(self): self.labels_need_update.clear() # clear flag def create_history_tab(self): - self.history_list = HistoryList(self) - self.history_list.edited.connect(self.update_labels) - self.history_list.searchable_list = self.history_list - return self.history_list + history_list = HistoryList(self) + history_list.edited.connect(self.update_labels) + return history_list def show_address(self, addr, *, parent=None): parent = parent or self.top_level_window() @@ -3098,49 +3096,28 @@ def convert_address(): return w - def create_list_tab(self, list_widget): - """Return a container widget wrapping the list widget. - The container widget has a monkey patched `searchable_list` attribute that - refers to `list_widget`. - FIXME: nothing in this method makes any sense - """ - widget = QtWidgets.QWidget() - widget.searchable_list = list_widget - vbox = QtWidgets.QVBoxLayout() - widget.setLayout(vbox) - vbox.setContentsMargins(0, 0, 0, 0) - vbox.setSpacing(0) - vbox.addWidget(list_widget) - return widget - def create_addresses_tab(self): - self.address_list = AddressList(self) - self.address_list.edited.connect(self.update_labels) - self.address_list.selection_cleared.connect( - self.status_bar.clear_selected_amount - ) - self.address_list.selected_amount_changed.connect( + address_list = AddressList(self) + address_list.edited.connect(self.update_labels) + address_list.selection_cleared.connect(self.status_bar.clear_selected_amount) + address_list.selected_amount_changed.connect( lambda satoshis: self.status_bar.set_selected_amount( self.format_amount_and_units(satoshis) ) ) - return self.create_list_tab(self.address_list) + return address_list def create_utxo_tab(self): - self.utxo_list = UTXOList(self) - self.utxo_list.selection_cleared.connect(self.status_bar.clear_selected_amount) - self.utxo_list.selected_amount_changed.connect( + utxo_list = UTXOList(self) + utxo_list.selection_cleared.connect(self.status_bar.clear_selected_amount) + utxo_list.selected_amount_changed.connect( lambda satoshis: self.status_bar.set_selected_amount( self.format_amount_and_units(satoshis) ) ) - self.gui_object.addr_fmt_changed.connect(self.utxo_list.update) - self.utxo_list.edited.connect(self.update_labels) - return self.create_list_tab(self.utxo_list) - - def create_contacts_tab(self): - self.contact_list = ContactList(self) - return self.create_list_tab(self.contact_list) + self.gui_object.addr_fmt_changed.connect(utxo_list.update) + utxo_list.edited.connect(self.update_labels) + return utxo_list def remove_address(self, addr): if self.question( @@ -3465,16 +3442,20 @@ def get_passphrase_dialog( ) return d.run() - def do_search(self, t: str): + def do_search(self, pattern: str): """Apply search text to all tabs. FIXME: if a plugin later is loaded it will not receive the search filter -- but most plugins I know about do not support searchable_list anyway, so hopefully it's a non-issue.""" for i in range(self.tabs.count()): tab = self.tabs.widget(i) - try: - tab.searchable_list.filter(t) - except (AttributeError, TypeError): - pass + searchable_list = None + if isinstance(tab, MyTreeWidget): + searchable_list = tab + elif hasattr(tab, "searchable_list"): + searchable_list = tab.searchable_list + if searchable_list is None: + return + searchable_list.filter(pattern) def new_contact_dialog(self): d = WindowModalDialog(self.top_level_window(), _("New Contact")) From 8a401a98641de77998d07ee1f1efd36450855c97 Mon Sep 17 00:00:00 2001 From: PiRK Date: Thu, 12 Jan 2023 10:50:21 +0100 Subject: [PATCH 4/9] [flake8] fix E731 errors (do not assign a lambda expression, use a def) remove the unused ones, move the ones that a single-used directly to the callsite, use a proper def for others --- .pre-commit-config.yaml | 4 +- electrumabc/base_wizard.py | 58 ++++++++++++++---------- electrumabc/bitcoin.py | 16 +++++-- electrumabc/coinchooser.py | 4 +- electrumabc/commands.py | 13 ++++-- electrumabc/interface.py | 5 +- electrumabc/keystore.py | 15 ++++-- electrumabc/mnemo.py | 3 +- electrumabc/network.py | 9 ++-- electrumabc/tests/test_simple_config.py | 58 ++++++++++++++++++------ electrumabc/util.py | 23 ++++------ electrumabc/wallet.py | 4 +- electrumabc_gui/qt/main_window.py | 5 +- electrumabc_gui/qt/transaction_dialog.py | 13 ++++-- electrumabc_gui/stdio.py | 5 +- electrumabc_gui/text.py | 4 +- electrumabc_plugins/fusion/fusion.py | 4 +- electrumabc_plugins/satochip/satochip.py | 38 ++++++++++------ scripts/block_headers | 7 ++- scripts/watch_address | 6 ++- 20 files changed, 192 insertions(+), 102 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 3dd0d1d03eb3..2969b7ae1233 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -26,7 +26,7 @@ repos: args: - --max-line-length=88 - --select=E1,E2,E3,E4,E5,E7,E9,F4,F5,F6,F7,F8,W1,W2,W3,W504,W6 - - --ignore=E501,E722,E731 # FIXME + - --ignore=E501,E722 # FIXME - --extend-ignore=E203 # This one is incompatible with black additional_dependencies: - flake8-mutable @@ -34,7 +34,7 @@ repos: - id: flake8 args: - --max-line-length=88 - - --ignore=E203,E501,E731,W503,SIM106,SIM119,FS002,FS003 + - --ignore=E203,E501,W503,SIM106,SIM119,FS002,FS003 additional_dependencies: - flake8-comprehensions - flake8-mutable diff --git a/electrumabc/base_wizard.py b/electrumabc/base_wizard.py index f901c8a403aa..6564f0c0f2f5 100644 --- a/electrumabc/base_wizard.py +++ b/electrumabc/base_wizard.py @@ -205,9 +205,11 @@ def choose_keystore(self): ) def import_addresses_or_keys(self): - v = lambda x: keystore.is_address_list(x) or keystore.is_private_key_list( - x, allow_bip38=True - ) + def is_valid(x): + return keystore.is_address_list(x) or keystore.is_private_key_list( + x, allow_bip38=True + ) + title = _(f"Import {CURRENCY} Addresses") message = _( f"Enter a list of {CURRENCY} addresses (this will create a" @@ -219,7 +221,7 @@ def import_addresses_or_keys(self): title=title, message=message, run_next=self.on_import, - is_valid=v, + is_valid=is_valid, allow_multi=True, ) @@ -555,20 +557,24 @@ def passphrase_dialog(self, run_next): def restore_from_seed(self): self.opt_bip39 = True self.opt_ext = True - test = ( - mnemo.is_seed - ) # TODO FIX #bitcoin.is_seed if self.wallet_type == 'standard' else bitcoin.is_new_seed + # TODO FIX #bitcoin.is_seed if self.wallet_type == 'standard' else bitcoin.is_new_seed + test = mnemo.is_seed self.restore_seed_dialog(run_next=self.on_restore_seed, test=test) def on_restore_seed(self, seed, is_bip39, is_ext): - self.seed_type = ( - "bip39" if is_bip39 else mnemo.seed_type_name(seed) - ) # NB: seed_type_name here may also auto-detect 'bip39' + # NB: seed_type_name here may also auto-detect 'bip39' + self.seed_type = "bip39" if is_bip39 else mnemo.seed_type_name(seed) if self.seed_type == "bip39": - f = lambda passphrase: self.on_restore_bip39(seed, passphrase) + + def f(passphrase): + self.on_restore_bip39(seed, passphrase) + self.passphrase_dialog(run_next=f) if is_ext else f("") elif self.seed_type in ["standard", "electrum"]: - f = lambda passphrase: self.run("create_keystore", seed, passphrase) + + def f(passphrase): + self.run("create_keystore", seed, passphrase) + self.passphrase_dialog(run_next=f) if is_ext else f("") elif self.seed_type == "old": self.run("create_keystore", seed, "") @@ -576,8 +582,11 @@ def on_restore_seed(self, seed, is_bip39, is_ext): raise BaseException("Unknown seed type", self.seed_type) def on_restore_bip39(self, seed, passphrase): - f = lambda x: self.run("on_bip44", seed, passphrase, str(x)) - self.derivation_dialog(f, keystore.bip44_derivation_xec(0), seed=seed) + self.derivation_dialog( + lambda x: self.run("on_bip44", seed, passphrase, str(x)), + keystore.bip44_derivation_xec(0), + seed=seed, + ) def create_keystore(self, seed, passphrase): # auto-detect, prefers old, electrum, bip39 in that order. Since we @@ -737,8 +746,6 @@ def create_standard_seed(self): self.create_seed("bip39") def create_seed(self, seed_type): - from . import mnemo - self.seed_type = seed_type if seed_type in ["standard", "electrum"]: seed = mnemo.Mnemonic_Electrum("en").make_seed() @@ -748,22 +755,23 @@ def create_seed(self, seed_type): # This should never happen. raise ValueError("Cannot make seed for unknown seed type " + str(seed_type)) self.opt_bip39 = False - f = lambda x: self.request_passphrase(seed, x) - self.show_seed_dialog(run_next=f, seed_text=seed) + self.show_seed_dialog( + run_next=lambda x: self.request_passphrase(seed, x), seed_text=seed + ) def request_passphrase(self, seed, opt_passphrase): if opt_passphrase: - f = lambda x: self.confirm_seed(seed, x) - self.passphrase_dialog(run_next=f) + self.passphrase_dialog(run_next=lambda x: self.confirm_seed(seed, x)) else: self.run("confirm_seed", seed, "") def confirm_seed(self, seed, passphrase): - f = lambda x: self.confirm_passphrase(seed, passphrase) - self.confirm_seed_dialog(run_next=f, test=lambda x: x == seed) + self.confirm_seed_dialog( + run_next=lambda x: self.confirm_passphrase(seed, passphrase), + test=lambda x: x == seed, + ) def confirm_passphrase(self, seed, passphrase): - f = lambda x: self.run("create_keystore", seed, x) if passphrase: title = _("Confirm Seed Extension") message = "\n".join( @@ -773,14 +781,14 @@ def confirm_passphrase(self, seed, passphrase): ] ) self.line_dialog( - run_next=f, + run_next=lambda x: self.run("create_keystore", seed, x), title=title, message=message, default="", test=lambda x: x == passphrase, ) else: - f("") + self.run("create_keystore", seed, "") def create_addresses(self): def task(): diff --git a/electrumabc/bitcoin.py b/electrumabc/bitcoin.py index 5b56967f84f1..8a284211a949 100644 --- a/electrumabc/bitcoin.py +++ b/electrumabc/bitcoin.py @@ -460,9 +460,17 @@ def hmac_oneshot(key, msg, digest): return hmac.new(key, msg, digest).digest() -hash_encode = lambda x: bh2u(x[::-1]) -hash_decode = lambda x: bfh(x)[::-1] -hmac_sha_512 = lambda x, y: hmac_oneshot(x, y, hashlib.sha512) +def hash_encode(x): + return bh2u(x[::-1]) + + +def hash_decode(x): + return bytes.fromhex(x)[::-1] + + +def hmac_sha_512(x, y): + return hmac_oneshot(x, y, hashlib.sha512) + # pywallet openssl private key implementation @@ -1024,8 +1032,6 @@ def decrypt_message(self, encrypted, magic=b"BIE1"): # BIP32 - -random_seed = lambda n: "%032x" % ecdsa.util.randrange(pow(2, n)) BIP32_PRIME = 0x80000000 diff --git a/electrumabc/coinchooser.py b/electrumabc/coinchooser.py index 3d7e333d4c22..87551786d829 100644 --- a/electrumabc/coinchooser.py +++ b/electrumabc/coinchooser.py @@ -214,7 +214,9 @@ def sufficient_funds(buckets): # This takes a count of change outputs and returns a tx fee; # each pay-to-bitcoin-address output serializes as 34 bytes - fee = lambda count: fee_estimator(tx_size + count * 34) + def fee(count): + return fee_estimator(tx_size + count * 34) + change, dust = self.change_outputs(tx, change_addrs, fee, dust_threshold) tx.add_outputs(change) tx.ephemeral["dust_to_fee"] = dust diff --git a/electrumabc/commands.py b/electrumabc/commands.py index 67a4a4c44efc..f233ed87171b 100644 --- a/electrumabc/commands.py +++ b/electrumabc/commands.py @@ -698,9 +698,10 @@ def _mktx( coins = self.wallet.get_spendable_coins(domain, self.config) if feerate is not None: fee_per_kb = 1000 * PyDecimal(feerate) - fee_estimator = lambda size: SimpleConfig.estimate_fee_for_feerate( - fee_per_kb, size - ) + + def fee_estimator(size): + return SimpleConfig.estimate_fee_for_feerate(fee_per_kb, size) + else: fee_estimator = fee tx = self.wallet.make_unsigned_transaction( @@ -1213,7 +1214,11 @@ def help(self): "year": (None, "Show history for a given year"), } -json_loads = lambda x: json.loads(x, parse_float=lambda x: str(PyDecimal(x))) + +def json_loads(x): + return json.loads(x, parse_float=lambda y: str(PyDecimal(y))) + + arg_types = { "num": int, "nbits": int, diff --git a/electrumabc/interface.py b/electrumabc/interface.py index 1d04dea4b981..c9c0faf23571 100644 --- a/electrumabc/interface.py +++ b/electrumabc/interface.py @@ -439,7 +439,10 @@ def send_requests(self): return True self.last_send = time.time() - make_dict = lambda m, p, i: {"method": m, "params": p, "id": i} + + def make_dict(m, p, i): + return {"method": m, "params": p, "id": i} + n = self.num_requests() wire_requests = self.unsent_requests[0:n] diff --git a/electrumabc/keystore.py b/electrumabc/keystore.py index 88834dd3f88f..5a31cc39733b 100644 --- a/electrumabc/keystore.py +++ b/electrumabc/keystore.py @@ -766,11 +766,16 @@ def is_private_key_list(text, *, allow_bip38=False): return bool(get_private_keys(text, allow_bip38=allow_bip38)) -is_mpk = lambda x: is_old_mpk(x) or bitcoin.is_xpub(x) -is_private = lambda x: mnemo.is_seed(x) or bitcoin.is_xprv(x) or is_private_key_list(x) -is_master_key = lambda x: is_old_mpk(x) or bitcoin.is_xprv(x) or bitcoin.is_xpub(x) -is_private_key = lambda x: bitcoin.is_xprv(x) or is_private_key_list(x) -is_bip32_key = lambda x: bitcoin.is_xprv(x) or bitcoin.is_xpub(x) +def is_private(text: str) -> bool: + return mnemo.is_seed(text) or bitcoin.is_xprv(text) or is_private_key_list(text) + + +def is_master_key(text: str) -> bool: + return is_old_mpk(text) or bitcoin.is_xprv(text) or bitcoin.is_xpub(text) + + +def is_bip32_key(text: str) -> bool: + return bitcoin.is_xprv(text) or bitcoin.is_xpub(text) def _bip44_derivation(coin: int, account_id: int) -> str: diff --git a/electrumabc/mnemo.py b/electrumabc/mnemo.py index 3e13e6f47266..b12b830f39e3 100644 --- a/electrumabc/mnemo.py +++ b/electrumabc/mnemo.py @@ -248,7 +248,8 @@ def format_seed_type_name_for_ui(name: str) -> str: return name.title() # Title Caps for "Old" and "Electrum" -is_seed = lambda x: seed_type(x) is not None +def is_seed(text: str) -> bool: + return seed_type(text) is not None def bip39_mnemonic_to_seed(words: str, passphrase: str = ""): diff --git a/electrumabc/network.py b/electrumabc/network.py index e338f40d990f..d2a9b9646eae 100644 --- a/electrumabc/network.py +++ b/electrumabc/network.py @@ -2196,12 +2196,13 @@ def broadcast_transaction2(self, transaction, timeout=30): Does not support using a callback function.""" command = "blockchain.transaction.broadcast" - invocation = lambda c: self.send([(command, [str(transaction)])], c) + + def invocation(c): + self.send([(command, [str(transaction)])], c) try: - out = Network.__wait_for( - invocation, timeout=timeout - ) # may raise util.TimeoutException, util.ServerErrorResponse + # may raise util.TimeoutException, util.ServerErrorResponse + out = Network.__wait_for(invocation, timeout=timeout) except util.ServerErrorResponse as e: # rephrase the generic message to something more suitable self.print_error("Server error response was:", str(e.server_msg)) diff --git a/electrumabc/tests/test_simple_config.py b/electrumabc/tests/test_simple_config.py index 71054c40d530..41822c18c29c 100644 --- a/electrumabc/tests/test_simple_config.py +++ b/electrumabc/tests/test_simple_config.py @@ -35,8 +35,13 @@ def tearDown(self): def test_simple_config_key_rename(self): """auto_cycle was renamed auto_connect""" - fake_read_user = lambda _: {"auto_cycle": True} - read_user_dir = lambda: self.user_dir + + def fake_read_user(_): + return {"auto_cycle": True} + + def read_user_dir(): + return self.user_dir + config = SimpleConfig( options=self.options, read_user_config_function=fake_read_user, @@ -44,7 +49,10 @@ def test_simple_config_key_rename(self): ) self.assertEqual(config.get("auto_connect"), True) self.assertEqual(config.get("auto_cycle"), None) - fake_read_user = lambda _: {"auto_connect": False, "auto_cycle": True} + + def fake_read_user(_): + return {"auto_connect": False, "auto_cycle": True} + config = SimpleConfig( options=self.options, read_user_config_function=fake_read_user, @@ -56,8 +64,13 @@ def test_simple_config_key_rename(self): def test_simple_config_command_line_overrides_everything(self): """Options passed by command line override all other configuration sources""" - fake_read_user = lambda _: {"data_path": "b"} - read_user_dir = lambda: self.user_dir + + def fake_read_user(_): + return {"data_path": "b"} + + def read_user_dir(): + return self.user_dir + config = SimpleConfig( options=self.options, read_user_config_function=fake_read_user, @@ -68,8 +81,13 @@ def test_simple_config_command_line_overrides_everything(self): def test_simple_config_user_config_is_used_if_others_arent_specified(self): """If no system-wide configuration and no command-line options are specified, the user configuration is used instead.""" - fake_read_user = lambda _: {"data_path": self.electrum_dir} - read_user_dir = lambda: self.user_dir + + def fake_read_user(_): + return {"data_path": self.electrum_dir} + + def read_user_dir(): + return self.user_dir + config = SimpleConfig( options={}, read_user_config_function=fake_read_user, @@ -78,8 +96,12 @@ def test_simple_config_user_config_is_used_if_others_arent_specified(self): self.assertEqual(self.options.get("data_path"), config.get("data_path")) def test_cannot_set_options_passed_by_command_line(self): - fake_read_user = lambda _: {"data_path": "b"} - read_user_dir = lambda: self.user_dir + def fake_read_user(_): + return {"data_path": "b"} + + def read_user_dir(): + return self.user_dir + config = SimpleConfig( options=self.options, read_user_config_function=fake_read_user, @@ -90,8 +112,13 @@ def test_cannot_set_options_passed_by_command_line(self): def test_can_set_options_set_in_user_config(self): another_path = tempfile.mkdtemp() - fake_read_user = lambda _: {"data_path": self.electrum_dir} - read_user_dir = lambda: self.user_dir + + def fake_read_user(_): + return {"data_path": self.electrum_dir} + + def read_user_dir(): + return self.user_dir + config = SimpleConfig( options={}, read_user_config_function=fake_read_user, @@ -102,8 +129,13 @@ def test_can_set_options_set_in_user_config(self): def test_user_config_is_not_written_with_read_only_config(self): """The user config does not contain command-line options when saved.""" - fake_read_user = lambda _: {"something": "a"} - read_user_dir = lambda: self.user_dir + + def fake_read_user(_): + return {"something": "a"} + + def read_user_dir(): + return self.user_dir + self.options.update({"something": "c"}) config = SimpleConfig( options=self.options, diff --git a/electrumabc/util.py b/electrumabc/util.py index 5a65a584a8df..f0e7ea51303b 100644 --- a/electrumabc/util.py +++ b/electrumabc/util.py @@ -1011,29 +1011,24 @@ class MethodProxy(weakref.WeakMethod): its print_func attribute). Instead use of the wrapper class 'Weak' defined in the enclosing scope is encouraged.""" - print_func = lambda x, this, info: print_error( - this, info - ) # <--- set this attribute if needed, either on the class or instance level, to control debug printing behavior. None is ok here. - def __init__(self, meth, *args, **kwargs): super().__init__(meth, *args, **kwargs) - # teehee.. save some information about what to call this thing for debug print purposes + # teehee.. save some information about what to call this thing for debug + # print purposes self.qname, self.sname = meth.__qualname__, str(meth.__self__) def __call__(self, *args, **kwargs): """Either directly calls the method for you or prints debug info if the target object died""" - meth = super().__call__() # if dead, None is returned - if ( - meth - ): # could also do callable() as the test but hopefully this is sightly faster + # if dead, None is returned + meth = super().__call__() + if meth: return meth(*args, **kwargs) - elif callable(self.print_func): - self.print_func( + else: + print_error( self, - "MethodProxy for '{}' called on a dead reference. Referent was: {})".format( - self.qname, self.sname - ), + f"MethodProxy for '{self.qname}' called on a dead reference. " + f"Referent was: {self.sname})", ) diff --git a/electrumabc/wallet.py b/electrumabc/wallet.py index 4a7fc7b00abb..635f8cfe9660 100644 --- a/electrumabc/wallet.py +++ b/electrumabc/wallet.py @@ -2058,7 +2058,9 @@ def make_unsigned_transaction( elif callable(fixed_fee): fee_estimator = fixed_fee else: - fee_estimator = lambda size: fixed_fee + + def fee_estimator(size): + return fixed_fee if i_max is None: # Let the coin chooser select the coins to spend diff --git a/electrumabc_gui/qt/main_window.py b/electrumabc_gui/qt/main_window.py index d05e643b8322..d471dbd3992e 100644 --- a/electrumabc_gui/qt/main_window.py +++ b/electrumabc_gui/qt/main_window.py @@ -3512,9 +3512,10 @@ def label(key): return "" labels = [label(i) for i in range(len(mpk_list))] - on_click = lambda clayout: show_mpk(clayout.selected_index()) labels_clayout = ChoicesLayout( - _("Master Public Keys"), labels, on_click + _("Master Public Keys"), + labels, + lambda clayout: show_mpk(clayout.selected_index()), ) vbox.addLayout(labels_clayout.layout()) else: diff --git a/electrumabc_gui/qt/transaction_dialog.py b/electrumabc_gui/qt/transaction_dialog.py index ac2ad8dfc140..f473966359e0 100644 --- a/electrumabc_gui/qt/transaction_dialog.py +++ b/electrumabc_gui/qt/transaction_dialog.py @@ -121,11 +121,14 @@ def __init__(self, tx, parent, desc, prompt_if_unsaved): vbox.addWidget(label) self.tx_hash_e.addCopyButton() weakSelfRef = Weak.ref(self) - qr_show = lambda: weakSelfRef() and weakSelfRef().main_window.show_qrcode( - str(weakSelfRef().tx_hash_e.text()), - _("Transaction ID"), - parent=weakSelfRef(), - ) + + def qr_show(): + return weakSelfRef() and weakSelfRef().main_window.show_qrcode( + str(weakSelfRef().tx_hash_e.text()), + _("Transaction ID"), + parent=weakSelfRef(), + ) + icon = ( ":icons/qrcode_white.svg" if ColorScheme.dark_scheme diff --git a/electrumabc_gui/stdio.py b/electrumabc_gui/stdio.py index 39ff89b6f652..e5f43467d214 100644 --- a/electrumabc_gui/stdio.py +++ b/electrumabc_gui/stdio.py @@ -10,7 +10,10 @@ from electrumabc.util import format_satoshis from electrumabc.wallet import Wallet -_ = lambda x: x + +def _(x): + x + # minimal fdisk like gui for console usage # written by rofl0r, with some bits stolen from the text gui (ncurses) diff --git a/electrumabc_gui/text.py b/electrumabc_gui/text.py index 040aee7cc7a8..0c98d2295caf 100644 --- a/electrumabc_gui/text.py +++ b/electrumabc_gui/text.py @@ -15,7 +15,9 @@ from electrumabc.util import format_satoshis from electrumabc.wallet import Wallet -_ = lambda x: x + +def _(x): + return x class ElectrumGui: diff --git a/electrumabc_plugins/fusion/fusion.py b/electrumabc_plugins/fusion/fusion.py index a33ed869d9a2..555c0c9f2026 100644 --- a/electrumabc_plugins/fusion/fusion.py +++ b/electrumabc_plugins/fusion/fusion.py @@ -936,7 +936,9 @@ def run_round(self, covert): # covert activities. clock = time.monotonic covert_T0 = clock() - covert_clock = lambda: clock() - covert_T0 + + def covert_clock(): + return clock() - covert_T0 round_time = msg.server_time diff --git a/electrumabc_plugins/satochip/satochip.py b/electrumabc_plugins/satochip/satochip.py index c11b29e9e69e..50691da4c1ed 100644 --- a/electrumabc_plugins/satochip/satochip.py +++ b/electrumabc_plugins/satochip/satochip.py @@ -891,22 +891,25 @@ def create_seed(self, wizard): wizard.seed_type = "bip39" wizard.opt_bip39 = True seed = self.to_bip39_mnemonic(128) - f = lambda x: self.request_passphrase(wizard, seed, x) - wizard.show_seed_dialog(run_next=f, seed_text=seed) + wizard.show_seed_dialog( + run_next=lambda x: self.request_passphrase(wizard, seed, x), seed_text=seed + ) def request_passphrase(self, wizard, seed, opt_passphrase): if opt_passphrase: - f = lambda x: self.confirm_seed(wizard, seed, x) - wizard.passphrase_dialog(run_next=f) + wizard.passphrase_dialog( + run_next=lambda x: self.confirm_seed(wizard, seed, x) + ) else: wizard.run("confirm_seed", seed, "") def confirm_seed(self, wizard, seed, passphrase): - f = lambda x: self.confirm_passphrase(wizard, seed, passphrase) - wizard.confirm_seed_dialog(run_next=f, test=lambda x: x == seed) + wizard.confirm_seed_dialog( + run_next=lambda x: self.confirm_passphrase(wizard, seed, passphrase), + test=lambda x: x == seed, + ) def confirm_passphrase(self, wizard, seed, passphrase): - f = lambda x: self.derive_bip39_seed(seed, x) if passphrase: title = _("Confirm Seed Extension") message = "\n".join( @@ -916,29 +919,33 @@ def confirm_passphrase(self, wizard, seed, passphrase): ] ) wizard.line_dialog( - run_next=f, + run_next=lambda x: self.derive_bip39_seed(seed, x), title=title, message=message, default="", test=lambda x: x == passphrase, ) else: - f("") + self.derive_bip39_seed(seed, "") # restore from seed def restore_from_seed(self, wizard): wizard.opt_bip39 = True wizard.opt_ext = True test = is_seed - f = lambda seed, is_bip39, is_ext: self.on_restore_seed( - wizard, seed, is_bip39, is_ext - ) + + def f(seed, is_bip39, is_ext): + self.on_restore_seed(wizard, seed, is_bip39, is_ext) + wizard.restore_seed_dialog(run_next=f, test=test) def on_restore_seed(self, wizard, seed, is_bip39, is_ext): wizard.seed_type = "bip39" if is_bip39 else seed_type_name(seed) if wizard.seed_type == "bip39": - f = lambda passphrase: self.derive_bip39_seed(seed, passphrase) + + def f(passphrase): + self.derive_bip39_seed(seed, passphrase) + wizard.passphrase_dialog(run_next=f) if is_ext else f("") elif wizard.seed_type in ["standard", "electrum"]: # warning message as Electrum seed on hardware is not standard and incompatible with other hw @@ -962,7 +969,10 @@ def on_restore_seed(self, wizard, seed, is_bip39, is_ext): ] ) wizard.confirm_dialog("Warning", message, run_next=lambda x: None) - f = lambda passphrase: self.derive_bip32_seed(seed, passphrase) + + def f(passphrase): + self.derive_bip32_seed(seed, passphrase) + wizard.passphrase_dialog(run_next=f) if is_ext else f("") elif wizard.seed_type == "old": raise Exception("Unsupported seed type", wizard.seed_type) diff --git a/scripts/block_headers b/scripts/block_headers index 5e58cd1f755d..29761b753c70 100755 --- a/scripts/block_headers +++ b/scripts/block_headers @@ -10,6 +10,11 @@ from electrumabc.printerror import print_msg from electrumabc.simple_config import SimpleConfig from electrumabc.util import json_encode + +def callback(response): + print_msg(json_encode(response.get("result"))) + + # start network c = SimpleConfig() network = Network(c) @@ -23,8 +28,8 @@ if not network.is_connected(): print_msg("daemon is not connected") sys.exit(1) + # 2. send the subscription -callback = lambda response: print_msg(json_encode(response.get("result"))) network.send([("server.version", ["block_headers script", "1.2"])], callback) network.send([("blockchain.headers.subscribe", [])], callback) diff --git a/scripts/watch_address b/scripts/watch_address index 3c4d0bebd18a..c3e7e8731e5e 100755 --- a/scripts/watch_address +++ b/scripts/watch_address @@ -9,6 +9,11 @@ from electrumabc.printerror import print_msg from electrumabc.simple_config import SimpleConfig from electrumabc.util import json_encode + +def callback(response): + print_msg(json_encode(response.get("result"))) + + try: addr = Address.from_string(sys.argv[1]) except Exception: @@ -30,7 +35,6 @@ if not network.is_connected(): # 2. send the subscription sh = addr.to_scripthash_hex() -callback = lambda response: print_msg(json_encode(response.get("result"))) network.send([("blockchain.scripthash.subscribe", [sh])], callback) # 3. wait for results From 960d2b5f71163c8da83eae1eb8dcb669bbd1a000 Mon Sep 17 00:00:00 2001 From: PiRK Date: Fri, 13 Jan 2023 12:59:05 +0100 Subject: [PATCH 5/9] don't inherit, raise or catch BaseException BaseException is the base class for all builtin exceptions, including stuff like SystemExit and KeyboardInterrupt. It is rarely a good idea to catch those. This is equivalent to bare except clauses (see next commit) The official python documentation explicitely says to not directly inherit this for custom exceptions, but inherit Exception instead. When it comes to explicitely raising an error, RuntimeError is generic enough and can be caught with a generic `except Exception`. --- contrib/build-wine/deterministic.spec | 2 +- contrib/osx/osx.spec | 2 +- electrum-abc | 2 +- electrumabc/avalanche/delegation.py | 2 +- electrumabc/base_wizard.py | 12 +++++----- electrumabc/bitcoin.py | 2 +- electrumabc/commands.py | 14 ++++++------ electrumabc/dnssec.py | 6 ++--- electrumabc/interface.py | 2 +- electrumabc/jsonrpc.py | 2 +- electrumabc/network.py | 6 ++--- electrumabc/paymentrequest.py | 14 ++++++------ electrumabc/plugins.py | 10 ++++----- electrumabc/simple_config.py | 4 ++-- electrumabc/tests/test_transaction.py | 2 +- electrumabc/tests/test_util.py | 6 ++--- electrumabc/transaction.py | 4 ++-- electrumabc/util.py | 2 +- electrumabc/wallet.py | 4 ++-- electrumabc/x509.py | 2 +- electrumabc_gui/qt/__init__.py | 8 +++---- electrumabc_gui/qt/address_dialog.py | 4 ++-- electrumabc_gui/qt/console.py | 4 ++-- electrumabc_gui/qt/installwizard.py | 4 ++-- electrumabc_gui/qt/main_window.py | 22 +++++++++---------- electrumabc_gui/qt/scan_beyond_gap.py | 2 +- .../digitalbitbox/digitalbitbox.py | 8 +++---- electrumabc_plugins/keepkey/clientbase.py | 4 ++-- electrumabc_plugins/keepkey/keepkey.py | 8 +++---- electrumabc_plugins/labels/labels.py | 6 ++--- electrumabc_plugins/ledger/ledger.py | 8 +++---- electrumabc_plugins/trezor/clientbase.py | 4 ++-- electrumabc_plugins/trezor/trezor.py | 6 ++--- 33 files changed, 94 insertions(+), 94 deletions(-) diff --git a/contrib/build-wine/deterministic.spec b/contrib/build-wine/deterministic.spec index 9205e16fa42f..e94ab024d859 100644 --- a/contrib/build-wine/deterministic.spec +++ b/contrib/build-wine/deterministic.spec @@ -8,7 +8,7 @@ for i, x in enumerate(sys.argv): cmdline_name = sys.argv[i+1] break else: - raise BaseException('no name') + raise RuntimeError('no name') home = 'C:\\electrumabc\\' diff --git a/contrib/osx/osx.spec b/contrib/osx/osx.spec index 454784d82f19..b4bd1ead53b5 100644 --- a/contrib/osx/osx.spec +++ b/contrib/osx/osx.spec @@ -16,7 +16,7 @@ for i, x in enumerate(sys.argv): VERSION = sys.argv[i+1] break else: - raise BaseException('no version') + raise Exception('no version') home = os.path.abspath(".") + "/" block_cipher = None diff --git a/electrum-abc b/electrum-abc index 4f3ed8738e48..dc461ca612d8 100755 --- a/electrum-abc +++ b/electrum-abc @@ -567,7 +567,7 @@ def main(): for i, arg in enumerate(sys.argv): if arg == "-": if sys.stdin.isatty(): - raise BaseException("Cannot get argument from stdin") + raise RuntimeError("Cannot get argument from stdin") sys.argv[i] = sys.stdin.read() break if arg == "?": diff --git a/electrumabc/avalanche/delegation.py b/electrumabc/avalanche/delegation.py index 913aacad679f..4d79de7d1cdd 100644 --- a/electrumabc/avalanche/delegation.py +++ b/electrumabc/avalanche/delegation.py @@ -42,7 +42,7 @@ ) -class WrongDelegatorKeyError(BaseException): +class WrongDelegatorKeyError(Exception): pass diff --git a/electrumabc/base_wizard.py b/electrumabc/base_wizard.py index 6564f0c0f2f5..bc0fee476c2a 100644 --- a/electrumabc/base_wizard.py +++ b/electrumabc/base_wizard.py @@ -92,7 +92,7 @@ def run(self, *args, **kwargs): f = getattr(self, action) f(*args, **kwargs) else: - raise BaseException("unknown action", action) + raise RuntimeError("unknown action", action) def can_go_back(self): return len(self._stack) > 1 @@ -236,7 +236,7 @@ def on_import(self, text): for addr in text.split(): try: Address.from_string(addr) - except BaseException: + except Exception: pass else: self.data["addresses"][addr] = {} @@ -426,7 +426,7 @@ def on_device(self, name, device_info: DeviceInfo, *, purpose, storage=None): except (GoBack, util.UserCancelled): self.choose_hw_device(purpose, storage=storage) return - except BaseException: + except Exception: self.choose_hw_device(purpose, storage=storage) return @@ -515,7 +515,7 @@ def on_hw_derivation(self, name, device_info: DeviceInfo, derivation): xpub = self.plugin.get_xpub(device_info.device.id_, derivation, xtype, self) client = devmgr.client_by_id(device_info.device.id_, scan_now=False) label = client.label() - except BaseException as e: + except Exception as e: self.print_error(traceback.format_exc()) self.show_error(str(e)) return @@ -579,7 +579,7 @@ def f(passphrase): elif self.seed_type == "old": self.run("create_keystore", seed, "") else: - raise BaseException("Unknown seed type", self.seed_type) + raise RuntimeError("Unknown seed type", self.seed_type) def on_restore_bip39(self, seed, passphrase): self.derivation_dialog( @@ -662,7 +662,7 @@ def create_wallet(self): devmgr.unpair_xpub(k.xpub) self.choose_hw_device() return - except BaseException as e: + except Exception as e: traceback.print_exc(file=sys.stderr) self.show_error(str(e)) return diff --git a/electrumabc/bitcoin.py b/electrumabc/bitcoin.py index 8a284211a949..e4a6c805f568 100644 --- a/electrumabc/bitcoin.py +++ b/electrumabc/bitcoin.py @@ -1145,7 +1145,7 @@ def serialize_xpub( return EncodeBase58Check(xpub) -class InvalidXKey(BaseException): +class InvalidXKey(Exception): pass diff --git a/electrumabc/commands.py b/electrumabc/commands.py index f233ed87171b..194a38191fd4 100644 --- a/electrumabc/commands.py +++ b/electrumabc/commands.py @@ -118,9 +118,9 @@ def func_wrapper(*args, **kwargs): network = args[0].network password = kwargs.get("password") if c.requires_network and network is None: - raise BaseException("Daemon offline") # Same wording as in daemon.py. + raise RuntimeError("Daemon offline") # Same wording as in daemon.py. if c.requires_wallet and wallet is None: - raise BaseException( + raise RuntimeError( f"Wallet not loaded. Use '{SCRIPT_NAME}" f" daemon load_wallet'" ) if ( @@ -604,7 +604,7 @@ def importprivkey(self, privkey, password=None): try: addr = self.wallet.import_private_key(privkey, password) out = "Keypair imported: " + addr - except BaseException as e: + except Exception as e: out = "Error: " + str(e) return out @@ -617,7 +617,7 @@ def _resolver(self, x): and self.nocheck is False and out.get("validated") is False ): - raise BaseException("cannot verify alias", x) + raise RuntimeError("cannot verify alias", x) return out["address"] @command("n") @@ -928,7 +928,7 @@ def gettransaction(self, txid): if raw: tx = Transaction(raw) else: - raise BaseException("Unknown transaction") + raise RuntimeError("Unknown transaction") return tx.as_dict() @command("") @@ -976,7 +976,7 @@ def getrequest(self, key): """Return a payment request""" r = self.wallet.get_payment_request(Address.from_string(key), self.config) if not r: - raise BaseException("Request not found") + raise RuntimeError("Request not found") return self._format_request(r) # @command('w') @@ -1088,7 +1088,7 @@ def callback(x): req = urllib.request.Request(URL, serialized_data, headers) urllib.request.urlopen(req, timeout=5) print_error("Got Response for %s" % address) - except BaseException as e: + except Exception as e: print_error(str(e)) h = Address.from_string(address).to_scripthash_hex() diff --git a/electrumabc/dnssec.py b/electrumabc/dnssec.py index 424f36ab9c09..2d230310faea 100644 --- a/electrumabc/dnssec.py +++ b/electrumabc/dnssec.py @@ -231,7 +231,7 @@ def check_query(ns, sub, _type, keys): elif answer[1].rdtype == dns.rdatatype.RRSIG: rrset, rrsig = answer else: - raise BaseException("No signature set in record") + raise RuntimeError("No signature set in record") if keys is None: keys = {dns.name.from_text(sub): rrset} dns.dnssec.validate(rrset, rrsig, keys) @@ -284,7 +284,7 @@ def get_and_validate(ns, url, _type): continue break else: - raise BaseException("DS does not match DNSKEY") + raise RuntimeError("DS does not match DNSKEY") # set key for next iteration keys = {name: rrset} # get TXT record (signed by zone) @@ -299,7 +299,7 @@ def query(url, rtype): try: out = get_and_validate(ns, url, rtype) validated = True - except BaseException as e: + except Exception as e: # traceback.print_exc(file=sys.stderr) print_error("DNSSEC error:", str(e)) resolver = dns.resolver.get_default_resolver() diff --git a/electrumabc/interface.py b/electrumabc/interface.py index c9c0faf23571..c19da3207048 100644 --- a/electrumabc/interface.py +++ b/electrumabc/interface.py @@ -120,7 +120,7 @@ def get_simple_socket(self): s.settimeout(2) s.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) return s - except BaseException as _e: + except Exception as _e: e = _e continue else: diff --git a/electrumabc/jsonrpc.py b/electrumabc/jsonrpc.py index c3f7102c3b60..838256d59a71 100644 --- a/electrumabc/jsonrpc.py +++ b/electrumabc/jsonrpc.py @@ -71,7 +71,7 @@ def parse_request(myself): RPCAuthUnsupportedType, ) as e: myself.send_error(401, str(e)) - except BaseException as e: + except Exception as e: import sys import traceback diff --git a/electrumabc/network.py b/electrumabc/network.py index d2a9b9646eae..fa6dfe45c681 100644 --- a/electrumabc/network.py +++ b/electrumabc/network.py @@ -2072,7 +2072,7 @@ def follow_chain(self, index): self.switch_to_interface(i.server, self.SWITCH_FOLLOW_CHAIN) break else: - raise BaseException("blockchain not found", index) + raise RuntimeError("blockchain not found", index) with self.interface_lock: if self.interface: @@ -2113,7 +2113,7 @@ def get_raw_tx_for_txid(self, txid, timeout=30): ("blockchain.transaction.get", [txid]), timeout=timeout ) return True, r - except BaseException as e: + except Exception as e: self.print_error( "Exception retrieving transaction for '{}': {}".format(txid, repr(e)) ) @@ -2177,7 +2177,7 @@ def broadcast_transaction(self, transaction, callback=None): try: out = self.broadcast_transaction2(transaction) - except BaseException as e: # catch-all. May be util.TimeoutException, util.ServerError subclass or other. + except Exception as e: # catch-all. May be util.TimeoutException, util.ServerError subclass or other. return False, "error: " + str( e ) # Ergh. To remain compatible with old code we prepend this ugly "error: " diff --git a/electrumabc/paymentrequest.py b/electrumabc/paymentrequest.py index 70edc0ffed74..332ecd3113cf 100644 --- a/electrumabc/paymentrequest.py +++ b/electrumabc/paymentrequest.py @@ -200,7 +200,7 @@ def verify_x509(self, paymntreq): # verify the chain of certificates try: x, ca = verify_cert_chain(cert.certificate) - except BaseException as e: + except Exception as e: traceback.print_exc(file=sys.stderr) self.error = str(e) return False @@ -428,9 +428,9 @@ def verify_cert_chain(chain): x.check_date() else: if not x.check_ca(): - raise BaseException("ERROR: Supplied CA Certificate Error") + raise RuntimeError("ERROR: Supplied CA Certificate Error") if not cert_num > 1: - raise BaseException( + raise RuntimeError( "ERROR: CA Certificate Chain Not Provided by Payment Processor" ) # if the root CA is not supplied, add it to the chain @@ -442,7 +442,7 @@ def verify_cert_chain(chain): root = ca_list[f] x509_chain.append(root) else: - raise BaseException("Supplied CA Not Found in Trusted CA Store.") + raise RuntimeError("Supplied CA Not Found in Trusted CA Store.") # verify the chain of signatures cert_num = len(x509_chain) for i in range(1, cert_num): @@ -463,9 +463,9 @@ def verify_cert_chain(chain): hashBytes = bytearray(hashlib.sha512(data).digest()) verify = pubkey.verify(sig, x509.PREFIX_RSA_SHA512 + hashBytes) else: - raise BaseException("Algorithm not supported") + raise RuntimeError("Algorithm not supported") if not verify: - raise BaseException( + raise RuntimeError( "Certificate not Signed by Provided CA Certificate Chain" ) @@ -576,7 +576,7 @@ def import_file(self, path): except json.decoder.JSONDecodeError: traceback.print_exc(file=sys.stderr) raise FileImportFailedEncrypted() - except BaseException: + except Exception: traceback.print_exc(file=sys.stdout) raise FileImportFailed() self.save() diff --git a/electrumabc/plugins.py b/electrumabc/plugins.py index 989bb2880fdc..d3da405f4c74 100644 --- a/electrumabc/plugins.py +++ b/electrumabc/plugins.py @@ -201,7 +201,7 @@ def load_internal_plugins(self): if not d.get("requires_wallet_type") and conf_value: try: self.load_internal_plugin(name) - except BaseException as e: + except Exception as e: fmt = traceback.format_exc() self.print_error(f"cannot initialize plugin {name}: {e!r} {fmt}") @@ -238,7 +238,7 @@ def load_external_plugins(self): ): try: self.load_external_plugin(package_name) - except BaseException as e: + except Exception as e: traceback.print_exc( file=sys.stdout ) # shouldn't this be... suppressed unless -v? @@ -502,7 +502,7 @@ def install_external_plugin(self, plugin_original_path): # plugin to be loaded, afterward. try: self.enable_external_plugin(package_name) - except BaseException as e: + except Exception as e: traceback.print_exc(file=sys.stdout) self.print_error( "cannot enable/load external plugin %s:" % package_name, str(e) @@ -1012,7 +1012,7 @@ def client_for_keystore( ) -> Optional[HardwareClientBase]: self.print_error("getting client for keystore") if handler is None: - raise BaseException( + raise RuntimeError( _("Handler not found for") + " " + plugin.name @@ -1222,7 +1222,7 @@ def scan_devices(self) -> List["Device"]: for f in self.enumerate_func: try: new_devices = f() - except BaseException as e: + except Exception as e: self.print_error( "custom device enum failed. func {}, error {}".format( str(f), str(e) diff --git a/electrumabc/simple_config.py b/electrumabc/simple_config.py index bdc77ddd2e09..34443f141136 100644 --- a/electrumabc/simple_config.py +++ b/electrumabc/simple_config.py @@ -172,7 +172,7 @@ def convert_version_2(self): int(port) # Throw if cannot be converted to int server_str = str("{}:{}:s".format(host, port)) self._set_key_in_user_config("server", server_str) - except BaseException: + except Exception: self._set_key_in_user_config("server", None) self.set_key("config_version", 2) @@ -182,7 +182,7 @@ def _is_upgrade_method_needed(self, min_version, max_version): if cur_version > max_version: return False elif cur_version < min_version: - raise BaseException( + raise RuntimeError( ( "config upgrade: unexpected version %d (should be %d-%d)" % (cur_version, min_version, max_version) diff --git a/electrumabc/tests/test_transaction.py b/electrumabc/tests/test_transaction.py index 910b59d6f871..831473659074 100644 --- a/electrumabc/tests/test_transaction.py +++ b/electrumabc/tests/test_transaction.py @@ -257,7 +257,7 @@ def test_tx_nonminimal_scriptSig(self): ) def test_errors(self): - with self.assertRaises(BaseException): + with self.assertRaises(Exception): xpubkey_to_address("") def test_parse_xpub(self): diff --git a/electrumabc/tests/test_util.py b/electrumabc/tests/test_util.py index 340a06a6f0d6..fb192271d100 100644 --- a/electrumabc/tests/test_util.py +++ b/electrumabc/tests/test_util.py @@ -284,12 +284,12 @@ def test_parse_URI_no_address_request_url(self): ) def test_parse_URI_invalid_address(self): - self.assertRaises(BaseException, parse_URI, "bitcoincash:invalidaddress") - self.assertRaises(BaseException, parse_URI, "ecash:invalidaddress") + self.assertRaises(Exception, parse_URI, "bitcoincash:invalidaddress") + self.assertRaises(Exception, parse_URI, "ecash:invalidaddress") def test_parse_URI_invalid(self): self.assertRaises( - BaseException, parse_URI, "notvalid:15mKKb2eos1hWa6tisdPwwDC1a5J1y9nma" + Exception, parse_URI, "notvalid:15mKKb2eos1hWa6tisdPwwDC1a5J1y9nma" ) def test_parse_URI_parameter_polution(self): diff --git a/electrumabc/transaction.py b/electrumabc/transaction.py index 4f130305dcea..0efb30e0a936 100644 --- a/electrumabc/transaction.py +++ b/electrumabc/transaction.py @@ -461,7 +461,7 @@ def __init__(self, raw, sign_schnorr=False): elif isinstance(raw, dict): self.raw = raw["hex"] else: - raise BaseException("cannot initialize transaction", raw) + raise RuntimeError("cannot initialize transaction", raw) self._inputs = None self._outputs = None self.locktime = 0 @@ -1060,7 +1060,7 @@ def verify_signature(pubkey, sig, msghash, reason=None): # verify_digest may also raise BadDigestError and BadSignatureError if isinstance(reason, list): reason.insert(0, repr(e)) - except BaseException as e: + except Exception as e: print_error( "[Transaction.verify_signature] unexpected exception", repr(e) ) diff --git a/electrumabc/util.py b/electrumabc/util.py index f0e7ea51303b..78a000b5cbef 100644 --- a/electrumabc/util.py +++ b/electrumabc/util.py @@ -437,7 +437,7 @@ def make_dir(path): # Make directory if it does not yet exist. if not os.path.exists(path): if os.path.islink(path): - raise BaseException("Dangling link: " + path) + raise RuntimeError("Dangling link: " + path) os.mkdir(path) os.chmod(path, stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR) diff --git a/electrumabc/wallet.py b/electrumabc/wallet.py index 635f8cfe9660..4d8dd56674a1 100644 --- a/electrumabc/wallet.py +++ b/electrumabc/wallet.py @@ -2039,7 +2039,7 @@ def make_unsigned_transaction( _type, data, value = o if value == "!": if i_max is not None: - raise BaseException("More than one output set to spend max") + raise RuntimeError("More than one output set to spend max") i_max = i # Avoid index-out-of-range with inputs[0] below @@ -2047,7 +2047,7 @@ def make_unsigned_transaction( raise NotEnoughFunds() if fixed_fee is None and config.fee_per_kb() is None: - raise BaseException("Dynamic fee estimates not available") + raise RuntimeError("Dynamic fee estimates not available") for item in inputs: self.add_input_info(item) diff --git a/electrumabc/x509.py b/electrumabc/x509.py index a19da9b38a7e..3f9764217a16 100644 --- a/electrumabc/x509.py +++ b/electrumabc/x509.py @@ -410,7 +410,7 @@ def load_certificates(ca_path): try: x = X509(b) x.check_date() - except BaseException as e: + except Exception as e: # with open('/tmp/tmp.txt', 'w') as f: # f.write(pem.pem(b, 'CERTIFICATE').decode('ascii')) print_error("cert error:", e) diff --git a/electrumabc_gui/qt/__init__.py b/electrumabc_gui/qt/__init__.py index d3f72476d947..7c54090ea2e1 100644 --- a/electrumabc_gui/qt/__init__.py +++ b/electrumabc_gui/qt/__init__.py @@ -387,7 +387,7 @@ def set_dark_theme_if_needed(self): self.print_error( "Warning: Could not determine qdarkstyle version:", repr(e) ) - except BaseException as e: + except Exception as e: use_dark_theme = False self.print_error("Error setting dark theme: {}".format(repr(e))) # Apply any necessary stylesheet patches @@ -697,7 +697,7 @@ def start_new_window(self, path, uri, *, app_is_starting=False): wallet = self.daemon.load_wallet(path, None) if wallet is not None: self.daemon.cmd_runner.wallet = wallet - except BaseException as e: + except Exception as e: traceback.print_exc(file=sys.stdout) QtWidgets.QMessageBox.warning( None, _("Error"), _("Cannot load wallet") + " (1):\n" + str(e) @@ -727,7 +727,7 @@ def start_new_window(self, path, uri, *, app_is_starting=False): window.bring_to_top() return window = self._create_window_for_wallet(wallet) - except BaseException as e: + except Exception as e: traceback.print_exc(file=sys.stdout) QtWidgets.QMessageBox.warning( None, _("Error"), _("Cannot create window for wallet:") + "\n" + str(e) @@ -1147,7 +1147,7 @@ def main(self): return except GoBack: return - except BaseException: + except Exception: traceback.print_exc(file=sys.stdout) return self.timer.start() diff --git a/electrumabc_gui/qt/address_dialog.py b/electrumabc_gui/qt/address_dialog.py index 18dab68088d3..36d075af1484 100644 --- a/electrumabc_gui/qt/address_dialog.py +++ b/electrumabc_gui/qt/address_dialog.py @@ -75,7 +75,7 @@ def __init__(self, parent, address, *, windowParent=None): try: # the below line only works for deterministic wallets, other wallets lack this method pubkeys = self.wallet.get_public_keys(address) - except BaseException: + except Exception: try: # ok, now try the usual method for imported wallets, etc pubkey = self.wallet.get_public_key(address) @@ -92,7 +92,7 @@ def __init__(self, parent, address, *, windowParent=None): try: redeem_script = self.wallet.pubkeys_to_redeem_script(pubkeys) - except BaseException: + except Exception: redeem_script = None if redeem_script: vbox.addWidget(QtWidgets.QLabel(_("Redeem Script") + ":")) diff --git a/electrumabc_gui/qt/console.py b/electrumabc_gui/qt/console.py index ffbc3d5741ac..c04a4915da5b 100644 --- a/electrumabc_gui/qt/console.py +++ b/electrumabc_gui/qt/console.py @@ -451,8 +451,8 @@ def write(self, text): exec(command, self.namespace, self.namespace) except SystemExit: self.close() - except (Exception, BaseException): - # Catch errors in the network layer as well, as long as it uses BaseException. + except Exception: + # Catch errors in the network layer as well traceback_lines = traceback.format_exc().split("\n") # Remove traceback mentioning this file, and a linebreak for i in (3, 2, 1, -1): diff --git a/electrumabc_gui/qt/installwizard.py b/electrumabc_gui/qt/installwizard.py index d95cfc940bf9..10e940a250a6 100644 --- a/electrumabc_gui/qt/installwizard.py +++ b/electrumabc_gui/qt/installwizard.py @@ -324,7 +324,7 @@ def on_filename(filename): except InvalidPassword as e: QtWidgets.QMessageBox.information(None, _("Error"), str(e)) continue - except BaseException as e: + except Exception as e: traceback.print_exc(file=sys.stdout) QtWidgets.QMessageBox.information(None, _("Error"), str(e)) raise UserCancelled() @@ -347,7 +347,7 @@ def on_filename(filename): return self.select_storage(path, get_wallet_from_daemon) except (UserCancelled, GoBack): raise - except BaseException as e: + except Exception as e: traceback.print_exc(file=sys.stdout) QtWidgets.QMessageBox.information(None, _("Error"), str(e)) raise UserCancelled() diff --git a/electrumabc_gui/qt/main_window.py b/electrumabc_gui/qt/main_window.py index d471dbd3992e..b9ce37865c4a 100644 --- a/electrumabc_gui/qt/main_window.py +++ b/electrumabc_gui/qt/main_window.py @@ -2232,7 +2232,7 @@ def do_update_fee(self): except OPReturn.Error as e: self.statusBar().showMessage(str(e)) return - except BaseException: + except Exception: return if not freeze_fee: @@ -2576,7 +2576,7 @@ def do_send(self, preview=False): except ExcessiveFee: self.show_message(_("Your fee is too high. Max is 50 sat/byte.")) return - except BaseException as e: + except Exception as e: traceback.print_exc(file=sys.stderr) self.show_message(str(e)) return @@ -3400,7 +3400,7 @@ def change_password_dialog(self): hw_dev_pw = self.wallet.keystore.get_password_for_storage_encryption() except UserCancelled: return - except BaseException as e: + except Exception as e: traceback.print_exc(file=sys.stderr) self.show_error(str(e)) return @@ -3418,7 +3418,7 @@ def change_password_dialog(self): self.wallet, None ) # clear password cache when user changes it, just in case run_hook("on_new_password", self, old_password, new_password) - except BaseException as e: + except Exception as e: self.show_error(str(e)) return except: @@ -3572,7 +3572,7 @@ def show_seed_dialog(self, password): seed_type = getattr(keystore, "seed_type", "") if derivation == "m/" and seed_type in ["electrum", "standard"]: derivation = None # suppress Electrum seed 'm/' derivation from UI - except BaseException as e: + except Exception as e: self.show_error(str(e)) return @@ -3704,7 +3704,7 @@ def do_encrypt(self, message_e, pubkey_e, encrypted_e): try: encrypted = bitcoin.encrypt_message(message, pubkey_e.text()) encrypted_e.setText(encrypted.decode("ascii")) - except BaseException as e: + except Exception as e: if util.is_verbose: traceback.print_exc(file=sys.stderr) self.show_warning(str(e)) @@ -3821,14 +3821,14 @@ def _on_qr_reader_finished(success: bool, error: str, result): tx = self.tx_from_text(result) # will show an error dialog on error if not tx: return - except BaseException as e: + except Exception as e: self.show_error(str(e)) return self.show_transaction(tx) self._qr_dialog.qr_finished.connect(_on_qr_reader_finished) self._qr_dialog.start_scan(get_config().get_video_device()) - except BaseException as e: + except Exception as e: if util.is_verbose: traceback.print_exc(file=sys.stderr) self._qr_dialog = None @@ -4619,7 +4619,7 @@ def enable_sweep(): self.payto_e.setText(get_address_text()) self.spend_coins(coins) self.spend_max() - except BaseException as e: + except Exception as e: self.show_message(str(e)) return self.payto_e.setFrozen(True) @@ -4638,7 +4638,7 @@ def _do_import(self, title, msg, func): try: addr = func(key) good.append(addr) - except BaseException as e: + except Exception as e: bad.append(key) bad_info.append("{}: {}".format(key, str(e))) continue @@ -4902,7 +4902,7 @@ def on_alias_edit(): try: SSL_identity = paymentrequest.check_ssl_config(self.config) SSL_error = None - except BaseException as e: + except Exception as e: SSL_identity = "error" SSL_error = str(e) else: diff --git a/electrumabc_gui/qt/scan_beyond_gap.py b/electrumabc_gui/qt/scan_beyond_gap.py index 6464e316c91f..36e417dc3859 100644 --- a/electrumabc_gui/qt/scan_beyond_gap.py +++ b/electrumabc_gui/qt/scan_beyond_gap.py @@ -283,5 +283,5 @@ def scan_thread(self): # Suppress untrusted server string from appearing in the UI self.print_error("Server error:", repr(e)) self.done_sig.emit(None, ServerError("The server replied with an error.")) - except BaseException as e: + except Exception as e: self.done_sig.emit(None, e) diff --git a/electrumabc_plugins/digitalbitbox/digitalbitbox.py b/electrumabc_plugins/digitalbitbox/digitalbitbox.py index 1821ed9fd2ad..1e2a6b31eb50 100644 --- a/electrumabc_plugins/digitalbitbox/digitalbitbox.py +++ b/electrumabc_plugins/digitalbitbox/digitalbitbox.py @@ -103,7 +103,7 @@ def is_paired(self): def has_usable_connection_with_device(self): try: self.dbb_has_password() - except BaseException: + except Exception: return False return True @@ -118,7 +118,7 @@ def get_xpub(self, bip32_path, xtype): xpub = reply["xpub"] return xpub else: - raise BaseException("no reply") + raise RuntimeError("no reply") def dbb_has_password(self): reply = self.hid_send_plain(b'{"ping":""}') @@ -605,7 +605,7 @@ def sign_message(self, sequence, message, password, sigtype=SignatureType.BITCOI else: raise Exception(_("Could not sign message")) - except BaseException as e: + except Exception as e: self.give_error(e) return sig @@ -790,7 +790,7 @@ def input_script( tx._inputs[i] = txin except UserCancelled: raise - except BaseException as e: + except Exception as e: self.give_error(e, True) else: print_error("Transaction is_complete", tx.is_complete()) diff --git a/electrumabc_plugins/keepkey/clientbase.py b/electrumabc_plugins/keepkey/clientbase.py index 8ab63320c81b..b1fd642e8a4e 100644 --- a/electrumabc_plugins/keepkey/clientbase.py +++ b/electrumabc_plugins/keepkey/clientbase.py @@ -135,7 +135,7 @@ def has_usable_connection_with_device(self): try: res = self.ping("electrum-abc pinging device") # FIXME: Add some randomness assert res == "electrum-abc pinging device" - except BaseException: + except Exception: return False return True @@ -221,7 +221,7 @@ def clear_session(self): self.prevent_timeouts() try: super(KeepKeyClientBase, self).clear_session() - except BaseException as e: + except Exception as e: # If the device was removed it has the same effect... self.print_error("clear_session: ignoring error", str(e)) pass diff --git a/electrumabc_plugins/keepkey/keepkey.py b/electrumabc_plugins/keepkey/keepkey.py index daa0f25533cd..e8890a7505b8 100644 --- a/electrumabc_plugins/keepkey/keepkey.py +++ b/electrumabc_plugins/keepkey/keepkey.py @@ -167,7 +167,7 @@ def _try_hid(self, device): try: return self.hid_transport(pair) - except BaseException as e: + except Exception as e: # see fdb810ba622dc7dbe1259cbafb5b28e19d2ab114 # raise self.print_error(f"cannot connect at {device.path} {e}") @@ -177,7 +177,7 @@ def _try_webusb(self, device): self.print_error("Trying to connect over WebUSB...") try: return self.webusb_transport(device) - except BaseException as e: + except Exception as e: self.print_error(f"cannot connect at {device.path} {e}") return None @@ -198,7 +198,7 @@ def create_client(self, device, handler): # Try a ping for device sanity try: client.ping("t") - except BaseException as e: + except Exception as e: self.print_error(f"ping failed {e}") return None @@ -275,7 +275,7 @@ def _initialize_device_safe(self, settings, method, device_id, wizard, handler): self._initialize_device(settings, method, device_id, wizard, handler) except UserCancelled: exit_code = 1 - except BaseException as e: + except Exception as e: self.print_error(str(e)) handler.show_error(str(e)) exit_code = 1 diff --git a/electrumabc_plugins/labels/labels.py b/electrumabc_plugins/labels/labels.py index 0396f05a2889..16ce9969675c 100644 --- a/electrumabc_plugins/labels/labels.py +++ b/electrumabc_plugins/labels/labels.py @@ -98,12 +98,12 @@ def do_request(self, method, url="/labels", is_batch=False, data=None, noexc=Fal self.on_wallet_not_synched(wallet) return if response.status_code != 200: - raise BaseException(response.status_code, response.text) + raise RuntimeError(response.status_code, response.text) response = response.json() if "error" in response: - raise BaseException(response["error"]) + raise RuntimeError(response["error"]) return response - except BaseException as e: + except Exception as e: if noexc: wallet = self.find_wallet_by_id(wallet_id) if wallet: diff --git a/electrumabc_plugins/ledger/ledger.py b/electrumabc_plugins/ledger/ledger.py index 482455f766ca..1898a6399b66 100644 --- a/electrumabc_plugins/ledger/ledger.py +++ b/electrumabc_plugins/ledger/ledger.py @@ -121,7 +121,7 @@ def has_usable_connection_with_device(self): # communicate with the device, so we return True here. return True return False - except BaseException: + except Exception: return False return True @@ -296,7 +296,7 @@ def checkDevice(self): self.perform_hw1_preflight() except BTChipException as e: if e.sw == 0x6D00 or e.sw == 0x6700: - raise BaseException( + raise RuntimeError( _("{} not in Bitcoin Cash mode").format(self.device) ) from e raise e @@ -669,7 +669,7 @@ def sign_transaction(self, tx, password, *, use_cache=False): else: traceback.print_exc(file=sys.stderr) self.give_error(e, True) - except BaseException as e: + except Exception as e: traceback.print_exc(file=sys.stdout) self.give_error(e, True) finally: @@ -716,7 +716,7 @@ def show_address(self, sequence): else: traceback.print_exc(file=sys.stderr) self.handler.show_error(e) - except BaseException as e: + except Exception as e: traceback.print_exc(file=sys.stderr) self.handler.show_error(e) finally: diff --git a/electrumabc_plugins/trezor/clientbase.py b/electrumabc_plugins/trezor/clientbase.py index f3c71eb134ad..e4a960e56759 100644 --- a/electrumabc_plugins/trezor/clientbase.py +++ b/electrumabc_plugins/trezor/clientbase.py @@ -138,7 +138,7 @@ def has_usable_connection_with_device(self): try: self.client.init_device() - except BaseException: + except Exception: return False return True @@ -204,7 +204,7 @@ def clear_session(self): self.prevent_timeouts() try: self.client.clear_session() - except BaseException as e: + except Exception as e: # If the device was removed it has the same effect... self.print_error("clear_session: ignoring error", str(e)) diff --git a/electrumabc_plugins/trezor/trezor.py b/electrumabc_plugins/trezor/trezor.py index c905fd822fd5..4af07e9df2a7 100644 --- a/electrumabc_plugins/trezor/trezor.py +++ b/electrumabc_plugins/trezor/trezor.py @@ -205,7 +205,7 @@ def create_client(self, device, handler): try: self.print_error("connecting to device at", device.path) transport = trezorlib.transport.get_transport(device.path) - except BaseException as e: + except Exception as e: self.print_error("cannot connect at", device.path, str(e)) return None @@ -286,7 +286,7 @@ def f(method): exit_code = wizard.loop.exec_() loops.pop() if exit_code != 0: - if errors and isinstance(errors[0], BaseException): + if errors and isinstance(errors[0], Exception): msg = str(errors[0]).strip() if msg: # we do this here in the main thread so as to give @@ -310,7 +310,7 @@ def _initialize_device_safe(self, settings, method, device_id, loops, errors): self._initialize_device(settings, method, device_id) except UserCancelled: exit_code = 2 - except BaseException as e: + except Exception as e: traceback.print_exc(file=sys.stderr) errors.append(e) exit_code = 1 From f622873810e505d31cc849fa58bfa6a1355624d7 Mon Sep 17 00:00:00 2001 From: PiRK Date: Thu, 12 Jan 2023 14:14:53 +0100 Subject: [PATCH 6/9] [flake8] silence E722 errors (do not use bare except) I did this semi-automatically by just replacing bare exceptions with `except Exception`. It is still awful, but at least we no longer catch `KeyboardInterrupt` and `SystemExit`. Fixing this properly would take an enormous amount of work, understanding each one of the 100+ occurences to guess the correct exceptions to catch. This will have to be done the slow way, each occurence at a time when the code is touched for another reason. --- .pre-commit-config.yaml | 2 +- contrib/package_plugin.py | 2 +- electrumabc/address.py | 2 +- electrumabc/asert_daa.py | 2 +- electrumabc/base_wizard.py | 4 ++-- electrumabc/bitcoin.py | 12 ++++++------ electrumabc/commands.py | 2 +- electrumabc/contacts.py | 6 +++--- electrumabc/interface.py | 10 +++++----- electrumabc/json_db.py | 6 +++--- electrumabc/mnemo.py | 2 +- electrumabc/network.py | 10 +++++----- electrumabc/networks.py | 2 +- electrumabc/paymentrequest.py | 8 ++++---- electrumabc/plugins.py | 2 +- electrumabc/schnorr.py | 6 +++--- electrumabc/secp256k1.py | 4 ++-- electrumabc/slp/slp.py | 2 +- electrumabc/storage.py | 2 +- electrumabc/tor/controller.py | 6 +++--- electrumabc/transaction.py | 6 +++--- electrumabc/util.py | 8 ++++---- electrumabc/wallet.py | 8 ++++---- electrumabc/websockets.py | 2 +- electrumabc_gui/qt/address_dialog.py | 2 +- electrumabc_gui/qt/contact_list.py | 4 ++-- electrumabc_gui/qt/main_window.py | 14 +++++++------- electrumabc_gui/qt/paytoedit.py | 4 ++-- electrumabc_gui/qt/popup_widget.py | 4 ++-- electrumabc_gui/qt/qrtextedit.py | 2 +- electrumabc_gui/qt/transaction_dialog.py | 2 +- electrumabc_gui/qt/util.py | 4 ++-- electrumabc_plugins/digitalbitbox/digitalbitbox.py | 2 +- electrumabc_plugins/email_requests/qt.py | 2 +- electrumabc_plugins/fusion/comms.py | 10 +++++----- electrumabc_plugins/fusion/connection.py | 4 ++-- electrumabc_plugins/fusion/encrypt.py | 4 ++-- electrumabc_plugins/fusion/fusion.py | 4 ++-- electrumabc_plugins/fusion/pedersen.py | 2 +- electrumabc_plugins/fusion/server.py | 2 +- electrumabc_plugins/hw_wallet/qt.py | 2 +- electrumabc_plugins/labels/labels.py | 6 +++--- scripts/txradar | 2 +- 43 files changed, 96 insertions(+), 96 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 2969b7ae1233..5ab9f52c48bd 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -26,7 +26,7 @@ repos: args: - --max-line-length=88 - --select=E1,E2,E3,E4,E5,E7,E9,F4,F5,F6,F7,F8,W1,W2,W3,W504,W6 - - --ignore=E501,E722 # FIXME + - --ignore=E501 # FIXME - --extend-ignore=E203 # This one is incompatible with black additional_dependencies: - flake8-mutable diff --git a/contrib/package_plugin.py b/contrib/package_plugin.py index e1dbc4afaa26..27415838bbff 100755 --- a/contrib/package_plugin.py +++ b/contrib/package_plugin.py @@ -364,7 +364,7 @@ def on_export_manifest_clicked(self): self, "File Error", "Unable to write to selected file." ) return - except: + except Exception: QtWidgets.QMessageBox.critical( self, "Encoding Error", "Problem serialising json data." ) diff --git a/electrumabc/address.py b/electrumabc/address.py index d2929972e7df..b096d2981b4e 100644 --- a/electrumabc/address.py +++ b/electrumabc/address.py @@ -280,7 +280,7 @@ def lookup(x): # if too many escaped characters, it's too ugly! if friendlystring.count("\\") * 3 > len(astext): friendlystring = None - except: + except Exception: friendlystring = None if not friendlystring: diff --git a/electrumabc/asert_daa.py b/electrumabc/asert_daa.py index 1146f142471e..58461e8250d8 100644 --- a/electrumabc/asert_daa.py +++ b/electrumabc/asert_daa.py @@ -47,7 +47,7 @@ def _get_asert_activation_mtp(): mtp = os.environ.get("ASERT_MTP", default_mtp) try: mtp = int(mtp) - except: + except Exception: pass if not isinstance(mtp, int) or mtp <= 1510600000: print_error( diff --git a/electrumabc/base_wizard.py b/electrumabc/base_wizard.py index bc0fee476c2a..f5d21308d8ae 100644 --- a/electrumabc/base_wizard.py +++ b/electrumabc/base_wizard.py @@ -326,7 +326,7 @@ def choose_hw_device(self, purpose=HWD_SETUP_NEW_WALLET, *, storage=None): try: # FIXME: side-effect: unpaired_device_info sets client.handler u = devmgr.unpaired_device_infos(None, plugin) - except: + except Exception: devmgr.print_error("error", name) continue devices += list(map(lambda x: (name, x), u)) @@ -389,7 +389,7 @@ def choose_hw_device(self, purpose=HWD_SETUP_NEW_WALLET, *, storage=None): label = info.label or _("An unnamed {}").format(name) try: transport_str = str(info.device.path)[:20] - except: + except Exception: transport_str = "unknown transport" descr = f"{label} [{info.model_name or name}, {state}, {transport_str}]" choices.append(((name, info), descr)) diff --git a/electrumabc/bitcoin.py b/electrumabc/bitcoin.py index e4a6c805f568..b93d6acd2a84 100644 --- a/electrumabc/bitcoin.py +++ b/electrumabc/bitcoin.py @@ -90,7 +90,7 @@ # AES encryption try: from Cryptodome.Cipher import AES -except: +except ImportError: AES = None @@ -753,7 +753,7 @@ def is_private_key(key, *, net=None): try: k = deserialize_privkey(key, net=net) return k is not False - except: + except Exception: return False @@ -824,7 +824,7 @@ def verify_message( # check message try: public_key.verify_digest(sig[1:], h, sigdecode=ecdsa.util.sigdecode_string) - except: + except Exception: return False return True @@ -1216,7 +1216,7 @@ def is_xpub(text, *, net=None): try: deserialize_xpub(text, net=net) return True - except: + except Exception: return False @@ -1226,7 +1226,7 @@ def is_xprv(text, *, net=None): try: deserialize_xprv(text, net=net) return True - except: + except Exception: return False @@ -1272,7 +1272,7 @@ def is_bip32_derivation(x): try: [i for i in bip32_derivation(x)] return True - except: + except Exception: return False diff --git a/electrumabc/commands.py b/electrumabc/commands.py index 194a38191fd4..bcedc5c378a6 100644 --- a/electrumabc/commands.py +++ b/electrumabc/commands.py @@ -338,7 +338,7 @@ def _setconfig_normalize_value(cls, key, value): value = json_decode(value) try: value = ast.literal_eval(value) - except: + except Exception: pass return value diff --git a/electrumabc/contacts.py b/electrumabc/contacts.py index 94af1e094820..2d20f2eb5afc 100644 --- a/electrumabc/contacts.py +++ b/electrumabc/contacts.py @@ -107,14 +107,14 @@ class did.""" d2 = storage.get("contacts") try: d.update(d2) # catch type errors, etc by doing this - except: + except Exception: return [] data = [] # backward compatibility for k, v in d.copy().items(): try: _type, n = v - except: + except Exception: continue # Previous to 1.0 the format was { name : (type, address) } # -> current 1.0 format { address : (type, name) } @@ -187,7 +187,7 @@ def import_file(self, path: str) -> int: ) # enforce unique imports in case user imports the same file multiple times if res: count += 1 - except: + except Exception: self.print_error(traceback.format_exc()) raise if count: diff --git a/electrumabc/interface.py b/electrumabc/interface.py index c19da3207048..c1e39a50fa98 100644 --- a/electrumabc/interface.py +++ b/electrumabc/interface.py @@ -223,7 +223,7 @@ def get_socket(self): except ssl.SSLError as e: self.print_error("SSL error retrieving SSL certificate:", e) return - except: + except Exception: return dercert = s.getpeercert(True) @@ -280,7 +280,7 @@ def get_socket(self): try: b = pem.dePem(cert, "CERTIFICATE") x = x509.X509(b) - except: + except Exception: if is_verbose: self.print_error( "Error checking certificate, traceback follows" @@ -291,7 +291,7 @@ def get_socket(self): return try: x.check_date() - except: + except Exception: self.print_error("certificate has expired:", cert_path) try: os.unlink(cert_path) @@ -561,7 +561,7 @@ def check_cert(host, cert): try: b = pem.dePem(cert, "CERTIFICATE") x = x509.X509(b) - except: + except Exception: if is_verbose: print_error("Error checking certificate, traceback follows") traceback.print_exc(file=sys.stderr) @@ -570,7 +570,7 @@ def check_cert(host, cert): try: x.check_date() expired = False - except: + except Exception: expired = True m = "host: %s\n" % host diff --git a/electrumabc/json_db.py b/electrumabc/json_db.py index f82c9421027f..de3243f5def9 100644 --- a/electrumabc/json_db.py +++ b/electrumabc/json_db.py @@ -94,7 +94,7 @@ def put(self, key, value) -> bool: try: json.dumps(key, cls=util.MyEncoder) json.dumps(value, cls=util.MyEncoder) - except: + except Exception: self.print_error(f"json error: cannot save {repr(key)} ({repr(value)})") return False if value is not None: @@ -121,7 +121,7 @@ def dump(self): def load_data(self, s): try: self.data = json.loads(s) - except: + except Exception: try: d = ast.literal_eval(s) d.get("labels", {}) @@ -132,7 +132,7 @@ def load_data(self, s): try: json.dumps(key) json.dumps(value) - except: + except Exception: self.print_error("Failed to convert label to json format", key) continue self.data[key] = value diff --git a/electrumabc/mnemo.py b/electrumabc/mnemo.py index b12b830f39e3..fe997f915ea7 100644 --- a/electrumabc/mnemo.py +++ b/electrumabc/mnemo.py @@ -362,7 +362,7 @@ def is_wordlist_valid( if lang is None: try: lang = cls.detect_language(mnemonic) - except: + except Exception: lang = "en" elif lang not in cls.list_languages(): lang = "en" diff --git a/electrumabc/network.py b/electrumabc/network.py index fa6dfe45c681..2b77b4717f21 100644 --- a/electrumabc/network.py +++ b/electrumabc/network.py @@ -470,7 +470,7 @@ def read_recent_servers(self): with open(self.recent_servers_file(), "r", encoding="utf-8") as f: data = f.read() return json.loads(data) - except: + except Exception: return [] def save_recent_servers(self): @@ -480,7 +480,7 @@ def save_recent_servers(self): try: with open(self.recent_servers_file(), "w", encoding="utf-8") as f: f.write(s) - except: + except Exception: pass def get_server_height(self): @@ -654,7 +654,7 @@ def get_servers(self): for s in self.recent_servers: try: host, port, protocol = deserialize_server(s) - except: + except Exception: continue if host not in out: out[host] = {protocol: port} @@ -767,7 +767,7 @@ def save_parameters(self, host, port, protocol, proxy, auto_connect): if proxy: proxy_modes.index(proxy["mode"]) + 1 int(proxy["port"]) - except: + except Exception: raise ValueError("invalid server or proxy") self.config.set_key("auto_connect", auto_connect, False) @@ -797,7 +797,7 @@ def get_config_server(self): if server: try: deserialize_server(server) - except: + except Exception: self.print_error( "Warning: failed to parse server-string; falling back to random." ) diff --git a/electrumabc/networks.py b/electrumabc/networks.py index 220019ce20f9..1ca30f972728 100644 --- a/electrumabc/networks.py +++ b/electrumabc/networks.py @@ -41,7 +41,7 @@ def _read_json_dict(filename): try: data = pkgutil.get_data(__name__, filename) r = json.loads(data.decode("utf-8")) - except: + except Exception: r = {} return r diff --git a/electrumabc/paymentrequest.py b/electrumabc/paymentrequest.py index 332ecd3113cf..b68fe6340ad6 100644 --- a/electrumabc/paymentrequest.py +++ b/electrumabc/paymentrequest.py @@ -151,7 +151,7 @@ def parse(self, r): try: self.data = pb2.PaymentRequest() self.data.ParseFromString(r) - except: + except Exception: self.error = "cannot parse payment request" return self.details = pb2.PaymentDetails() @@ -175,7 +175,7 @@ def verify(self, contacts): pr = pb2.PaymentRequest() try: pr.ParseFromString(self.raw) - except: + except Exception: self.error = "Error: Cannot parse payment request" return False if not pr.signature: @@ -555,7 +555,7 @@ def load(self, d): try: # First try BitPay 2.0 style PR -- this contains compressed raw bytes of the headers & json associated with the request; will raise if wrong format pr = PaymentRequest_BitPay20.deserialize(raw) - except: + except Exception: pass if not pr: # Lastly, try the BIP70 style PR; this won't raise if bad format @@ -565,7 +565,7 @@ def load(self, d): self.invoices[k] = pr if pr.tx: self.paid[pr.tx] = k - except: + except Exception: continue def import_file(self, path): diff --git a/electrumabc/plugins.py b/electrumabc/plugins.py index d3da405f4c74..6052375f811a 100644 --- a/electrumabc/plugins.py +++ b/electrumabc/plugins.py @@ -536,7 +536,7 @@ def get_hardware_support(self): p = self.find_plugin(name, force_load=True) if p.is_enabled(): out.append([name, details[2], p]) - except: + except Exception: self.print_error( "cannot load plugin for:", name, diff --git a/electrumabc/schnorr.py b/electrumabc/schnorr.py index a93273175002..d172282ce219 100644 --- a/electrumabc/schnorr.py +++ b/electrumabc/schnorr.py @@ -232,7 +232,7 @@ def verify(pubkey, signature, message_hash): try: pubpoint = ser_to_point(pubkey) - except: + except Exception: # off-curve points, failed decompression, bad format, # point at infinity: raise ValueError("pubkey could not be parsed") @@ -399,13 +399,13 @@ def _calc_initial(self): # Internal function, calculates Rxnew, c, and compressed pubkey. try: Rpoint = ser_to_point(self.R) - except: + except Exception: # off-curve points, failed decompression, bad format, # point at infinity: raise ValueError("R could not be parsed") try: pubpoint = ser_to_point(self.pubkey) - except: + except Exception: # off-curve points, failed decompression, bad format, # point at infinity: raise ValueError("pubkey could not be parsed") diff --git a/electrumabc/secp256k1.py b/electrumabc/secp256k1.py index 02dec33c95eb..5b8aa66c4c27 100644 --- a/electrumabc/secp256k1.py +++ b/electrumabc/secp256k1.py @@ -61,7 +61,7 @@ def _load_library(): for lp in library_paths: try: secp256k1 = ctypes.cdll.LoadLibrary(lp) - except: + except Exception: continue if secp256k1: break @@ -168,5 +168,5 @@ def _load_library(): try: secp256k1 = _load_library() -except: +except Exception: secp256k1 = None diff --git a/electrumabc/slp/slp.py b/electrumabc/slp/slp.py index e1ac5cd3b126..40d02abbb01d 100644 --- a/electrumabc/slp/slp.py +++ b/electrumabc/slp/slp.py @@ -237,7 +237,7 @@ def read(keys): continue try: v = getattr(self, k, None) - except: + except Exception: continue if v is not None and not callable(v): d[k] = v diff --git a/electrumabc/storage.py b/electrumabc/storage.py index 3fa4517d1b3c..0272414e8433 100644 --- a/electrumabc/storage.py +++ b/electrumabc/storage.py @@ -160,7 +160,7 @@ def _init_encryption_version(self): return STO_EV_XPUB_PW else: return STO_EV_PLAINTEXT - except: + except Exception: return STO_EV_PLAINTEXT def get_key(self, password): diff --git a/electrumabc/tor/controller.py b/electrumabc/tor/controller.py index 9025f01c58b2..6ad3e3b047e5 100644 --- a/electrumabc/tor/controller.py +++ b/electrumabc/tor/controller.py @@ -181,7 +181,7 @@ def _read_tor_msg(self): if not line: break self._tor_msg_handler(line) - except: + except Exception: self.print_exception("Exception in Tor message reader") _orig_subprocess_popen = subprocess.Popen @@ -260,7 +260,7 @@ def start(self): "Log": "NOTICE stdout", }, ) - except: + except Exception: self.print_exception("Failed to start Tor") self._tor_process = None self.status = TorController.Status.ERRORED @@ -286,7 +286,7 @@ def start(self): self._handle_network_liveliness_event, stem.control.EventType.NETWORK_LIVENESS, ) # pylint: disable=no-member - except: + except Exception: self.print_exception("Failed to connect to Tor control port") self.stop() return diff --git a/electrumabc/transaction.py b/electrumabc/transaction.py index 0efb30e0a936..c2d81e0864fc 100644 --- a/electrumabc/transaction.py +++ b/electrumabc/transaction.py @@ -239,7 +239,7 @@ def parse_sig(x_sig): def safe_parse_pubkey(x): try: return xpubkey_to_pubkey(x) - except: + except Exception: return x @@ -272,7 +272,7 @@ def parse_scriptSig(d, _bytes): try: signatures = parse_sig([sig]) pubkey, address = xpubkey_to_address(x_pubkey) - except: + except Exception: print_error("cannot find address in input script", bh2u(_bytes)) return d["type"] = "p2pkh" @@ -1595,7 +1595,7 @@ def tx_from_str(txt): try: bfh(txt) is_hex = True - except: + except Exception: is_hex = False if is_hex: return txt diff --git a/electrumabc/util.py b/electrumabc/util.py index 78a000b5cbef..4263d02ae0a3 100644 --- a/electrumabc/util.py +++ b/electrumabc/util.py @@ -282,7 +282,7 @@ def json_encode(obj): def json_decode(x): try: return json.loads(x, parse_float=Decimal) - except: + except Exception: return x @@ -308,7 +308,7 @@ def ensure_sparse_file(filename): if os.name == "nt": try: subprocess.call('fsutil sparse setFlag "' + filename + '" 1', shell=True) - except: + except Exception: pass @@ -364,7 +364,7 @@ def assert_bytes(*args): try: for x in args: assert isinstance(x, (bytes, bytearray)) - except: + except Exception: print("assert bytes failed", list(map(type, args))) raise @@ -553,7 +553,7 @@ def format_fee_satoshis(fee, num_zeros=0): def timestamp_to_datetime(timestamp): try: return datetime.fromtimestamp(timestamp) - except: + except Exception: return None diff --git a/electrumabc/wallet.py b/electrumabc/wallet.py index 4d8dd56674a1..301eb600c7c6 100644 --- a/electrumabc/wallet.py +++ b/electrumabc/wallet.py @@ -1326,7 +1326,7 @@ def can_do_work(): f"{time.time()-t0:3.2f}", "seconds", ) - except: + except Exception: import traceback self.print_error(f"{me.name}:", traceback.format_exc()) @@ -2443,7 +2443,7 @@ def can_sign(self, tx): _, addr = xpubkey_to_address(x_pubkey) try: c, index = self.get_address_index(addr) - except: + except Exception: continue if index is not None: k.set_wallet_advice(addr, [c, index]) @@ -2802,7 +2802,7 @@ def f(x): try: addr = x["address"] return self.get_address_index(addr) or addr - except: + except Exception: return addr return sorted(m, key=f) @@ -3489,7 +3489,7 @@ def load_keystore(self): self.keystore = load_keystore(self.storage, "keystore") try: xtype = bitcoin.xpub_type(self.keystore.xpub) - except: + except Exception: xtype = "standard" self.txin_type = "p2pkh" if xtype == "standard" else xtype diff --git a/electrumabc/websockets.py b/electrumabc/websockets.py index b5051dc8380f..45d42ff2cb99 100644 --- a/electrumabc/websockets.py +++ b/electrumabc/websockets.py @@ -88,7 +88,7 @@ def reading_thread(self): continue try: addr, amount = self.make_request(request_id) - except: + except Exception: continue try: addr = Address.from_string(addr) diff --git a/electrumabc_gui/qt/address_dialog.py b/electrumabc_gui/qt/address_dialog.py index 36d075af1484..71d92913e134 100644 --- a/electrumabc_gui/qt/address_dialog.py +++ b/electrumabc_gui/qt/address_dialog.py @@ -80,7 +80,7 @@ def __init__(self, parent, address, *, windowParent=None): # ok, now try the usual method for imported wallets, etc pubkey = self.wallet.get_public_key(address) pubkeys = [pubkey.to_ui_string()] - except: + except Exception: # watching only wallets (totally lacks a private/public key pair for this address) pubkeys = None if pubkeys: diff --git a/electrumabc_gui/qt/contact_list.py b/electrumabc_gui/qt/contact_list.py index 146c9f1eccd4..48de4a92b492 100644 --- a/electrumabc_gui/qt/contact_list.py +++ b/electrumabc_gui/qt/contact_list.py @@ -106,7 +106,7 @@ def on_edited(self, item, column, prior_value): label_key = contact.address try: label_key = Address.from_string(label_key).to_storage_string() - except: + except Exception: pass self.wallet.set_label(label_key, item.text(2)) self.update() # force refresh in case 2 contacts use the same address @@ -336,7 +336,7 @@ def on_update(self): address = addy.to_ui_string() label_key = addy.to_storage_string() del addy - except: + except Exception: """This may happen because we may not have always enforced this as strictly as we could have in legacy code. Just move on..""" label = self.wallet.get_label(label_key) item = QtWidgets.QTreeWidgetItem( diff --git a/electrumabc_gui/qt/main_window.py b/electrumabc_gui/qt/main_window.py index b9ce37865c4a..23f2dea730fd 100644 --- a/electrumabc_gui/qt/main_window.py +++ b/electrumabc_gui/qt/main_window.py @@ -637,7 +637,7 @@ def init_geometry(self): screen = self.app.desktop().screenGeometry() assert screen.contains(QRect(*winpos)) self.setGeometry(*winpos) - except: + except Exception: self.print_error("using default geometry") self.setGeometry(100, 100, 840, 400) @@ -779,7 +779,7 @@ def update_recently_visited(self, filename): recent = self.config.get("recently_open", []) try: sorted(recent) - except: + except Exception: recent = [] if filename in recent: recent.remove(filename) @@ -2720,7 +2720,7 @@ def broadcast_thread(): fee = None try: fee = tx.get_fee() - except: + except Exception: pass # no fee info available for tx # Check fee >= size otherwise warn. FIXME: If someday network relay # rules change to be other than 1.0 sats/B minimum, this code needs @@ -2767,7 +2767,7 @@ def broadcast_done(result): txid = ( tx.txid() ) # returns None if not is_complete, but may raise potentially as well - except: + except Exception: txid = None if txid is not None: if tx_desc is not None: @@ -3040,7 +3040,7 @@ def convert_address(): addr = Address.from_string( source_address.text().strip(), support_arbitrary_prefix=True ) - except: + except Exception: addr = None for widget, fmt in widgets: if addr: @@ -3421,7 +3421,7 @@ def change_password_dialog(self): except Exception as e: self.show_error(str(e)) return - except: + except Exception: if util.is_verbose: traceback.print_exc(file=sys.stderr) self.show_error(_("Failed to update password")) @@ -3773,7 +3773,7 @@ def tx_from_text(self, txt) -> Optional[Transaction]: my_index = my_outpoints.index(outpoint) tx._inputs[i]["value"] = my_coins[my_index]["value"] return tx - except: + except Exception: if util.is_verbose: traceback.print_exc(file=sys.stderr) self.show_critical( diff --git a/electrumabc_gui/qt/paytoedit.py b/electrumabc_gui/qt/paytoedit.py index 07f83f44d231..e91cdb189fd0 100644 --- a/electrumabc_gui/qt/paytoedit.py +++ b/electrumabc_gui/qt/paytoedit.py @@ -132,7 +132,7 @@ def parse_output(cls, x): try: address = cls.parse_address(x) return bitcoin.TYPE_ADDRESS, address - except: + except Exception: return bitcoin.TYPE_SCRIPT, ScriptOutput.from_string(x) @staticmethod @@ -167,7 +167,7 @@ def check_text(self): return try: self.payto_address = self.parse_output(data) - except: + except Exception: pass if self.payto_address: self.win.lock_amount(False) diff --git a/electrumabc_gui/qt/popup_widget.py b/electrumabc_gui/qt/popup_widget.py index e1cb0630fb15..4ecd69ea2549 100644 --- a/electrumabc_gui/qt/popup_widget.py +++ b/electrumabc_gui/qt/popup_widget.py @@ -298,7 +298,7 @@ def hideEvent(self, e): def _disconnectFinished(self): try: self.animation.finished.disconnect() - except: + except Exception: pass def hideAnimated(self): @@ -457,7 +457,7 @@ def KillPopupLabel(name="Global"): if extant: try: extant.destroyed.disconnect() - except: + except Exception: pass try: destroyed_print_error(extant, "[PopupLabel/{}] destroyed".format(name)) diff --git a/electrumabc_gui/qt/qrtextedit.py b/electrumabc_gui/qt/qrtextedit.py index 07c292e1541b..a39933f98e62 100644 --- a/electrumabc_gui/qt/qrtextedit.py +++ b/electrumabc_gui/qt/qrtextedit.py @@ -49,7 +49,7 @@ def qr_show(self): try: s = str(self.toPlainText()) - except: + except Exception: s = self.toPlainText() QRDialog(s).exec_() diff --git a/electrumabc_gui/qt/transaction_dialog.py b/electrumabc_gui/qt/transaction_dialog.py index f473966359e0..7afd9c374bbf 100644 --- a/electrumabc_gui/qt/transaction_dialog.py +++ b/electrumabc_gui/qt/transaction_dialog.py @@ -170,7 +170,7 @@ def open_be_url(link): url = web.BE_URL( self.main_window.config, web.ExplorerUrlParts.TX, txid ) - except: + except Exception: raise url = None if url: diff --git a/electrumabc_gui/qt/util.py b/electrumabc_gui/qt/util.py index 81f285b0592b..25576f8222fa 100644 --- a/electrumabc_gui/qt/util.py +++ b/electrumabc_gui/qt/util.py @@ -1093,7 +1093,7 @@ def run(self): try: result = task.task() self.doneSig.emit(result, task.cb_done, task.cb_success) - except: + except Exception: self.doneSig.emit(sys.exc_info(), task.cb_done, task.cb_error) finally: self.print_error("exiting") @@ -1499,7 +1499,7 @@ def destroyed_print_error(qobject, msg=None): qobject.parent().objectName() or qobject.parent().__class__.__qualname__ ) + "." - except: + except Exception: pass # some of the code in this project overrites .parent or it may not have a parent name += qobject.__class__.__qualname__ msg = f"[{name}] destroyed" diff --git a/electrumabc_plugins/digitalbitbox/digitalbitbox.py b/electrumabc_plugins/digitalbitbox/digitalbitbox.py index 1e2a6b31eb50..1ab38925f005 100644 --- a/electrumabc_plugins/digitalbitbox/digitalbitbox.py +++ b/electrumabc_plugins/digitalbitbox/digitalbitbox.py @@ -84,7 +84,7 @@ def close(self): with self.device_manager().hid_lock: try: self.dbb_hid.close() - except: + except Exception: pass self.opened = False diff --git a/electrumabc_plugins/email_requests/qt.py b/electrumabc_plugins/email_requests/qt.py index 39e02f972168..f94b11d93cfd 100644 --- a/electrumabc_plugins/email_requests/qt.py +++ b/electrumabc_plugins/email_requests/qt.py @@ -77,7 +77,7 @@ def diagnostic_name(self): def poll(self): try: self.M.select() - except: + except Exception: return typ, data = self.M.search(None, "ALL") for num in data[0].split(): diff --git a/electrumabc_plugins/fusion/comms.py b/electrumabc_plugins/fusion/comms.py index c7db051497dd..38b0f137a003 100644 --- a/electrumabc_plugins/fusion/comms.py +++ b/electrumabc_plugins/fusion/comms.py @@ -158,7 +158,7 @@ def diagnostic_name(self): self.peername = ":".join( str(x) for x in self.connection.socket.getpeername() ) - except: + except Exception: pass # on some systems socket.getpeername() is not supported peername = self.peername or "???" return f"Client {peername}" @@ -281,7 +281,7 @@ def __init__(self, bindhost, port, clientclass, upnp=None): try: s.connect(("8.8.8.8", 1)) host = s.getsockname()[0] - except: + except Exception: host = "127.0.0.1" finally: s.close() @@ -328,16 +328,16 @@ def run( self.spawned_clients.add(client) client.addjob(self.new_client_job) client.start() - except: + except Exception: self.print_error("failed with exception") traceback.print_exc(file=sys.stderr) try: self.listensock.close() - except: + except Exception: pass try: self.upnp.deleteportmapping(self.port, "TCP") - except: + except Exception: pass self.print_error("stopped") diff --git a/electrumabc_plugins/fusion/connection.py b/electrumabc_plugins/fusion/connection.py index a3e3105a219b..962bf0b58321 100644 --- a/electrumabc_plugins/fusion/connection.py +++ b/electrumabc_plugins/fusion/connection.py @@ -72,7 +72,7 @@ def open_connection( if ssl: try: conn_socket = sslcontext.wrap_socket(bare_socket, server_hostname=host) - except: + except Exception: bare_socket.close() raise else: @@ -80,7 +80,7 @@ def open_connection( try: return Connection(conn_socket, default_timeout) - except: + except Exception: conn_socket.close() raise diff --git a/electrumabc_plugins/fusion/encrypt.py b/electrumabc_plugins/fusion/encrypt.py index 9847f8ea5062..4328442b922e 100644 --- a/electrumabc_plugins/fusion/encrypt.py +++ b/electrumabc_plugins/fusion/encrypt.py @@ -87,7 +87,7 @@ def encrypt(message, pubkey, pad_to_length=None): """ try: pubpoint = ser_to_point(pubkey) - except: + except Exception: raise EncryptionFailed nonce_sec = ecdsa.util.randrange(order) nonce_pub = point_to_ser(nonce_sec * G, comp=True) @@ -150,7 +150,7 @@ def decrypt(data, privkey): raise DecryptionFailed try: nonce_pub = ser_to_point(data[:33]) - except: + except Exception: raise DecryptionFailed sec = int.from_bytes(privkey, "big") key = hashlib.sha256(point_to_ser(sec * nonce_pub, comp=True)).digest() diff --git a/electrumabc_plugins/fusion/fusion.py b/electrumabc_plugins/fusion/fusion.py index 555c0c9f2026..de3460836cb4 100644 --- a/electrumabc_plugins/fusion/fusion.py +++ b/electrumabc_plugins/fusion/fusion.py @@ -878,7 +878,7 @@ def start_covert( self.status = ("running", "Setting up Tor connections") try: covert_domain = self.covert_domain_b.decode("ascii") - except: + except Exception: raise FusionError("badly encoded covert domain") covert = CovertSubmitter( covert_domain, @@ -921,7 +921,7 @@ def start_covert( self.check_stop() self.check_coins() - except: + except Exception: covert.stop() raise diff --git a/electrumabc_plugins/fusion/pedersen.py b/electrumabc_plugins/fusion/pedersen.py index ae9db5712c4c..6544bad69a9d 100644 --- a/electrumabc_plugins/fusion/pedersen.py +++ b/electrumabc_plugins/fusion/pedersen.py @@ -88,7 +88,7 @@ def __init__(self, H): if not seclib: try: Hpoint = ser_to_point(H) - except: + except Exception: raise ValueError("H could not be parsed") HGpoint = Hpoint + ecdsa.SECP256k1.generator if HGpoint == ecdsa.ellipticcurve.INFINITY: diff --git a/electrumabc_plugins/fusion/server.py b/electrumabc_plugins/fusion/server.py index b89e9e6d3dae..eadafcea84b7 100644 --- a/electrumabc_plugins/fusion/server.py +++ b/electrumabc_plugins/fusion/server.py @@ -533,7 +533,7 @@ def new_client_job(self, client): statuses[t] = status client.send(pb.TierStatusUpdate(statuses=statuses)) start_ev.wait(2) - except: + except Exception: # Remove client from waiting pools on failure (on success, we are already removed; on stop we don't care.) with self.lock: for t, pool in mytierpools.items(): diff --git a/electrumabc_plugins/hw_wallet/qt.py b/electrumabc_plugins/hw_wallet/qt.py index 76922eb83f78..1c13ec0a1b00 100644 --- a/electrumabc_plugins/hw_wallet/qt.py +++ b/electrumabc_plugins/hw_wallet/qt.py @@ -256,7 +256,7 @@ def run(self): try: result = task.task() self.doneSig.emit(result, task.cb_done, task.cb_success) - except: + except Exception: self.doneSig.emit(sys.exc_info(), task.cb_done, task.cb_error) def stop(self, *args, **kwargs): diff --git a/electrumabc_plugins/labels/labels.py b/electrumabc_plugins/labels/labels.py index 16ce9969675c..37b964479e8b 100644 --- a/electrumabc_plugins/labels/labels.py +++ b/electrumabc_plugins/labels/labels.py @@ -142,7 +142,7 @@ def push_thread(self, wallet): try: encoded_key = self.encode(wallet, key) encoded_value = self.encode(wallet, value) - except: + except Exception: self.print_error("cannot encode", repr(key), repr(value)) continue bundle["labels"].append( @@ -178,12 +178,12 @@ def pull_thread(self, wallet, force): try: key = self.decode(wallet, label["externalId"]) value = self.decode(wallet, label["encryptedLabel"]) - except: + except Exception: continue try: json.dumps(key) json.dumps(value) - except: + except Exception: self.print_error("error: no json", key) continue result[key] = value diff --git a/scripts/txradar b/scripts/txradar index 5bb2bb75f0ec..bd17777c8397 100755 --- a/scripts/txradar +++ b/scripts/txradar @@ -5,7 +5,7 @@ import util try: tx = sys.argv[1] -except: +except Exception: print("usage: txradar txid") sys.exit(1) From 20a9aed5e81e04577d72c63bcf9922cfbd40a056 Mon Sep 17 00:00:00 2001 From: PiRK Date: Fri, 13 Jan 2023 08:50:31 +0100 Subject: [PATCH 7/9] move a bunch of same-line comments to previous line This improves the code formatting by black --- contrib/build-wine/deterministic.spec | 3 +- contrib/osx/osx.spec | 3 +- electrumabc/bitcoin.py | 6 +- electrumabc/contacts.py | 5 +- electrumabc/network.py | 19 +++--- electrumabc/slp/slp.py | 37 ++++++---- electrumabc/transaction.py | 5 +- electrumabc/wallet.py | 5 +- electrumabc_gui/qt/__init__.py | 12 ++-- electrumabc_gui/qt/main_window.py | 44 ++++++++---- electrumabc_gui/qt/network_dialog.py | 10 ++- electrumabc_gui/qt/seed_dialog.py | 11 ++- electrumabc_gui/qt/util.py | 56 ++++++++------- electrumabc_plugins/cosigner_pool/qt.py | 6 +- electrumabc_plugins/fusion/fusion.py | 3 +- electrumabc_plugins/fusion/plugin.py | 5 +- electrumabc_plugins/fusion/qt.py | 24 +++---- electrumabc_plugins/fusion/server.py | 5 +- .../fusion/tests/test_encrypt.py | 5 +- electrumabc_plugins/labels/labels.py | 20 +++--- electrumabc_plugins/satochip/satochip.py | 68 ++++++++----------- 21 files changed, 184 insertions(+), 168 deletions(-) diff --git a/contrib/build-wine/deterministic.spec b/contrib/build-wine/deterministic.spec index e94ab024d859..2248ef321d69 100644 --- a/contrib/build-wine/deterministic.spec +++ b/contrib/build-wine/deterministic.spec @@ -61,7 +61,8 @@ datas = [ datas += collect_data_files('trezorlib') datas += collect_data_files('btchip') datas += collect_data_files('keepkeylib') -datas += collect_data_files('mnemonic') # wordlists used by keepkeylib from lib mnemonic +# wordlists used by keepkeylib from lib mnemonic +datas += collect_data_files('mnemonic') # We don't put these files in to actually include them in the script but to make the Analysis method scan them for imports a = Analysis([home+'electrum-abc', diff --git a/contrib/osx/osx.spec b/contrib/osx/osx.spec index b4bd1ead53b5..86095a172a6b 100644 --- a/contrib/osx/osx.spec +++ b/contrib/osx/osx.spec @@ -41,7 +41,8 @@ datas = [ datas += collect_data_files('trezorlib') datas += collect_data_files('btchip') datas += collect_data_files('keepkeylib') -datas += collect_data_files('mnemonic') # wordlists used by keepkeylib from lib mnemonic +# wordlists used by keepkeylib from lib mnemonic +datas += collect_data_files('mnemonic') # Add libusb so Trezor will work diff --git a/electrumabc/bitcoin.py b/electrumabc/bitcoin.py index b93d6acd2a84..1ea6e147ff3a 100644 --- a/electrumabc/bitcoin.py +++ b/electrumabc/bitcoin.py @@ -522,7 +522,8 @@ def hash160_to_b58_address(h160, addrtype): def b58_address_to_hash160(addr): addr = to_bytes(addr, "ascii") - _bytes = base_decode(addr, 25, base=58) # will raise ValueError on bad characters + # will raise ValueError on bad characters + _bytes = base_decode(addr, 25, base=58) return _bytes[0], _bytes[1:21] @@ -697,10 +698,11 @@ def deserialize_privkey(key, *, net=None): return "p2pkh", minikey_to_private_key(key), False elif vch: txin_type = inv_dict(SCRIPT_TYPES)[vch[0] - net.WIF_PREFIX] + # We do it this way because eg iOS runs with PYTHONOPTIMIZE=1 if len(vch) not in ( 33, 34, - ): # We do it this way because eg iOS runs with PYTHONOPTIMIZE=1 + ): raise AssertionError("Key {} has invalid length".format(key)) compressed = len(vch) == 34 if compressed and vch[33] != 0x1: diff --git a/electrumabc/contacts.py b/electrumabc/contacts.py index 2d20f2eb5afc..20c10dc8f230 100644 --- a/electrumabc/contacts.py +++ b/electrumabc/contacts.py @@ -154,9 +154,8 @@ def _save(data: List[Contact], v1_too: bool = False) -> dict: return ret def save(self): - d = self._save( - self.data, v1_too=False - ) # Note: set v1_too = True if you want to save to v1 so older EC wallets can also see the updated contacts + # Note: set v1_too = True if you want to save to v1 so older EC wallets can also see the updated contacts + d = self._save(self.data, v1_too=False) for k, v in d.items(): self.storage.put(k, v) # "contacts2", "contacts" are the two expected keys diff --git a/electrumabc/network.py b/electrumabc/network.py index 2b77b4717f21..bdcfd4b78c1c 100644 --- a/electrumabc/network.py +++ b/electrumabc/network.py @@ -390,9 +390,8 @@ def get_instance(): return Network.INSTANCE def callback_listener_count(self, event): - return len( - self.callbacks.get(event, []) - ) # we intentionally don't take any locks here as a performance optimization + # we intentionally don't take any locks here as a performance optimization + return len(self.callbacks.get(event, [])) def register_callback(self, callback, events): with self.lock: @@ -426,14 +425,16 @@ def _legacy_callback_detector_and_mogrifier(self, event, *args): # electron cash plugins that still use this event, and we need # to keep this hack here so they don't break on new EC # versions. "Technical debt" :) - self.trigger_callback( - "updated" - ) # we will re-enter this function with event == 'updated' (triggering the warning in the elif clause below) + # + # we will re-enter this function with event == 'updated' (triggering the + # warning in the elif clause below) + self.trigger_callback("updated") elif event == "verified2" and "verified" in self.callbacks: # pop off the 'wallet' arg as the old bad 'verified' callback lacked it. - self.trigger_callback( - "verified", args[1:] - ) # we will re-enter this function with event == 'verified' (triggering the warning in the elif clause below) + # + # we will re-enter this function with event == 'verified' (triggering the + # warning in the elif clause below) + self.trigger_callback("verified", args[1:]) elif event in self._deprecated_alternatives: # If we see updated or verified events come through here, warn: # deprecated. Note that the above 2 clauses will also trigger this diff --git a/electrumabc/slp/slp.py b/electrumabc/slp/slp.py index 40d02abbb01d..dd711758db6f 100644 --- a/electrumabc/slp/slp.py +++ b/electrumabc/slp/slp.py @@ -54,11 +54,11 @@ def __new__(cls, script): ) script = bytes(script) if isinstance(script, bytearray) else script self = super(__class__, cls).__new__(cls, script) - self.message = cls._script_message_cache.get( - self.script - ) # will return a valid object or None + # will return a valid object or None + self.message = cls._script_message_cache.get(self.script) if self.message is None: - self.message = Message.parse(self) # raises on parse error + # raises on parse error + self.message = Message.parse(self) return self @classmethod @@ -812,21 +812,28 @@ def save(self): def clear(self): """Caller should hold locks""" self.need_rebuild = False - self.validity = dict() # txid -> int - self.txo_byaddr = dict() # [address] -> set of "prevouthash:n" for that address - self.token_quantities = ( - dict() - ) # [token_id_hex] -> dict of ["prevouthash:n"] -> qty (-1 for qty indicates minting baton) - self.txo_token_id = dict() # ["prevouthash:n"] -> "token_id_hex" + + # txid -> int + self.validity = dict() + + # [address] -> set of "prevouthash:n" for that address + self.txo_byaddr = dict() + + # [token_id_hex] -> dict of ["prevouthash:n"] -> qty (-1 for qty indicates + # minting baton) + self.token_quantities = dict() + + # ["prevouthash:n"] -> "token_id_hex" + self.txo_token_id = dict() def rebuild(self): """This takes wallet.lock""" with self.wallet.lock: self.clear() for txid, tx in self.wallet.transactions.items(): - self.add_tx( - txid, Transaction(tx.raw) - ) # we take a copy of the transaction so prevent storing deserialized tx in wallet.transactions dict + # we take a copy of the transaction so prevent storing deserialized tx + # in wallet.transactions dict + self.add_tx(txid, Transaction(tx.raw)) # --- GETTERS / SETTERS from wallet def token_info_for_txo(self, txo) -> Tuple[str, int]: @@ -838,10 +845,12 @@ def token_info_for_txo(self, txo) -> Tuple[str, int]: """ token_id_hex = self.txo_token_id.get(txo) if token_id_hex is not None: + # we want this to raise KeyError here if missing as it indicates a + # programming error return ( token_id_hex, self.token_quantities[token_id_hex][txo], - ) # we want this to raise KeyError here if missing as it indicates a programming error + ) def txo_has_token(self, txo) -> bool: """Takes no locks.""" diff --git a/electrumabc/transaction.py b/electrumabc/transaction.py index c2d81e0864fc..73fa97d52539 100644 --- a/electrumabc/transaction.py +++ b/electrumabc/transaction.py @@ -1433,9 +1433,8 @@ def got_tx_info(r): "block_height" ) # indicate to other thread we got the block_height reply from network try: - confs = r.get("result").get( - "confirmations", 0 - ) # will raise of error reply + # will raise of error reply + confs = r.get("result").get("confirmations", 0) if confs and lh: # the whole point.. was to get this piece of data.. the block_height eph["block_height"] = bh = lh - confs + 1 diff --git a/electrumabc/wallet.py b/electrumabc/wallet.py index 301eb600c7c6..c7fadd40d3a7 100644 --- a/electrumabc/wallet.py +++ b/electrumabc/wallet.py @@ -1275,9 +1275,8 @@ def can_do_work(): # .txid()) which ensures the tx from the server # is not junk. assert prevout_hash == tx.txid(), "txid mismatch" - Transaction.tx_cache_put( - tx, prevout_hash - ) # will cache a copy + # will cache a copy + Transaction.tx_cache_put(tx, prevout_hash) except Exception as e: self.print_error( f"{me.name}: Error retrieving txid", diff --git a/electrumabc_gui/qt/__init__.py b/electrumabc_gui/qt/__init__.py index 7c54090ea2e1..7bfc6a4c5e72 100644 --- a/electrumabc_gui/qt/__init__.py +++ b/electrumabc_gui/qt/__init__.py @@ -1159,9 +1159,9 @@ def main(self): return signal.signal(signal.SIGINT, lambda signum, frame: self.shutdown_signal.emit()) - self.app.setQuitOnLastWindowClosed( - False - ) # we want to control this in our slot (since we support non-visible, backgrounded windows via the systray show/hide facility) + # we want to control this in our slot (since we support non-visible, + # backgrounded windows via the systray show/hide facility) + self.app.setQuitOnLastWindowClosed(False) self.app.lastWindowClosed.connect(self._quit_after_last_window) def clean_up(): @@ -1178,9 +1178,9 @@ def clean_up(): self.app.aboutToQuit.connect(clean_up) - ExceptionHook( - self.config - ) # This wouldn't work anyway unless the app event loop is active, so we must install it once here and no earlier. + # This wouldn't work anyway unless the app event loop is active, so we must + # install it once here and no earlier. + ExceptionHook(self.config) # main loop self.app.exec_() # on some platforms the exec_ call may not return, so use clean_up() diff --git a/electrumabc_gui/qt/main_window.py b/electrumabc_gui/qt/main_window.py index 23f2dea730fd..bff31e3556b0 100644 --- a/electrumabc_gui/qt/main_window.py +++ b/electrumabc_gui/qt/main_window.py @@ -1166,10 +1166,12 @@ def timer_actions(self): # Note this runs in the GUI thread if self.need_update.is_set(): - self._update_wallet() # will clear flag when it runs. (also clears labels_need_update as well) + # will clear flag when it runs. (also clears labels_need_update as well) + self._update_wallet() if self.labels_need_update.is_set(): - self._update_labels() # will clear flag when it runs. + # will clear flag when it runs. + self._update_labels() # resolve aliases # FIXME this is a blocking network call that has a timeout of 5 sec @@ -1179,7 +1181,8 @@ def timer_actions(self): self.do_update_fee() self.require_fee_update = False - # hook for other classes to be called here. For example the tx_update_mgr is called here (see TxUpdateMgr.do_check). + # hook for other classes to be called here. For example the tx_update_mgr is + # called here (see TxUpdateMgr.do_check). self.on_timer_signal.emit() def format_amount(self, x, is_diff=False, whitespaces=False): @@ -1338,7 +1341,8 @@ def update_status(self): run_hook("window_update_status", self) def update_wallet(self): - self.need_update.set() # will enqueue an _update_wallet() call in at most 0.5 seconds from now. + # will enqueue an _update_wallet() call in at most 0.5 seconds from now. + self.need_update.set() def _update_wallet(self): """Called by self.timer_actions every 0.5 secs if need_update flag is set. @@ -1364,15 +1368,22 @@ def update_tabs(self): self.contact_list.update() self.invoice_list.update() self.update_completions() - self.history_updated_signal.emit() # inform things like address_dialog that there's a new history, also clears self.tx_update_mgr.verif_q + # inform things like address_dialog that there's a new history, also clears + # self.tx_update_mgr.verif_q + self.history_updated_signal.emit() self.need_update.clear() # clear flag if self.labels_need_update.is_set(): - # if flag was set, might as well declare the labels updated since they necessarily were due to a full update. - self.labels_updated_signal.emit() # just in case client code was waiting for this signal to proceed. - self.labels_need_update.clear() # clear flag + # if flag was set, might as well declare the labels updated since they + # necessarily were due to a full update. + # + # just in case client code was waiting for this signal to proceed. + self.labels_updated_signal.emit() + # clear flag + self.labels_need_update.clear() def update_labels(self): - self.labels_need_update.set() # will enqueue an _update_labels() call in at most 0.5 seconds from now + # will enqueue an _update_labels() call in at most 0.5 seconds from now + self.labels_need_update.set() @rate_limited(1.0) def _update_labels(self): @@ -1384,7 +1395,8 @@ def _update_labels(self): self.utxo_list.update_labels() self.update_completions() self.labels_updated_signal.emit() - self.labels_need_update.clear() # clear flag + # clear flag + self.labels_need_update.clear() def create_history_tab(self): history_list = HistoryList(self) @@ -1664,9 +1676,9 @@ def save_payment_request(self): self.wallet.add_payment_request(req, self.config) self.sign_payment_request(self.receive_address) self.request_list.update() - self.request_list.select_item_by_address( - req.get("address") - ) # when adding items to the view the current selection may not reflect what's in the UI. Make sure it's selected. + # when adding items to the view the current selection may not reflect what's in + # the UI. Make sure it's selected. + self.request_list.select_item_by_address(req.get("address")) self.address_list.update() self.save_request_button.setEnabled(False) @@ -3818,7 +3830,8 @@ def _on_qr_reader_finished(success: bool, error: str, result): # else if the user scanned an offline signed tx try: result = bh2u(bitcoin.base_decode(result, length=None, base=43)) - tx = self.tx_from_text(result) # will show an error dialog on error + # will show an error dialog on error + tx = self.tx_from_text(result) if not tx: return except Exception as e: @@ -4196,7 +4209,8 @@ def on_dialog_closed(*args): except TypeError: pass if thr and thr.is_alive(): - thr.join(timeout=1.0) # wait for thread to end for maximal GC mojo + # wait for thread to end for maximal GC mojo + thr.join(timeout=1.0) def computing_privkeys_slot(): if stop: diff --git a/electrumabc_gui/qt/network_dialog.py b/electrumabc_gui/qt/network_dialog.py index 2eb71885fcf6..5c49a73363c8 100644 --- a/electrumabc_gui/qt/network_dialog.py +++ b/electrumabc_gui/qt/network_dialog.py @@ -592,15 +592,13 @@ def hideEvent(slf, e): grid.addWidget(self.server_host, 3, 1, 1, 2) grid.addWidget(self.server_port, 3, 3) - self.server_list_label = label = QtWidgets.QLabel( - "" - ) # will get set by self.update() + # will get set by self.update() + self.server_list_label = label = QtWidgets.QLabel("") grid.addWidget(label, 4, 0, 1, 5) self.servers_list = ServerListWidget(self) grid.addWidget(self.servers_list, 5, 0, 1, 5) - self.legend_label = label = WWLabel( - "" - ) # will get populated with the legend by self.update() + # will get populated with the legend by self.update() + self.legend_label = label = WWLabel("") label.setTextInteractionFlags( label.textInteractionFlags() & (~Qt.TextSelectableByMouse) ) # disable text selection by mouse here diff --git a/electrumabc_gui/qt/seed_dialog.py b/electrumabc_gui/qt/seed_dialog.py index 4f23387ff328..8d237e211801 100644 --- a/electrumabc_gui/qt/seed_dialog.py +++ b/electrumabc_gui/qt/seed_dialog.py @@ -156,12 +156,11 @@ def __init__( opt_button = EnterButton(_("Options"), self.seed_options) hbox.addWidget(opt_button) self.addLayout(hbox) - grid_maybe = ( - QtWidgets.QGridLayout() - ) # may not be used if none of the below if expressions evaluates to true, that's ok. - grid_maybe.setColumnStretch( - 1, 1 - ) # we want the right-hand column to take up as much space as it needs. + # may not be used if none of the below if expressions evaluates to true, + # that's ok. + grid_maybe = QtWidgets.QGridLayout() + # we want the right-hand column to take up as much space as it needs. + grid_maybe.setColumnStretch(1, 1) grid_row = 0 if seed_type: seed_type_text = mnemo.format_seed_type_name_for_ui(seed_type) diff --git a/electrumabc_gui/qt/util.py b/electrumabc_gui/qt/util.py index 25576f8222fa..11e3b7a4f2e1 100644 --- a/electrumabc_gui/qt/util.py +++ b/electrumabc_gui/qt/util.py @@ -500,10 +500,13 @@ def update_progress(self, progress: int): def on_accepted(self): self.thread.stop() if self.auto_cleanup: - self.wait() # wait for thread to complete so that we can get cleaned up - self.setParent( - None - ) # this causes GC to happen sooner rather than later. Before this call was added the WaitingDialogs would stick around in memory until the ElectrumWindow was closed and would never get GC'd before then. (as of PyQt5 5.11.3) + # wait for thread to complete so that we can get cleaned up + self.wait() + # this causes GC to happen sooner rather than later. Before this call was + # added the WaitingDialogs would stick around in memory until the + # ElectrumWindow was closed and would never get GC'd before then. + # (as of PyQt5 5.11.3) + self.setParent(None) def on_rejected(self): if self.auto_cleanup: @@ -1269,9 +1272,9 @@ def invoke(cls, rate, ts_after, func, args, kwargs): obj = args[0] a_name = cls.attr_name(func) # print_error("*** a_name =",a_name,"obj =",obj) - rl = getattr( - obj, a_name, None - ) # we hide the RateLimiter state object in an attribute (name based on the wrapped function name) in the target object + # we hide the RateLimiter state object in an attribute (name based on the + # wrapped function name) in the target object + rl = getattr(obj, a_name, None) if rl is None: # must be the first invocation, create a new RateLimiter state instance. rl = cls(rate, ts_after, obj, func) @@ -1279,20 +1282,22 @@ def invoke(cls, rate, ts_after, func, args, kwargs): return rl._invoke(args, kwargs) def _invoke(self, args, kwargs): - self._push_args( - args, kwargs - ) # since we're collating, save latest invocation's args unconditionally. any future invocation will use the latest saved args. + # since we're collating, save latest invocation's args unconditionally. any + # future invocation will use the latest saved args. + self._push_args(args, kwargs) self.ctr += 1 # increment call counter # self.print_error("args_saved",args,"kwarg_saved",kwargs) if not self.timer: # check if there's a pending invocation already now = time.time() diff = float(self.rate) - (now - self.last_ts) if diff <= 0: - # Time since last invocation was greater than self.rate, so call the function directly now. + # Time since last invocation was greater than self.rate, so call the + # function directly now. # self.print_error("calling directly") return self._doIt() else: - # Time since last invocation was less than self.rate, so defer to the future with a timer. + # Time since last invocation was less than self.rate, so defer to the + # future with a timer. self.timer = QTimer( self.obj() if isinstance(self.obj(), QObject) else None ) @@ -1302,19 +1307,18 @@ def _invoke(self, args, kwargs): self.timer.start(int(diff * 1e3)) # self.print_error("deferring") else: - # We had a timer active, which means as future call will occur. So return early and let that call happenin the future. - # Note that a side-effect of this aborted invocation was to update self.saved_args. + # We had a timer active, which means as future call will occur. So return + # early and let that call happenin the future. + # Note that a side-effect of this aborted invocation was to update + # self.saved_args. pass # self.print_error("ignoring (already scheduled)") def _pop_args(self): - ( - args, - kwargs, - ) = ( - self.saved_args - ) # grab the latest collated invocation's args. this attribute is always defined. - self.saved_args = (tuple(), dict()) # clear saved args immediately + # grab the latest collated invocation's args. this attribute is always defined. + args, kwargs = self.saved_args + # clear saved args immediately + self.saved_args = (tuple(), dict()) return args, kwargs def _push_args(self, args, kwargs): @@ -1417,17 +1421,17 @@ def _call_func_for_all(self, weak_dict): obj = ref() if obj: args, kwargs = weak_dict[obj] - # self.print_error("calling for",obj.diagnostic_name() if hasattr(obj, "diagnostic_name") else obj,"timer=",bool(self.timer)) self.func_target(obj, *args, **kwargs) def __init__(self, rate, ts_after, obj, func): - # note: obj here is really the __class__ of the obj because we prepended the class in our custom invoke() above. + # note: obj here is really the __class__ of the obj because we prepended the + # class in our custom invoke() above. super().__init__(rate, ts_after, obj, func) self.func_target = func self.func = self._call_func_for_all - self.saved_args = ( - Weak.KeyDictionary() - ) # we don't use a simple arg tuple, but instead an instance -> args,kwargs dictionary to store collated calls, per instance collated + # we don't use a simple arg tuple, but instead an instance -> args,kwargs + # dictionary to store collated calls, per instance collated + self.saved_args = Weak.KeyDictionary() def rate_limited(rate, *, classlevel=False, ts_after=False): diff --git a/electrumabc_plugins/cosigner_pool/qt.py b/electrumabc_plugins/cosigner_pool/qt.py index 52e8f398306d..6b4a573d4a93 100644 --- a/electrumabc_plugins/cosigner_pool/qt.py +++ b/electrumabc_plugins/cosigner_pool/qt.py @@ -134,9 +134,11 @@ def run(self): self.print_error("exiting.") def stop(self): - # extends DaemonThread by also writing to the timeoutQ to wake up the sleeping thread, if any + # extends DaemonThread by also writing to the timeoutQ to wake up the sleeping + # thread, if any super().stop() - self.timeoutQ.put(None) # wake up sleeper, if any + # wake up sleeper, if any + self.timeoutQ.put(None) def start(self): # overrides DaemonThread -- clears queue on (re)start diff --git a/electrumabc_plugins/fusion/fusion.py b/electrumabc_plugins/fusion/fusion.py index de3460836cb4..899a125f735e 100644 --- a/electrumabc_plugins/fusion/fusion.py +++ b/electrumabc_plugins/fusion/fusion.py @@ -287,7 +287,8 @@ class Fusion(threading.Thread, PrintError): stopping = False stopping_if_not_running = False max_outputs = None - status = ("setup", None) # will always be 2-tuple; second param has extra details + # will always be 2-tuple; second param has extra details + status = ("setup", None) def __init__( self, diff --git a/electrumabc_plugins/fusion/plugin.py b/electrumabc_plugins/fusion/plugin.py index e07cbef60f28..7ce47818f76e 100644 --- a/electrumabc_plugins/fusion/plugin.py +++ b/electrumabc_plugins/fusion/plugin.py @@ -323,9 +323,8 @@ def __init__(self, *args, **kwargs): self.t_last_net_ok = time.monotonic() - self.remote_donation_address: str = ( - "" # optionally announced by the remote server in 'serverhello' message - ) + # optionally announced by the remote server in 'serverhello' message + self.remote_donation_address: str = "" def on_close( self, diff --git a/electrumabc_plugins/fusion/qt.py b/electrumabc_plugins/fusion/qt.py index 29ee17b71275..d64f16f28ab4 100644 --- a/electrumabc_plugins/fusion/qt.py +++ b/electrumabc_plugins/fusion/qt.py @@ -116,13 +116,12 @@ class Plugin(FusionPlugin, QObject): _hide_history_txs = False def __init__(self, *args, **kwargs): - QObject.__init__( - self - ) # parentless top-level QObject. We need this type for the signal. - FusionPlugin.__init__(self, *args, **kwargs) # gives us self.config - self.widgets = ( - weakref.WeakSet() - ) # widgets we made, that need to be hidden & deleted when plugin is disabled + # parentless top-level QObject. We need this type for the signal. + QObject.__init__(self) + # gives us self.config + FusionPlugin.__init__(self, *args, **kwargs) + # widgets we made, that need to be hidden & deleted when plugin is disabled + self.widgets = weakref.WeakSet() self._hide_history_txs = Global(self.config).hide_history_txs def on_close(self): @@ -131,7 +130,8 @@ def on_close(self): # This can be triggered from one wallet's window while # other wallets' windows have plugin-related modals open. for window in self.gui.windows: - # this could be slow since it touches windows one by one... could optimize this by dispatching simultaneously. + # this could be slow since it touches windows one by one... could optimize + # this by dispatching simultaneously. self.on_close_window(window) # Clean up for w in self.widgets: @@ -141,12 +141,12 @@ def on_close(self): w.hide() w.deleteLater() except Exception: - # could be but really we just want to suppress all exceptions + # could be but really we just want to suppress all exceptions pass # clean up member attributes to be tidy - self.fusions_win = ( - None # should trigger a deletion of object if not already dead - ) + # should trigger a deletion of object if not already dead + self.fusions_win = None self.weak_settings_tab = None self.gui = None self.initted = False diff --git a/electrumabc_plugins/fusion/server.py b/electrumabc_plugins/fusion/server.py index eadafcea84b7..446d123697c0 100644 --- a/electrumabc_plugins/fusion/server.py +++ b/electrumabc_plugins/fusion/server.py @@ -324,9 +324,8 @@ def __init__( t: WaitingPool(Params.min_clients, Params.max_tier_client_tags) for t in Params.tiers } - self.t_last_fuse = ( - time.monotonic() - ) # when the last fuse happened; as a placeholder, set this to startup time. + # when the last fuse happened; as a placeholder, set this to startup time. + self.t_last_fuse = time.monotonic() self.reset_timer() def run(self): diff --git a/electrumabc_plugins/fusion/tests/test_encrypt.py b/electrumabc_plugins/fusion/tests/test_encrypt.py index cd719cf233b7..ab0638a0e8b0 100644 --- a/electrumabc_plugins/fusion/tests/test_encrypt.py +++ b/electrumabc_plugins/fusion/tests/test_encrypt.py @@ -59,9 +59,8 @@ def TestNormal(self): e12_bad[0] ^= 1 with self.assertRaises(encrypt.DecryptionFailed): encrypt.decrypt(e12_bad, Apriv) - d12 = encrypt.decrypt_with_symmkey( - e12_bad, k - ) # works because it doesn't care about nonce point + # works because it doesn't care about nonce point + d12 = encrypt.decrypt_with_symmkey(e12_bad, k) self.assertEqual(d12, msg12) # tweak the hmac diff --git a/electrumabc_plugins/labels/labels.py b/electrumabc_plugins/labels/labels.py index 37b964479e8b..350e1fc5d690 100644 --- a/electrumabc_plugins/labels/labels.py +++ b/electrumabc_plugins/labels/labels.py @@ -87,9 +87,8 @@ def do_request(self, method, url="/labels", is_batch=False, data=None, noexc=Fal kwargs["data"] = json.dumps(data) kwargs["headers"]["Content-Type"] = "application/json" - response = requests.request( - method, url, **kwargs, timeout=5.0 - ) # will raise requests.exceptions.Timeout on timeout + # will raise requests.exceptions.Timeout on timeout + response = requests.request(method, url, **kwargs, timeout=5.0) if response.status_code == 400: if "serverNonce is larger then walletNonce" in response.text: @@ -262,7 +261,9 @@ def stop_wallet(self, wallet): return bool(w) def on_close(self): - self.closing = True # this is to minimize chance of race conditions but the way this class is written they can theoretically still happen. c'est la vie. + # this is to minimize chance of race conditions but the way this class is + # written they can theoretically still happen. c'est la vie. + self.closing = True ct = 0 for w in self.wallets.copy(): ct += int(bool(self.stop_wallet(w))) @@ -273,16 +274,17 @@ def on_close(self): continue uniq_thrds.append(t) if t.is_alive(): - t.join() # wait for it to complete + # wait for it to complete + t.join() stopped += 1 self.print_error( - "Plugin closed, stopped {} extant wallets, joined {} extant threads.".format( - ct, stopped - ) + f"Plugin closed, stopped {ct} extant wallets, joined {stopped} extant" + f" threads." ) + # due to very very unlikely race conditions this is in fact a possibility. assert 0 == len( self.threads - ), "Labels Plugin: Threads were left alive on close!" # due to very very unlikely race conditions this is in fact a possibility. + ), "Labels Plugin: Threads were left alive on close!" def on_init(self): """Here for symmetry with on_close. In reality plugins get unloaded diff --git a/electrumabc_plugins/satochip/satochip.py b/electrumabc_plugins/satochip/satochip.py index 50691da4c1ed..99a945cb543d 100644 --- a/electrumabc_plugins/satochip/satochip.py +++ b/electrumabc_plugins/satochip/satochip.py @@ -57,7 +57,7 @@ logging.basicConfig( level=logging.DEBUG, format="%(levelname)s [%(module)s] %(funcName)s | %(message)s" -) # debugSatochip +) # debug: smartcard reader ids SATOCHIP_VID = 0x096E @@ -97,7 +97,7 @@ def __init__(self, plugin, handler): if not LIBS_AVAILABLE: self.print_error("** No libraries available") return - self.print_error("__init__()") # debugSatochip + self.print_error("__init__()") self.device = plugin.device self.handler = handler # self.parser= CardDataParser() @@ -115,7 +115,7 @@ def is_pairable(self): return LIBS_AVAILABLE def close(self): - self.print_error("close()") # debugSatochip + self.print_error("close()") self.cc.card_disconnect() self.cc.cardmonitor.deleteObserver(self.cc.cardobserver) @@ -126,7 +126,7 @@ def is_initialized(self): return LIBS_AVAILABLE def has_usable_connection_with_device(self): - self.print_error("has_usable_connection_with_device()") # debugSatochip + self.print_error("has_usable_connection_with_device()") try: atr = self.cc.card_get_ATR() self.print_error("Card ATR: " + bytes(atr).hex()) @@ -145,7 +145,7 @@ def get_xpub(self, bip32_path, xtype): self.print_error( "get_xpub(): self.handler.win.wallet.storage.authentikey:", hex_authentikey, - ) # debugSatochip + ) if hex_authentikey is not None: self.cc.parser.authentikey_from_storage = ECPubkey( bytes.fromhex(hex_authentikey) @@ -154,14 +154,14 @@ def get_xpub(self, bip32_path, xtype): self.print_error( "get_xpub(): exception when getting authentikey from self.handler.win.wallet.storage:", str(e), - ) # debugSatochip + ) try: # needs PIN self.cc.card_verify_PIN() # bip32_path is of the form 44'/0'/1' - self.print_error("[get_xpub(): bip32_path = ", bip32_path) # debugSatochip + self.print_error("[get_xpub(): bip32_path = ", bip32_path) (depth, bytepath) = bip32path2bytes(bip32_path) (childkey, childchaincode) = self.cc.card_bip32_get_extendedkey(bytepath) @@ -185,7 +185,7 @@ def get_xpub(self, bip32_path, xtype): fingerprint, child_number, ) - self.print_error("SatochipClient: get_xpub(): xpub=", xpub) # debugSatochip + self.print_error("SatochipClient: get_xpub(): xpub=", xpub) return xpub # return BIP32Node(xtype=xtype, # eckey=childkey, @@ -419,7 +419,7 @@ def sign_message(self, sequence, message, password, sigtype=SignatureType.ECASH) return compsig def sign_transaction(self, tx: Transaction, password, *, use_cache=False): - self.print_error("sign_transaction(): tx: " + str(tx)) # debugSatochip + self.print_error("sign_transaction(): tx: " + str(tx)) client = self.get_client() @@ -427,26 +427,20 @@ def sign_transaction(self, tx: Transaction, password, *, use_cache=False): txOutputs = "".join(tx.serialize_output(o) for o in tx.outputs()) hashOutputs = bh2u(Hash(bfh(txOutputs))) txOutputs = var_int(len(tx.outputs())) + txOutputs - self.print_error( - "sign_transaction(): hashOutputs= ", hashOutputs - ) # debugSatochip - self.print_error("sign_transaction(): outputs= ", txOutputs) # debugSatochip + self.print_error("sign_transaction(): hashOutputs= ", hashOutputs) + self.print_error("sign_transaction(): outputs= ", txOutputs) # Fetch inputs of the transaction to sign derivations = self.get_tx_derivations(tx) for i, txin in enumerate(tx.inputs()): - self.print_error("sign_transaction(): input =", i) # debugSatochip - self.print_error( - "sign_transaction(): input[type]:", txin["type"] - ) # debugSatochip + self.print_error("sign_transaction(): input =", i) + self.print_error("sign_transaction(): input[type]:", txin["type"]) if txin["type"] == "coinbase": self.give_error("Coinbase not supported") # should never happen pubkeys, x_pubkeys = tx.get_sorted_pubkeys(txin) for j, x_pubkey in enumerate(x_pubkeys): - self.print_error( - "sign_transaction(): forforloop: j=", j - ) # debugSatochip + self.print_error("sign_transaction(): forforloop: j=", j) if tx.is_txin_complete(txin): break @@ -465,12 +459,8 @@ def sign_transaction(self, tx: Transaction, password, *, use_cache=False): ) # hex representation => converted to bytes pre_hash = Hash(bfh(pre_tx_hex)) pre_hash_hex = pre_hash.hex() - self.print_error( - "sign_transaction(): pre_tx_hex=", pre_tx_hex - ) # debugSatochip - self.print_error( - "sign_transaction(): pre_hash=", pre_hash_hex - ) # debugSatochip + self.print_error("sign_transaction(): pre_tx_hex=", pre_tx_hex) + self.print_error("sign_transaction(): pre_hash=", pre_hash_hex) # (response, sw1, sw2) = client.cc.card_parse_transaction(pre_tx, True) # use 'True' since BCH use BIP143 as in Segwit... # print_error('[satochip] sign_transaction(): response= '+str(response)) #debugSatochip # (tx_hash, needs_2fa) = client.parser.parse_parse_transaction(response) @@ -603,7 +593,7 @@ def __init__(self, parent, config, name): if not LIBS_AVAILABLE: return - self.print_error("init()") # debugSatochip + self.print_error("init()") # self.libraries_available = self.check_libraries_available() #debugSatochip # if not self.libraries_available: @@ -616,12 +606,12 @@ def get_library_version(self): return "0.0.1" def detect_smartcard_reader(self): - self.print_error("detect_smartcard_reader") # debugSatochip + self.print_error("detect_smartcard_reader") self.cardtype = AnyCardType() try: cardrequest = CardRequest(timeout=0.1, cardType=self.cardtype) cardrequest.waitforcard() - self.print_error("detect_smartcard_reader: found card!") # debugSatochip + self.print_error("detect_smartcard_reader: found card!") return [ Device( path="/satochip", @@ -643,7 +633,7 @@ def detect_smartcard_reader(self): return [] def create_client(self, device, handler): - self.print_error("create_client()") # debugSatochip + self.print_error("create_client()") if handler: self.handler = handler @@ -655,7 +645,7 @@ def create_client(self, device, handler): return None def setup_device(self, device_info, wizard, purpose): - self.print_error("setup_device()") # debugSatochip + self.print_error("setup_device()") if not LIBS_AVAILABLE: raise RuntimeError("No libraries available") @@ -683,7 +673,7 @@ def setup_device(self, device_info, wizard, purpose): v_applet = d["protocol_version"] self.print_error( f"[SatochipPlugin] setup_device(): Satochip version={hex(v_applet)} Electrum supported version= {hex(v_supported)}" - ) # debugSatochip + ) if v_supported < v_applet: msg = ( _( @@ -754,7 +744,7 @@ def setup_device(self, device_info, wizard, purpose): + hex(sw1) + " " + hex(sw2) - ) # debugSatochip + ) raise RuntimeError( "Unable to setup the device with error code:" + hex(sw1) @@ -804,33 +794,31 @@ def setup_device(self, device_info, wizard, purpose): if sw1 != 0x90 or sw2 != 0x00: self.print_error( f"setup_device(): unable to set 2FA! sw12={hex(sw1)},{hex(sw2)}" - ) # debugSatochip + ) raise RuntimeError( f"Unable to setup 2FA with error code: {hex(sw1)} {hex(sw2)}" ) # seed dialog... - self.print_error("setup_device(): import seed:") # debugSatochip + self.print_error("setup_device(): import seed:") self.choose_seed(wizard) seed = list(self.bip32_seed) authentikey = client.cc.card_bip32_import_seed(seed) hex_authentikey = authentikey.get_public_key_hex(compressed=True) - self.print_error( - "setup_device(): authentikey=", hex_authentikey - ) # debugSatochip + self.print_error("setup_device(): authentikey=", hex_authentikey) wizard.data["authentikey"] = hex_authentikey self.print_error( "setup_device(): authentikey from storage=", wizard.data["authentikey"] - ) # debugSatochip + ) break return client def get_xpub(self, device_id, derivation, xtype, wizard): # this seems to be part of the pairing process only, not during normal ops? # base_wizard:on_hw_derivation - self.print_error("get_xpub()") # debugSatochip + self.print_error("get_xpub()") # if xtype not in self.SUPPORTED_XTYPES: # raise ScriptTypeNotSupported(_('This type of script is not supported with {}.').format(self.device)) client = self.scan_and_create_client_for_device( From e358fe135137ff4132ee396598bba1ada886a997 Mon Sep 17 00:00:00 2001 From: PiRK Date: Fri, 13 Jan 2023 09:40:03 +0100 Subject: [PATCH 8/9] [mypy] don't use implicit optionals This is explicitely prohibited by PEP 484 --- electrumabc/address.py | 6 ++--- electrumabc/base_wizard.py | 2 +- electrumabc/bitcoin.py | 6 ++--- electrumabc/contacts.py | 7 ++++-- electrumabc/plugins.py | 4 ++-- electrumabc/transaction.py | 4 ++-- electrumabc/wallet.py | 4 ++-- electrumabc/winconsole.py | 22 +++++++++---------- electrumabc_gui/qt/avalanche/proof_editor.py | 2 +- electrumabc_gui/qt/avalanche/util.py | 4 ++-- electrumabc_gui/qt/main_window.py | 2 +- .../qt/qrreader/crop_blur_effect.py | 5 +++-- electrumabc_gui/qt/qrreader/video_overlay.py | 4 ++-- electrumabc_gui/qt/qrreader/video_surface.py | 4 ++-- electrumabc_gui/qt/qrreader/video_widget.py | 3 ++- electrumabc_gui/qt/sign_verify_dialog.py | 4 +++- electrumabc_gui/qt/style_patcher.py | 3 ++- electrumabc_gui/qt/util.py | 9 ++++---- electrumabc_gui/qt/utils/aspect_layout.py | 6 +++-- electrumabc_gui/qt/utils/aspect_svg_widget.py | 5 ++++- electrumabc_plugins/fusion/plugin.py | 2 +- 21 files changed, 60 insertions(+), 48 deletions(-) diff --git a/electrumabc/address.py b/electrumabc/address.py index b096d2981b4e..8190948653d3 100644 --- a/electrumabc/address.py +++ b/electrumabc/address.py @@ -28,7 +28,7 @@ import hashlib import struct from collections import namedtuple -from typing import Tuple, Union +from typing import Optional, Tuple, Union from . import cashaddr, networks from .bitcoin import ( @@ -394,7 +394,7 @@ def from_cashaddr_string( cls, string: str, *, - net: networks.AbstractNet = None, + net: Optional[networks.AbstractNet] = None, support_arbitrary_prefix: bool = False, ): """Construct from a cashaddress string. @@ -451,7 +451,7 @@ def from_string( cls, string: str, *, - net: networks.AbstractNet = None, + net: Optional[networks.AbstractNet] = None, support_arbitrary_prefix: bool = False, ): """Construct from an address string. diff --git a/electrumabc/base_wizard.py b/electrumabc/base_wizard.py index f5d21308d8ae..ed54a2e867b3 100644 --- a/electrumabc/base_wizard.py +++ b/electrumabc/base_wizard.py @@ -146,7 +146,7 @@ def do_upgrade(): do_upgrade, _("Upgrading wallet format..."), on_finished=on_finished ) - def run_task_without_blocking_gui(self, task, *, msg: str = None) -> Any: + def run_task_without_blocking_gui(self, task, *, msg: Optional[str] = None) -> Any: """Perform a task in a thread without blocking the GUI. Returns the result of 'task', or raises the same exception. This method blocks until 'task' is finished. diff --git a/electrumabc/bitcoin.py b/electrumabc/bitcoin.py index 1ea6e147ff3a..93fdaceb46db 100644 --- a/electrumabc/bitcoin.py +++ b/electrumabc/bitcoin.py @@ -1508,13 +1508,13 @@ def __init__(self, enc, *, net=None): ) @property - def lot(self) -> int: + def lot(self) -> Optional[int]: """Returns the 'lot' number if 'hasLotSequence' or None otherwise.""" if self.dec and self.hasLotSequence: return self.entropy[4] * 4096 + self.entropy[5] * 16 + self.entropy[6] // 16 @property - def sequence(self) -> int: + def sequence(self) -> Optional[int]: """Returns the 'sequence' number if 'hasLotSequence' or None otherwise.""" if self.dec and self.hasLotSequence: @@ -1783,7 +1783,7 @@ def encrypt(cls, wif: str, passphrase: str, *, net=None) -> object: def createECMult( cls, passphrase: str, - lot_sequence: Tuple[int, int] = None, + lot_sequence: Optional[Tuple[int, int]] = None, compressed=True, *, net=None, diff --git a/electrumabc/contacts.py b/electrumabc/contacts.py index 20c10dc8f230..40210ed038d2 100644 --- a/electrumabc/contacts.py +++ b/electrumabc/contacts.py @@ -26,7 +26,7 @@ import re import traceback from collections import namedtuple -from typing import List +from typing import List, Optional import dns from dns.exception import DNSException @@ -303,7 +303,10 @@ def replace(self, old: Contact, new: Contact): return False def add( - self, contact: Contact, replace_old: Contact = None, unique: bool = False + self, + contact: Contact, + replace_old: Optional[Contact] = None, + unique: bool = False, ) -> bool: """Puts a contact in the contact list, appending it at the end. Optionally, if replace_old is specified, will replace the entry diff --git a/electrumabc/plugins.py b/electrumabc/plugins.py index 6052375f811a..835ee366d7c3 100644 --- a/electrumabc/plugins.py +++ b/electrumabc/plugins.py @@ -1092,7 +1092,7 @@ def unpaired_device_infos( self, handler: Optional[HardwareHandlerBase], plugin: HW_PluginBase, - devices: List[Device] = None, + devices: Optional[List[Device]] = None, ) -> List["DeviceInfo"]: """Returns a list of DeviceInfo objects: one for each connected, unpaired device accepted by the plugin.""" @@ -1122,7 +1122,7 @@ def select_device( plugin: HW_PluginBase, handler: HardwareHandlerBase, keystore: Hardware_KeyStore, - devices: List["Device"] = None, + devices: Optional[List["Device"]] = None, ) -> DeviceInfo: """Ask the user to select a device to use if there is more than one, and return the DeviceInfo for the device.""" diff --git a/electrumabc/transaction.py b/electrumabc/transaction.py index 73fa97d52539..08d688e52110 100644 --- a/electrumabc/transaction.py +++ b/electrumabc/transaction.py @@ -26,7 +26,7 @@ import hashlib import struct import warnings -from typing import Tuple, Union +from typing import Optional, Tuple, Union import ecdsa @@ -1574,7 +1574,7 @@ def tx_cache_get(cls, txid: str) -> object: return None @classmethod - def tx_cache_put(cls, tx: object, txid: str = None): + def tx_cache_put(cls, tx: object, txid: Optional[str] = None): """Puts a non-deserialized copy of tx into the tx_cache.""" if not tx or not tx.raw: raise ValueError("Please pass a tx which has a valid .raw attribute!") diff --git a/electrumabc/wallet.py b/electrumabc/wallet.py index c7fadd40d3a7..8f64772393ba 100644 --- a/electrumabc/wallet.py +++ b/electrumabc/wallet.py @@ -2954,12 +2954,12 @@ def rebuild_history(self): self.start_threads(network) self.network.trigger_callback("wallet_updated", self) - def is_schnorr_possible(self, reason: list = None) -> bool: + def is_schnorr_possible(self, reason: Optional[list] = None) -> bool: """Returns True if this wallet type is compatible. `reason` is an optional list where you would like a translated string of why Schnorr isn't possible placed (on False return).""" ok = bool(not self.is_multisig() and not self.is_hardware()) - if not ok and isinstance(reason, list): + if not ok and reason is not None: reason.insert(0, _("Schnorr signatures are disabled for this wallet type.")) return ok diff --git a/electrumabc/winconsole.py b/electrumabc/winconsole.py index 1ca06ed3732d..981d44eb2a80 100644 --- a/electrumabc/winconsole.py +++ b/electrumabc/winconsole.py @@ -32,12 +32,13 @@ import ctypes import os import sys +from typing import Iterator, Optional STD_OUTPUT_HANDLE = -11 FILE_TYPE_DISK = 1 -def parent_process_pids() -> int: +def parent_process_pids() -> Iterator[int]: """ Returns all parent process PIDs, starting with the closest parent """ @@ -58,16 +59,15 @@ def get_console_title() -> str: b = bytes(1024) b_ptr = ctypes.c_char_p(b) title = None - title_len = ctypes.windll.kernel32.GetConsoleTitleW( - b_ptr, len(b) // 2 - ) # GetConsoleTitleW expects size in 2-byte chars + # GetConsoleTitleW expects size in 2-byte chars + title_len = ctypes.windll.kernel32.GetConsoleTitleW(b_ptr, len(b) // 2) # type: ignore[attr-defined] if title_len > 0: title = b.decode("utf-16")[:title_len] return title def create_or_attach_console( - *, attach: bool = True, create: bool = False, title: str = None + *, attach: bool = True, create: bool = False, title: Optional[str] = None ) -> bool: """ Workaround to the fact that cmd.exe based execution of this program means @@ -90,8 +90,7 @@ def create_or_attach_console( (sys.stdout, sys.stderr) to this found and/or created console. Always return True on success or if there was a console already, - False or None on failure (a None return indicates a missing lib or some - other unspecified exception was raised when attempting to create a console). + False on failure. """ std_out_handle = ctypes.windll.kernel32.GetStdHandle(STD_OUTPUT_HANDLE) @@ -111,7 +110,7 @@ def create_or_attach_console( break except ImportError: # User's system lacks psutil - return # Return None in case caller wants to differntiate exceptional failures from regular False return + return False created = False @@ -134,12 +133,11 @@ def create_or_attach_console( except OSError: # If we get here, we likely were in MinGW / MSYS where CONOUT$ / CONIN$ # are not valid files or some other weirdness occurred. Give up. - return # return None to indicate underlying exception + return False if title: - old_title = ( - get_console_title() if not created else None - ) # save the old title only if not created by us + # save the old title only if not created by us + old_title = get_console_title() if not created else None # Set the console title, if specified ctypes.windll.kernel32.SetConsoleTitleW(title) if old_title is not None: diff --git a/electrumabc_gui/qt/avalanche/proof_editor.py b/electrumabc_gui/qt/avalanche/proof_editor.py index 1888891d6451..f7340e7a4507 100644 --- a/electrumabc_gui/qt/avalanche/proof_editor.py +++ b/electrumabc_gui/qt/avalanche/proof_editor.py @@ -79,7 +79,7 @@ def __init__( self, wallet: Deterministic_Wallet, receive_address: Optional[Address] = None, - parent: QtWidgets.QWidget = None, + parent: Optional[QtWidgets.QWidget] = None, ): CachedWalletPasswordWidget.__init__(self, wallet, parent=parent) # This is enough width to show a whole compressed pubkey. diff --git a/electrumabc_gui/qt/avalanche/util.py b/electrumabc_gui/qt/avalanche/util.py index d195472cf16e..5a1b92d36f79 100644 --- a/electrumabc_gui/qt/avalanche/util.py +++ b/electrumabc_gui/qt/avalanche/util.py @@ -42,7 +42,7 @@ def __init__( self, wallet: Deterministic_Wallet, pwd: Optional[str] = None, - parent: QtWidgets.QWidget = None, + parent: Optional[QtWidgets.QWidget] = None, ): super().__init__(parent) self._pwd = pwd @@ -168,7 +168,7 @@ def __init__( self, wallet: Deterministic_Wallet, pwd: Optional[str] = None, - parent: QtWidgets.QWidget = None, + parent: Optional[QtWidgets.QWidget] = None, additional_info: Optional[str] = None, ): super().__init__(parent) diff --git a/electrumabc_gui/qt/main_window.py b/electrumabc_gui/qt/main_window.py index bff31e3556b0..7e5181bfda10 100644 --- a/electrumabc_gui/qt/main_window.py +++ b/electrumabc_gui/qt/main_window.py @@ -3447,7 +3447,7 @@ def change_password_dialog(self): self.status_bar.update_lock_icon(self.wallet.has_password()) def get_passphrase_dialog( - self, msg: str, title: str = None, *, permit_empty=False + self, msg: str, title: Optional[str] = None, *, permit_empty=False ) -> str: d = PassphraseDialog( self.wallet, self.top_level_window(), msg, title, permit_empty=permit_empty diff --git a/electrumabc_gui/qt/qrreader/crop_blur_effect.py b/electrumabc_gui/qt/qrreader/crop_blur_effect.py index 6c49b29ff7e0..ccf438a9743f 100644 --- a/electrumabc_gui/qt/qrreader/crop_blur_effect.py +++ b/electrumabc_gui/qt/qrreader/crop_blur_effect.py @@ -23,6 +23,7 @@ # ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from typing import Optional from PyQt5 import QtWidgets from PyQt5.QtCore import QObject, QPoint, QRect, Qt @@ -36,12 +37,12 @@ class QrReaderCropBlurEffect(QtWidgets.QGraphicsBlurEffect): BLUR_DARKEN = 0.25 BLUR_RADIUS = 8 - def __init__(self, parent: QObject, crop: QRect = None): + def __init__(self, parent: QObject, crop: Optional[QRect] = None): super().__init__(parent) self.crop = crop self.setBlurRadius(self.BLUR_RADIUS) - def setCrop(self, crop: QRect = None): + def setCrop(self, crop: Optional[QRect] = None): self.crop = crop def draw(self, painter: QPainter): diff --git a/electrumabc_gui/qt/qrreader/video_overlay.py b/electrumabc_gui/qt/qrreader/video_overlay.py index 9b72c1a9f838..27bf2778fae4 100644 --- a/electrumabc_gui/qt/qrreader/video_overlay.py +++ b/electrumabc_gui/qt/qrreader/video_overlay.py @@ -24,7 +24,7 @@ # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. -from typing import List +from typing import List, Optional from PyQt5 import QtWidgets from PyQt5.QtCore import QPoint, QRect, QRectF, QSize, Qt @@ -48,7 +48,7 @@ class QrReaderVideoOverlay(QtWidgets.QWidget): QR_FINDER_OPACITY = 0.25 QR_FINDER_SIZE = 0.5 - def __init__(self, parent: QtWidgets.QWidget = None): + def __init__(self, parent: Optional[QtWidgets.QWidget] = None): super().__init__(parent) self.results = [] diff --git a/electrumabc_gui/qt/qrreader/video_surface.py b/electrumabc_gui/qt/qrreader/video_surface.py index 478234157509..b83765e2b8c1 100644 --- a/electrumabc_gui/qt/qrreader/video_surface.py +++ b/electrumabc_gui/qt/qrreader/video_surface.py @@ -24,7 +24,7 @@ # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. -from typing import List +from typing import List, Optional from PyQt5.QtCore import QObject, pyqtSignal from PyQt5.QtGui import QImage @@ -45,7 +45,7 @@ class QrReaderVideoSurface(QAbstractVideoSurface): necessary and sends them to listeners via the frame_available event. """ - def __init__(self, parent: QObject = None): + def __init__(self, parent: Optional[QObject] = None): super().__init__(parent) def present(self, frame: QVideoFrame) -> bool: diff --git a/electrumabc_gui/qt/qrreader/video_widget.py b/electrumabc_gui/qt/qrreader/video_widget.py index a013efeba8a2..0c9895e97d6d 100644 --- a/electrumabc_gui/qt/qrreader/video_widget.py +++ b/electrumabc_gui/qt/qrreader/video_widget.py @@ -23,6 +23,7 @@ # ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from typing import Optional from PyQt5 import QtWidgets from PyQt5.QtGui import QPainter, QPaintEvent, QPixmap @@ -35,7 +36,7 @@ class QrReaderVideoWidget(QtWidgets.QWidget): USE_BILINEAR_FILTER = True - def __init__(self, parent: QtWidgets.QWidget = None): + def __init__(self, parent: Optional[QtWidgets.QWidget] = None): super().__init__(parent) self.pixmap = None diff --git a/electrumabc_gui/qt/sign_verify_dialog.py b/electrumabc_gui/qt/sign_verify_dialog.py index b9eb37834d5b..b3902ab6ff8b 100644 --- a/electrumabc_gui/qt/sign_verify_dialog.py +++ b/electrumabc_gui/qt/sign_verify_dialog.py @@ -33,7 +33,9 @@ class CollapsibleSection(QWidget): - def __init__(self, title: str, content_widget: QWidget, parent: QWidget = None): + def __init__( + self, title: str, content_widget: QWidget, parent: Optional[QWidget] = None + ): super().__init__(parent) main_layout = QGridLayout(self) diff --git a/electrumabc_gui/qt/style_patcher.py b/electrumabc_gui/qt/style_patcher.py index 8ca8a7527097..0c0bd2a54e6c 100644 --- a/electrumabc_gui/qt/style_patcher.py +++ b/electrumabc_gui/qt/style_patcher.py @@ -2,6 +2,7 @@ This is used to patch the QApplication style sheet. It reads the current stylesheet, appends our modifications and sets the new stylesheet. """ +from typing import Optional from PyQt5 import QtWidgets @@ -37,7 +38,7 @@ """ -def patch(use_dark_theme: bool = False, darkstyle_ver: tuple = None): +def patch(use_dark_theme: bool = False, darkstyle_ver: Optional[tuple] = None): if not use_dark_theme: return custom_patch = "" diff --git a/electrumabc_gui/qt/util.py b/electrumabc_gui/qt/util.py index 11e3b7a4f2e1..10ddffb5c964 100644 --- a/electrumabc_gui/qt/util.py +++ b/electrumabc_gui/qt/util.py @@ -9,6 +9,7 @@ from collections import namedtuple from functools import partial, wraps from locale import atof +from typing import Optional from PyQt5 import QtWidgets from PyQt5.QtCore import QObject, Qt, QThread, QTimer, pyqtSignal @@ -980,7 +981,7 @@ def _updateOverlayPos(self): x -= scrollbar_width self.overlay_widget.move(x, y) - def addWidget(self, widget: QtWidgets.QWidget, index: int = None): + def addWidget(self, widget: QtWidgets.QWidget, index: Optional[int] = None): if index is not None: self.overlay_layout.insertWidget(index, widget) else: @@ -991,9 +992,9 @@ def addButton( icon_name: str, on_click, tooltip: str, - index: int = None, + index: Optional[int] = None, *, - text: str = None, + text: Optional[str] = None, ) -> QtWidgets.QAbstractButton: """icon_name may be None but then you must define text (which is hopefully then some nice Unicode character). Both cannot be None. @@ -1540,7 +1541,7 @@ class TextBrowserKeyboardFocusFilter(QtWidgets.QTextBrowser): deactivate keyboard text selection. """ - def __init__(self, parent: QtWidgets.QWidget = None): + def __init__(self, parent: Optional[QtWidgets.QWidget] = None): super().__init__(parent) def focusInEvent(self, e: QFocusEvent): diff --git a/electrumabc_gui/qt/utils/aspect_layout.py b/electrumabc_gui/qt/utils/aspect_layout.py index d610fa8b0c8e..609b2dd28a7a 100644 --- a/electrumabc_gui/qt/utils/aspect_layout.py +++ b/electrumabc_gui/qt/utils/aspect_layout.py @@ -24,14 +24,16 @@ # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. -from typing import List +from typing import List, Optional from PyQt5 import QtWidgets from PyQt5.QtCore import QPoint, QRect, QSize, Qt class FixedAspectRatioLayout(QtWidgets.QLayout): - def __init__(self, parent: QtWidgets.QWidget = None, aspect_ratio: float = 1.0): + def __init__( + self, parent: Optional[QtWidgets.QWidget] = None, aspect_ratio: float = 1.0 + ): super().__init__(parent) self.aspect_ratio = aspect_ratio self.items: List[QtWidgets.QLayoutItem] = [] diff --git a/electrumabc_gui/qt/utils/aspect_svg_widget.py b/electrumabc_gui/qt/utils/aspect_svg_widget.py index 62fa3428c6b5..cf1946f0357c 100644 --- a/electrumabc_gui/qt/utils/aspect_svg_widget.py +++ b/electrumabc_gui/qt/utils/aspect_svg_widget.py @@ -23,13 +23,16 @@ # ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from typing import Optional from PyQt5.QtCore import QObject, QSize from PyQt5.QtSvg import QSvgWidget class FixedAspectRatioSvgWidget(QSvgWidget): - def __init__(self, width: int, file: str = None, parent: QObject = None): + def __init__( + self, width: int, file: Optional[str] = None, parent: Optional[QObject] = None + ): if file: super().__init__(file, parent) else: diff --git a/electrumabc_plugins/fusion/plugin.py b/electrumabc_plugins/fusion/plugin.py index 7ce47818f76e..33d3df45a534 100644 --- a/electrumabc_plugins/fusion/plugin.py +++ b/electrumabc_plugins/fusion/plugin.py @@ -761,7 +761,7 @@ def update_coins_ui(self, wallet): This is called by the Fusion thread (in its thread context) when it freezes & unfreezes coins.""" - def notify_server_status(self, b, tup: tuple = None): + def notify_server_status(self, b, tup: Optional[tuple] = None): """The Qt plugin subclass implements this to tell the GUI about bad servers.""" if not b: From 3a62d7f74b4ceb75979b598475d47b38afc64377 Mon Sep 17 00:00:00 2001 From: PiRK Date: Fri, 13 Jan 2023 14:43:07 +0100 Subject: [PATCH 9/9] move more same line comments to previous line Focus on the longest comments that are most likely to cause problems with black formatting. --- electrumabc/base_wizard.py | 10 +- electrumabc/bitcoin.py | 15 +- electrumabc/caches.py | 6 +- electrumabc/commands.py | 4 +- electrumabc/contacts.py | 6 +- electrumabc/network.py | 61 +++++---- electrumabc/paymentrequest.py | 7 +- electrumabc/qrreaders/osxqrdetect.py | 6 +- electrumabc/slp/slp.py | 35 +++-- electrumabc/synchronizer.py | 16 +-- electrumabc/transaction.py | 11 +- electrumabc/util.py | 17 ++- electrumabc/utils/event.py | 11 +- electrumabc/verifier.py | 6 +- electrumabc/wallet.py | 35 +++-- electrumabc_gui/qt/__init__.py | 50 +++---- electrumabc_gui/qt/address_dialog.py | 6 +- electrumabc_gui/qt/bip38_importer.py | 35 +++-- electrumabc_gui/qt/contact_list.py | 13 +- electrumabc_gui/qt/external_plugins_window.py | 3 +- electrumabc_gui/qt/history_list.py | 4 +- electrumabc_gui/qt/main_window.py | 128 ++++++++---------- electrumabc_gui/qt/network_dialog.py | 27 ++-- electrumabc_gui/qt/popup_widget.py | 8 +- electrumabc_gui/qt/qrwindow.py | 11 +- electrumabc_gui/qt/transaction_dialog.py | 11 +- electrumabc_gui/qt/util.py | 12 +- electrumabc_plugins/fusion/pedersen.py | 6 +- electrumabc_plugins/fusion/qt.py | 37 +++-- electrumabc_plugins/fusion/server.py | 6 +- electrumabc_plugins/hw_wallet/plugin.py | 13 +- electrumabc_plugins/labels/labels.py | 3 +- electrumabc_plugins/labels/qt.py | 12 +- electrumabc_plugins/trezor/qt.py | 16 ++- 34 files changed, 327 insertions(+), 320 deletions(-) diff --git a/electrumabc/base_wizard.py b/electrumabc/base_wizard.py index ed54a2e867b3..2c4af3f5c2e7 100644 --- a/electrumabc/base_wizard.py +++ b/electrumabc/base_wizard.py @@ -254,13 +254,15 @@ def on_import(self, text): return for b38, tup in decrypted.items(): wif, adr = tup - text = text.replace( - b38, wif - ) # kind of a hack.. but works. replace the bip38 key with the wif key in the text. + # kind of a hack.. but works. replace the bip38 key with the wif + # key in the text. + text = text.replace(b38, wif) self.keystores = [keystore.from_private_key_list(text)] self.data["wallet_type"] = self.wallet_type = "imported_privkey" - self.reset_stack() # 'Back' button wasn't working anyway at this point, so we just force it to read 'Cancel' and this proceeds with no password set. + # 'Back' button wasn't working anyway at this point, so we just force it to + # read 'Cancel' and this proceeds with no password set. + self.reset_stack() else: return self.terminate() return self.run("create_wallet") diff --git a/electrumabc/bitcoin.py b/electrumabc/bitcoin.py index 93fdaceb46db..ad256699e752 100644 --- a/electrumabc/bitcoin.py +++ b/electrumabc/bitcoin.py @@ -1650,9 +1650,8 @@ def decrypt( self, passphrase: str ) -> Tuple[str, object]: # returns the (wifkey string, Address object) assert isinstance(passphrase, str), "Passphrase must be a string!" - passphrase = self._normalizeNFC( - passphrase - ) # ensure unicode bytes are normalized to NFC standard as specified by bip38 + # ensure unicode bytes are normalized to NFC standard as specified by bip38 + passphrase = self._normalizeNFC(passphrase) if self.typ == Bip38Key.Type.NonECMult: return self._decryptNoEC(passphrase) elif self.typ != Bip38Key.Type.ECMult: @@ -1747,9 +1746,8 @@ def encrypt(cls, wif: str, passphrase: str, *, net=None) -> object: public_key = public_key_from_private_key(key_bytes, compressed) addr_str = pubkey_to_address(_type, public_key, net=net) addr_hash = Hash(addr_str)[0:4] - passphrase = cls._normalizeNFC( - passphrase - ) # ensure unicode bytes are normalized to NFC standard as specified by bip38 + # ensure unicode bytes are normalized to NFC standard as specified by bip38 + passphrase = cls._normalizeNFC(passphrase) derived_key = cls._scrypt(passphrase, addr_hash, N=16384, r=8, p=8, dkLen=64) @@ -1835,9 +1833,8 @@ def createECMult( ignored, passpoint = get_pubkeys_from_secret(passfactor) - intermediate_passphrase_string = ( - magic + ownerentropy + passpoint - ) # 49 bytes (not a str, despite name. We use the name from bip38 spec here) + # 49 bytes (not a str, despite name. We use the name from bip38 spec here) + intermediate_passphrase_string = magic + ownerentropy + passpoint enc = EncodeBase58Check(intermediate_passphrase_string) return cls.ec_mult_from_intermediate_passphrase_string(enc, compressed) diff --git a/electrumabc/caches.py b/electrumabc/caches.py index 5a5568d90e89..47f8c8a74293 100644 --- a/electrumabc/caches.py +++ b/electrumabc/caches.py @@ -230,9 +230,9 @@ def mgr_thread(self): ) ) # 2. maxlen check (always on) - len_c = len( - c.d - ) # capture length here as c.d may mutate and grow while this code executes. + # capture length here as c.d may mutate and grow while this code + # executes. + len_c = len(c.d) if len_c > c.maxlen: t0 = time.time() num = cls._try_to_expire_old_items(c.d, len_c - c.maxlen) diff --git a/electrumabc/commands.py b/electrumabc/commands.py index bcedc5c378a6..03ea693adabe 100644 --- a/electrumabc/commands.py +++ b/electrumabc/commands.py @@ -834,7 +834,9 @@ def trigger_callback(self, *args, **kwargs): fakenet = FakeNetwork(q) fx = FxThread(self.config, fakenet) kwargs["fx"] = fx - fx.run() # invoke the fx to grab history rates at least once, otherwise results will always contain "No data" (see #1671) + # invoke the fx to grab history rates at least once, otherwise results will + # always contain "No data" (see #1671) + fx.run() if fakenet and q and fx.is_enabled() and fx.get_history_config(): # queue.get docs aren't clean on whether 0 means block or don't # block, so we ensure at least 1ms timeout. diff --git a/electrumabc/contacts.py b/electrumabc/contacts.py index 40210ed038d2..6f00523613d6 100644 --- a/electrumabc/contacts.py +++ b/electrumabc/contacts.py @@ -181,9 +181,9 @@ def import_file(self, path: str) -> int: } # make it look like a dict with 'contacts' in it so that it resembles a wallet file, and next call to _load_from_dict_like_object works contacts = self._load_from_dict_like_object(d) for contact in contacts: - res = self.add( - contact, unique=True - ) # enforce unique imports in case user imports the same file multiple times + # enforce unique imports in case user imports the same file + # multiple times + res = self.add(contact, unique=True) if res: count += 1 except Exception: diff --git a/electrumabc/network.py b/electrumabc/network.py index bdcfd4b78c1c..b180821556a9 100644 --- a/electrumabc/network.py +++ b/electrumabc/network.py @@ -250,21 +250,26 @@ class Network(util.DaemonThread): is_connected(), set_parameters(), stop() """ - INSTANCE = None # Only 1 Network instance is ever alive during app lifetime (it's a singleton) + # Only 1 Network instance is ever alive during app lifetime (it's a singleton) + INSTANCE = None # These defaults are decent for the desktop app. Other platforms may # override these at any time (iOS sets these to lower values). - NODES_RETRY_INTERVAL = 60 # How often to retry a node we know about in secs, if we are connected to less than 10 nodes - SERVER_RETRY_INTERVAL = 10 # How often to reconnect when server down in secs - MAX_MESSAGE_BYTES = ( - 1024 * 1024 * 32 - ) # = 32MB. The message size limit in bytes. This is to prevent a DoS vector whereby the server can fill memory with garbage data. + # + # How often to retry a node we know about in secs, if we are connected to less than + # 10 nodes + NODES_RETRY_INTERVAL = 60 + # How often to reconnect when server down in secs + SERVER_RETRY_INTERVAL = 10 + # = 32MB. The message size limit in bytes. This is to prevent a DoS vector whereby + # the server can fill memory with garbage data. + MAX_MESSAGE_BYTES = 1024 * 1024 * 32 tor_controller: TorController = None def __init__(self, config=None): if config is None: - config = {} # Do not use mutables as default values! + config = {} util.DaemonThread.__init__(self) self.config = SimpleConfig(config) if isinstance(config, dict) else config self.num_server = 10 if not self.config.get("oneserver") else 0 @@ -534,12 +539,11 @@ def queue_request( if interface is None: interface = self.interface elif interface == "random": - interface = random.choice( - self.get_interfaces(interfaces=True) or (None,) - ) # may set interface to None if no interfaces - message_id = ( - self.message_id() - ) # Note: self.message_id is a Monotonic (thread-safe) counter-object, see util.Monotonic + # may set interface to None if no interfaces + interface = random.choice(self.get_interfaces(interfaces=True) or (None,)) + # Note: self.message_id is a Monotonic (thread-safe) counter-object, + # see util.Monotonic + message_id = self.message_id() if callback: if max_qlen and len(self.unanswered_requests) >= max_qlen: # Indicate to client code we are busy @@ -588,9 +592,9 @@ def send_subscriptions(self): # missing a callback (no entry in self.subscriptions dict). # self.print_error("removing defunct subscription", h) self.subscribed_addresses.discard(h) - self.subscriptions.pop( - k, None - ) # it may be an empty list (or missing), so pop it just in case it's a list. + # it may be an empty list (or missing), so pop it just in case it's a + # list. + self.subscriptions.pop(k, None) n_defunct += 1 self.print_error( "sent subscriptions to", @@ -1437,13 +1441,15 @@ def on_block_headers(self, interface, request, response): target_blockchain = interface.blockchain chunk_data = bytes.fromhex(hexdata) + # fix #1079 -- invariant is violated here due to extant bugs, so rather than + # raise an exception, just trigger a connection_down below... connect_state = ( target_blockchain.connect_chunk( request_base_height, chunk_data, proof_was_provided ) if target_blockchain else blockchain.CHUNK_BAD - ) # fix #1079 -- invariant is violated here due to extant bugs, so rather than raise an exception, just trigger a connection_down below... + ) if connect_state == blockchain.CHUNK_ACCEPTED: interface.print_error( "connected chunk, height={} count={} proof_was_provided={}".format( @@ -2178,10 +2184,11 @@ def broadcast_transaction(self, transaction, callback=None): try: out = self.broadcast_transaction2(transaction) - except Exception as e: # catch-all. May be util.TimeoutException, util.ServerError subclass or other. - return False, "error: " + str( - e - ) # Ergh. To remain compatible with old code we prepend this ugly "error: " + except Exception as e: + # catch-all. May be util.TimeoutException, util.ServerError subclass + # or other. + # Ergh. To remain compatible with old code we prepend this ugly "error: " + return False, "error: " + str(e) return True, out @@ -2498,12 +2505,12 @@ def _compute_whitelist(self): hostmap_to_servers(networks.net.DEFAULT_SERVERS) ) ret = set(self._hardcoded_whitelist) - ret |= set( - self.config.get("server_whitelist_added", []) - ) # this key is all the servers that weren't in the hardcoded whitelist that the user explicitly added - ret -= set( - self.config.get("server_whitelist_removed", []) - ) # this key is all the servers that were hardcoded in the whitelist that the user explicitly removed + # this key is all the servers that weren't in the hardcoded whitelist that the + # user explicitly added + ret |= set(self.config.get("server_whitelist_added", [])) + # this key is all the servers that were hardcoded in the whitelist that the + # user explicitly removed + ret -= set(self.config.get("server_whitelist_removed", [])) return ret, servers_to_hostmap(ret) def is_whitelist_only(self): diff --git a/electrumabc/paymentrequest.py b/electrumabc/paymentrequest.py index b68fe6340ad6..0c6bcf1f6786 100644 --- a/electrumabc/paymentrequest.py +++ b/electrumabc/paymentrequest.py @@ -305,10 +305,9 @@ def get_outputs(self): def send_payment(self, raw_tx, refund_addr): pay_det = self.details if not self.details.payment_url: - return ( - False, - "no url", - ) # note caller is expecting this exact string in the "no payment url specified" case. see main_window.py + # note caller is expecting this exact string in the "no payment url + # specified" case. see main_window.py + return False, "no url" paymnt = pb2.Payment() paymnt.merchant_data = pay_det.merchant_data paymnt.transactions.append(bfh(raw_tx)) diff --git a/electrumabc/qrreaders/osxqrdetect.py b/electrumabc/qrreaders/osxqrdetect.py index 7c36cdc322d4..948e0afe07a4 100644 --- a/electrumabc/qrreaders/osxqrdetect.py +++ b/electrumabc/qrreaders/osxqrdetect.py @@ -137,9 +137,9 @@ def read_qr_code( if retval: self.print_error("Got", res.width, res.height, res.str) qrstring = res.str.decode("utf-8") - res.topLeftY = ( - height - res.topLeftY - res.height - ) # flip vertically as y=0 in this coordinate space and in OSX coordinate space are flipped + # flip vertically as y=0 in this coordinate space and in OSX coordinate + # space are flipped + res.topLeftY = height - res.topLeftY - res.height center = ( int(res.topLeftX + res.width / 2), int(res.topLeftY + res.height / 2), diff --git a/electrumabc/slp/slp.py b/electrumabc/slp/slp.py index dd711758db6f..8ce8702e351e 100644 --- a/electrumabc/slp/slp.py +++ b/electrumabc/slp/slp.py @@ -71,11 +71,13 @@ def protocol_match(cls, script_bytes: bytes) -> bool: # fast test passed -- next try the slow test -- attempt to parse and # validate OP_RETURN message try: - slf = cls(script_bytes) # raises on parse error - if slf.message is not None: # should always be not None - cls._script_message_cache.put( - slf.script, slf.message - ) # save parsed message since likely it will be needed again very soon by class c'tor + # raises on parse error + slf = cls(script_bytes) + # should always be not None + if slf.message is not None: + # save parsed message since likely it will be needed again very soon + # by class c'tor + cls._script_message_cache.put(slf.script, slf.message) return True except Error: pass @@ -90,10 +92,8 @@ def protocol_match(cls, script_bytes: bytes) -> bool: # /ScriptOutput - -address.ScriptOutput.protocol_classes.add( - ScriptOutput -) # register class with Electron Cash script 'protocol factory' system +# register class with Electron Cash script 'protocol factory' system +address.ScriptOutput.protocol_classes.add(ScriptOutput) class Message: @@ -902,17 +902,16 @@ def rm_tx(self, txid): for addr, txo_set in self.txo_byaddr.copy().items(): for txo in list(txo_set): if txo.rsplit(":", 1)[0] == txid: - txo_set.discard( - txo - ) # this actually points to the real txo_set instance in the dict + # this actually points to the real txo_set instance in the dict + txo_set.discard(txo) if not txo_set: self.txo_byaddr.pop(addr, None) for tok_id, txo_dict in self.token_quantities.copy().items(): for txo in txo_dict.copy(): if txo.rsplit(":", 1)[0] == txid: - txo_dict.pop( - txo, None - ) # this actually points to the real txo_dict instance in the token_quantities[tok_id] dict + # this actually points to the real txo_dict instance in the + # token_quantities[tok_id] dict + txo_dict.pop(txo, None) if not txo_dict: self.token_quantities.pop(tok_id, None) # this token has no more relevant tx's -- pop it from @@ -925,9 +924,9 @@ def add_tx(self, txid, tx): with locks held.""" outputs = tx.outputs() so = outputs and outputs[0][1] - if not isinstance( - so, ScriptOutput - ): # Note: ScriptOutput here is the subclass defined in this file, not address.ScriptOutput + # Note: ScriptOutput here is the subclass defined in this file, not + # address.ScriptOutput + if not isinstance(so, ScriptOutput): return transaction_type = so.message.transaction_type try: diff --git a/electrumabc/synchronizer.py b/electrumabc/synchronizer.py index bff4e8a5b06c..3f09fd6f3fb2 100644 --- a/electrumabc/synchronizer.py +++ b/electrumabc/synchronizer.py @@ -241,19 +241,19 @@ def _check_change_scripthash(self, sh: str): or sh in self.requested_histories or sh not in self.change_subs_active ): - # this scripthash is either not change or is not subbed or is not yet "stable", discard and abort early + # this scripthash is either not change or is not subbed or is not yet + # "stable", discard and abort early self.change_subs_expiry_candidates.discard(sh) return addr = self.h2addr.get(sh) if not addr: return - hlen = len(self.wallet.get_address_history(addr)) # O(1) lookup into a dict - if ( - hlen == 2 - ): # Only "expire" old change address with precisely 1 input tx and 1 spending tx - bal = self.wallet.get_addr_balance( - addr - ) # Potentially fast lookup since addr_balance gets cached + # O(1) lookup into a dict + hlen = len(self.wallet.get_address_history(addr)) + # Only "expire" old change address with precisely 1 input tx and 1 spending tx + if hlen == 2: + # Potentially fast lookup since addr_balance gets cached + bal = self.wallet.get_addr_balance(addr) else: bal = None if bal is not None and not any(bal): diff --git a/electrumabc/transaction.py b/electrumabc/transaction.py index 08d688e52110..ff3f252638f9 100644 --- a/electrumabc/transaction.py +++ b/electrumabc/transaction.py @@ -1513,12 +1513,11 @@ class ErrorResp(Exception): # crucial on error/timeout/failure. for func in callback_funcs_to_cancel: wallet.network.cancel_requests(func) - if ( - len(inps) == len(self._inputs) and eph.get("_fetch") == t - ): # sanity check - eph.pop( - "_fetch", None - ) # potential race condition here, popping wrong t -- but in practice w/ CPython threading it won't matter + # sanity check + if len(inps) == len(self._inputs) and eph.get("_fetch") == t: + # potential race condition here, popping wrong t -- but in practice w/ + # CPython threading it won't matter + eph.pop("_fetch", None) print_error(f"fetch_input_data: elapsed {(time.time()-t0):.4f} sec") if done_callback: done_callback(*done_args) diff --git a/electrumabc/util.py b/electrumabc/util.py index 4263d02ae0a3..ae077f5bf514 100644 --- a/electrumabc/util.py +++ b/electrumabc/util.py @@ -175,15 +175,14 @@ def __init__(self): self.running = False self.running_lock = threading.Lock() self.job_lock = threading.Lock() - self.jobs = ( - [] - ) # could use a set here but order is important, so we enforce uniqueness in this list in the add/remove methods - self._jobs2add = ( - list() - ) # adding jobs needs to preserve order, so we use a list. - self._jobs2rm = ( - set() - ) # removing jobs does not need to preserve orer so we can benefit from the uniqueness property of using a set. + # could use a set here but order is important, so we enforce uniqueness in this + # list in the add/remove methods + self.jobs = [] + # adding jobs needs to preserve order, so we use a list. + self._jobs2add = list() + # removing jobs does not need to preserve orer so we can benefit from the + # uniqueness property of using a set. + self._jobs2rm = set() def add_jobs(self, jobs): if threading.current_thread() is not self: diff --git a/electrumabc/utils/event.py b/electrumabc/utils/event.py index 54b3eb3f6411..1bb6da59f120 100644 --- a/electrumabc/utils/event.py +++ b/electrumabc/utils/event.py @@ -36,11 +36,8 @@ class Event(list): """ def __call__(self, *args, **kwargs): - for ( - method - ) in ( - self.copy() - ): # prevent mutation while invoking, in case callbacks themselves add to this list + # prevent mutation while invoking, in case callbacks themselves add to this list + for method in self.copy(): if isinstance(method, weakref.WeakMethod): strong_method = method() if not strong_method: @@ -48,7 +45,9 @@ def __call__(self, *args, **kwargs): try: self.remove(method) except ValueError: - pass # allow for the possibility some other callback removed it already while we were iterating + # allow for the possibility some other callback removed it + # already while we were iterating + pass continue else: # it's good, proceed with dereferenced strong_method diff --git a/electrumabc/verifier.py b/electrumabc/verifier.py index 9fc9b1ae962a..77f28c737fcf 100644 --- a/electrumabc/verifier.py +++ b/electrumabc/verifier.py @@ -233,9 +233,9 @@ def verify_merkle(self, response): self.wallet.add_verified_tx(tx_hash, (tx_height, header.get("timestamp"), pos)) if self.is_up_to_date() and self.wallet.is_up_to_date() and not self.qbusy: self.wallet.save_verified_tx(write=True) - self.network.trigger_callback( - "wallet_updated", self.wallet - ) # This callback will happen very rarely.. mostly right as the last tx is verified. It's to ensure GUI is updated fully. + # This callback will happen very rarely.. mostly right as the last tx is + # verified. It's to ensure GUI is updated fully. + self.network.trigger_callback("wallet_updated", self.wallet) @classmethod def hash_merkle_root(cls, merkle_s, target_hash, pos): diff --git a/electrumabc/wallet.py b/electrumabc/wallet.py index 8f64772393ba..c9b904d02cff 100644 --- a/electrumabc/wallet.py +++ b/electrumabc/wallet.py @@ -962,9 +962,8 @@ def get_addr_balance(self, address, exclude_frozen_coins=False): freezing, not address-level.""" assert isinstance(address, Address) mempoolHeight = self.get_local_height() + 1 - if ( - not exclude_frozen_coins - ): # we do not use the cache when excluding frozen coins as frozen status is a dynamic quantity that can change at any time in the UI + # we do not use the cache when excluding frozen coins as frozen status is a dynamic quantity that can change at any time in the UI + if not exclude_frozen_coins: cached = self._addr_bal_cache.get(address) if cached is not None: return cached @@ -1165,9 +1164,9 @@ def mkser(prevout_hash, prevout_n): return f"{prevout_hash}:{prevout_n}" def rm(ser, pruned_too=True, *, tup=None): - h, n = tup or deser( - ser - ) # tup arg is for performance when caller already knows the info (avoid a redundant .split on ':') + # tup arg is for performance when caller already knows the info + # (avoid a redundant .split on ':') + h, n = tup or deser(ser) s = txid_n[h] s.discard(n) if not s: @@ -1538,9 +1537,9 @@ def _update_request_statuses_touched_by_tx(self, tx_hash): and self.network.callback_listener_count("payment_received") > 0 ): for _a, addr, _b in tx.outputs(): - status = self.get_request_status( - addr - ) # returns PR_UNKNOWN quickly if addr has no requests, otherwise returns tuple + # returns PR_UNKNOWN quickly if addr has no requests, otherwise + # returns tuple + status = self.get_request_status(addr) if status != PR_UNKNOWN: status = status[0] # unpack status from tuple self.network.trigger_callback( @@ -1855,9 +1854,9 @@ def fmt_amt(v, is_diff): item["fiat_fee"] = fx.historical_value_str(fee, date) out.append(item) if progress_callback: - progress_callback( - 1.0 - ) # indicate done, just in case client code expects a 1.0 in order to detect completion + # indicate done, just in case client code expects a 1.0 in order to detect + # completion + progress_callback(1.0) return out def get_label(self, tx_hash): @@ -1870,9 +1869,9 @@ def get_default_label(self, tx_hash): if not self.txi.get(tx_hash): d = self.txo.get(tx_hash, {}) labels = [] - for addr in list( - d.keys() - ): # use a copy to avoid possibility of dict changing during iteration, see #1328 + # use a copy to avoid possibility of dict changing during iteration, + # see #1328 + for addr in list(d.keys()): label = self.labels.get(addr.to_storage_string()) if label: labels.append(label) @@ -3131,9 +3130,9 @@ def delete_address(self, address): self.verified_tx.pop(tx_hash, None) self.unverified_tx.pop(tx_hash, None) self.transactions.pop(tx_hash, None) - self._addr_bal_cache.pop( - address, None - ) # not strictly necessary, above calls also have this side-effect. but here to be safe. :) + # not strictly necessary, above calls also have this side-effect. + # but here to be safe. :) + self._addr_bal_cache.pop(address, None) if self.verifier: # TX is now gone. Toss its SPV proof in case we have it # in memory. This allows user to re-add PK again and it diff --git a/electrumabc_gui/qt/__init__.py b/electrumabc_gui/qt/__init__.py index 7bfc6a4c5e72..508f77d165b7 100644 --- a/electrumabc_gui/qt/__init__.py +++ b/electrumabc_gui/qt/__init__.py @@ -186,21 +186,15 @@ def init_qapplication(config): class ElectrumGui(QtCore.QObject, PrintError): new_window_signal = QtCore.pyqtSignal(str, object) update_available_signal = QtCore.pyqtSignal(bool) - addr_fmt_changed = ( - QtCore.pyqtSignal() - ) # app-wide signal for when cashaddr format is toggled. This used to live in each ElectrumWindow instance but it was recently refactored to here. - cashaddr_status_button_hidden_signal = QtCore.pyqtSignal( - bool - ) # app-wide signal for when cashaddr toggle button is hidden from the status bar - shutdown_signal = ( - QtCore.pyqtSignal() - ) # signal for requesting an app-wide full shutdown + addr_fmt_changed = QtCore.pyqtSignal() + cashaddr_status_button_hidden_signal = QtCore.pyqtSignal(bool) + shutdown_signal = QtCore.pyqtSignal() do_in_main_thread_signal = QtCore.pyqtSignal(object, object, object) instance = None def __init__(self, config: SimpleConfig, daemon: Daemon, plugins: Plugins): - super(__class__, self).__init__() # QtCore.QObject init + super(__class__, self).__init__() assert ( __class__.instance is None ), "ElectrumGui is a singleton, yet an instance appears to already exist! FIXME!" @@ -226,8 +220,10 @@ def __init__(self, config: SimpleConfig, daemon: Daemon, plugins: Plugins): self.app = QtWidgets.QApplication.instance() - self._load_fonts() # this needs to be done very early, before the font engine loads fonts.. out of paranoia - self._exit_if_required_pyqt_is_missing() # This may immediately exit the app if missing required PyQt5 modules, so it should also be done early. + # this needs to be done very early, before the font engine loads fonts.. + # out of paranoia + self._load_fonts() + self._exit_if_required_pyqt_is_missing() self.new_version_available = None self._set_icon() self.app.installEventFilter(self) @@ -423,9 +419,10 @@ def _cache_password(self, wallet, password): self._expire_cached_password(wallet) if password is None: return - timer = ( - QtCore.QTimer() - ) # NB a top-level parentless QObject will get delete by Python when its Python refct goes to 0, which is what we want here. Future programmers: Do not give this timer a parent! + # NB a top-level parentless QObject will get delete by Python when its Python + # refct goes to 0, which is what we want here. + # Future programmers: Do not give this timer a parent! + timer = QtCore.QTimer() self._wallet_password_cache[wallet] = (password, timer) weakWallet = Weak.ref(wallet) weakSelf = Weak.ref(self) @@ -496,13 +493,16 @@ def _load_fonts(self): if ( sys.platform == "linux" - and self.linux_qt_use_custom_fontconfig # method-backed property, checks config settings + # method-backed property, checks config settings + and self.linux_qt_use_custom_fontconfig and not os.environ.get("FONTCONFIG_FILE") and os.path.exists("/etc/fonts/fonts.conf") and os.path.exists(linux_font_config_file) and os.path.exists(emojis_ttf_path) + # doing this on Qt < 5.12 causes harm and makes the whole app render fonts + # badly and self.qt_version() >= (5, 12) - ): # doing this on Qt < 5.12 causes harm and makes the whole app render fonts badly + ): # On Linux, we override some fontconfig rules by loading our own # font config XML file. This makes it so that our custom emojis and # other needed glyphs are guaranteed to get picked up first, @@ -568,7 +568,7 @@ def build_tray_menu(self): # convince yourself of this. Doing it this way actually cleans-up # the menus and they do not leak. m_old.clear() - m_old.deleteLater() # C++ object and its children will be deleted later when we return to the event loop + m_old.deleteLater() m = QtWidgets.QMenu() m.setObjectName("SysTray.QMenu") self.tray.setContextMenu(m) @@ -655,9 +655,9 @@ def on_focus_change(self, ignored, new_focus_widget): if not new_focus_widget: return if isinstance(new_focus_widget, QtWidgets.QWidget): - window = QtWidgets.QWidget.window( - new_focus_widget - ) # call base class because some widgets may actually override 'window' with Python attributes. + # call base class because some widgets may actually override 'window' with + # Python attributes. + window = QtWidgets.QWidget.window(new_focus_widget) if isinstance(window, ElectrumWindow): self._last_active_window = Weak.ref(window) @@ -794,15 +794,15 @@ def close_window(self, window): # open. It was bizarre behavior to keep the app open when # things like a transaction dialog or the network dialog were still # up. - self._quit_after_last_window() # central point that checks if we should quit. - - # window.deleteLater() # <--- This has the potential to cause bugs (esp. with misbehaving plugins), so commented-out. The object gets deleted anyway when Python GC kicks in. Forcing a delete may risk python to have a dangling reference to a deleted C++ object. + # central point that checks if we should quit. + self._quit_after_last_window() def gc_schedule(self): """Schedule garbage collection to happen in the near future. Note that rapid-fire calls to this re-start the timer each time, thus only the last call takes effect (it's rate-limited).""" - self.gc_timer.start() # start/re-start the timer to fire exactly once in timeInterval() msecs + # start/re-start the timer to fire exactly once in timeInterval() msecs + self.gc_timer.start() @staticmethod def gc(): diff --git a/electrumabc_gui/qt/address_dialog.py b/electrumabc_gui/qt/address_dialog.py index 71d92913e134..271d8e8b3814 100644 --- a/electrumabc_gui/qt/address_dialog.py +++ b/electrumabc_gui/qt/address_dialog.py @@ -158,7 +158,7 @@ def exec_(self): self.disconnect_signals() import gc - QTimer.singleShot( - 10, lambda: gc.collect() - ) # run GC in 10 ms. Otherwise this window sticks around in memory for way too long + # run GC in 10 ms. Otherwise this window sticks around in memory for way too + # long + QTimer.singleShot(10, lambda: gc.collect()) return retval diff --git a/electrumabc_gui/qt/bip38_importer.py b/electrumabc_gui/qt/bip38_importer.py index 702e40b5982f..a636f3689b8a 100644 --- a/electrumabc_gui/qt/bip38_importer.py +++ b/electrumabc_gui/qt/bip38_importer.py @@ -31,9 +31,9 @@ class Bip38Importer(WindowModalDialog, PrintError): Requires bitcoin.is_bip38_available() == True otherwise will raise RuntimeError on instantiation.""" - decrypted_sig = pyqtSignal( - object, object - ) # Decrypt thread emits this with _decrypt_thread.self, (decrypted_wif, Address) or _decrypt_thread.self, () on failure due to bad password + # Decrypt thread emits this with _decrypt_thread.self, (decrypted_wif, Address) + # or _decrypt_thread.self, () on failure due to bad password + decrypted_sig = pyqtSignal(object, object) def __init__( self, @@ -41,11 +41,16 @@ def __init__( *, parent=None, title=None, - message=None, # The message to display as a label up top - show_count=True, # If false, don't show 'Key 1/n:' in UI instead just say: 'Key: ' - on_success=None, # Callback will be called with a dict of bip38key -> (decoded_wif_str, Address) objects + # The message to display as a label up top + message=None, + # If false, don't show 'Key 1/n:' in UI instead just say: 'Key: ' + show_count=True, + # Callback will be called with a dict of + # bip38key -> (decoded_wif_str, Address) objects + on_success=None, + # Callback will be called if user hits cancel on_cancel=None, - ): # Callback will be called if user hits cancel + ): """bip38_keys should be a list of '6P' strings, representing bip38 keys. The user will be prompted for each key to enter a password and will be shown the decoded address and WIF key. Note that this @@ -307,18 +312,20 @@ class _decrypt_thread(threading.Thread, PrintError): def __init__(self, w, key, pw): super().__init__(daemon=True, target=self.decrypt) - self.w = util.Weak.ref( - w - ) # We keep a weak ref to parent because parent may die while we are still running. In which case we don't want to call into parent when it's already closed/done executing + # We keep a weak ref to parent because parent may die while we are still + # running. In which case we don't want to call into parent when it's already + # closed/done executing + self.w = util.Weak.ref(w) self.key = key self.pw = pw self.start() def decrypt(self): - result = bitcoin.bip38_decrypt( - self.key, self.pw - ) # Potentially slow-ish operation. Note: result may be None or empty; client code's slot checks for that condition, so no need to check result here. - parent = self.w() # grab strong ref from weak ref if weak ref still alive + # Potentially slow-ish operation. Note: result may be None or empty; client + # code's slot checks for that condition, so no need to check result here. + result = bitcoin.bip38_decrypt(self.key, self.pw) + # grab strong ref from weak ref if weak ref still alive + parent = self.w() if parent: parent.decrypted_sig.emit(self, result) else: diff --git a/electrumabc_gui/qt/contact_list.py b/electrumabc_gui/qt/contact_list.py index 48de4a92b492..4d4ae7a063c1 100644 --- a/electrumabc_gui/qt/contact_list.py +++ b/electrumabc_gui/qt/contact_list.py @@ -238,9 +238,9 @@ def create_menu(self, position): lambda: self.main_window.sign_verify_message(signAddr), ) if signAddr.kind != Address.ADDR_P2PKH: - a.setDisabled( - True - ) # We only allow this for P2PKH since it makes no sense for P2SH (ambiguous public key) + # We only allow this for P2PKH since it makes no sense for P2SH + # (ambiguous public key) + a.setDisabled(True) URLs = [ web.BE_URL( self.config, @@ -308,10 +308,9 @@ def on_update(self): selected_contacts = set( item.data(0, self.DataRoles.Contact) for item in selected ) - del ( - item, - selected, - ) # must not hold a reference to a C++ object that will soon be deleted in self.clear().. + # must not hold a reference to a C++ object that will soon be deleted in + # self.clear().. + del item, selected self.clear() type_names = defaultdict(lambda: _("Unknown")) type_names.update( diff --git a/electrumabc_gui/qt/external_plugins_window.py b/electrumabc_gui/qt/external_plugins_window.py index 52c96a0bc75d..c5c5d231a553 100644 --- a/electrumabc_gui/qt/external_plugins_window.py +++ b/electrumabc_gui/qt/external_plugins_window.py @@ -588,11 +588,12 @@ def refresh_ui(self): header = self.horizontalHeader() header.setStretchLastSection(False) for col in range(header.count()): + # description field is the stretch column, others are resized to contents sm = ( QtWidgets.QHeaderView.Stretch if col == 1 else QtWidgets.QHeaderView.ResizeToContents - ) # description field is the stretch column, others are resized to contents + ) header.setSectionResizeMode(col, sm) del header diff --git a/electrumabc_gui/qt/history_list.py b/electrumabc_gui/qt/history_list.py index 128ff4d240eb..a3955dfa6511 100644 --- a/electrumabc_gui/qt/history_list.py +++ b/electrumabc_gui/qt/history_list.py @@ -108,9 +108,7 @@ def get_domain(self): """Replaced in address_dialog.py""" return self.wallet.get_addresses() - @rate_limited( - 1.0, classlevel=True, ts_after=True - ) # We rate limit the history list refresh no more than once every second, app-wide + @rate_limited(1.0, classlevel=True, ts_after=True) def update(self): if self.cleaned_up: # short-cut return if window was closed and wallet is stopped diff --git a/electrumabc_gui/qt/main_window.py b/electrumabc_gui/qt/main_window.py index 7e5181bfda10..29056ef4dd7f 100644 --- a/electrumabc_gui/qt/main_window.py +++ b/electrumabc_gui/qt/main_window.py @@ -219,9 +219,9 @@ def __init__(self, gui_object: ElectrumGui, wallet: Abstract_Wallet): self.gui_thread = gui_object.gui_thread self.wallet = wallet assert not self.wallet.weak_window - self.wallet.weak_window = Weak.ref( - self - ) # This enables plugins such as CashFusion to keep just a reference to the wallet, but eventually be able to find the window it belongs to. + # This enables plugins such as CashFusion to keep just a reference to the + # wallet, but eventually be able to find the window it belongs to. + self.wallet.weak_window = Weak.ref(self) self.config = config = gui_object.config assert self.wallet and self.config and self.gui_object @@ -242,25 +242,20 @@ def __init__(self, gui_object: ElectrumGui, wallet: Abstract_Wallet): self.externalpluginsdialog = None self.hardwarewalletdialog = None self.require_fee_update = False - self.addr_fmt_changed = ( - self.gui_object.addr_fmt_changed - ) # alias for backwards compatibility for plugins -- this signal used to live in each window and has since been refactored to gui-object where it belongs (since it's really an app-global setting) + # alias for backwards compatibility for plugins -- this signal used to live in + # each window and has since been refactored to gui-object where it belongs + # (since it's really an app-global setting) + self.addr_fmt_changed = self.gui_object.addr_fmt_changed self.tl_windows = [] self.tx_external_keypairs = {} self._tx_dialogs = Weak.Set() - self.tx_update_mgr = TxUpdateMgr( - self - ) # manages network callbacks for 'new_transaction' and 'verified2', and collates GUI updates from said callbacks as a performance optimization - self.is_schnorr_enabled = ( - self.wallet.is_schnorr_enabled - ) # This is a function -- Support for plugins that may be using the 4.0.3 & 4.0.4 API -- this function used to live in this class, before being moved to Abstract_Wallet. - self.send_tab_opreturn_widgets, self.receive_tab_opreturn_widgets = ( - [], - [], - ) # defaults to empty list - self._shortcuts = ( - Weak.Set() - ) # keep track of shortcuts and disable them on close + # manages network callbacks for 'new_transaction' and 'verified2', and collates + # GUI updates from said callbacks as a performance optimization + self.tx_update_mgr = TxUpdateMgr(self) + # defaults to empty list + self.send_tab_opreturn_widgets, self.receive_tab_opreturn_widgets = ([], []) + # keep track of shortcuts and disable them on close + self._shortcuts = Weak.Set() self.status_bar = self.create_status_bar() @@ -913,7 +908,7 @@ def add_toggle_action(view_menu, tab): prefs_tit = _("Preferences") + "..." a = tools_menu.addAction( prefs_tit, self.settings_dialog, QKeySequence("Ctrl+,") - ) # Note: on macOS this hotkey sequence won't be shown in the menu (since it's reserved by the system), but will still work. :/ + ) if sys.platform == "darwin": # This turns off the heuristic matching based on name and keeps the # "Preferences" action out of the application menu and into the @@ -1355,9 +1350,7 @@ def _update_wallet(self): ): self.update_tabs() - @rate_limited( - 1.0, classlevel=True, ts_after=True - ) # Limit tab updates to no more than 1 per second, app-wide. Multiple calls across instances will be collated into 1 deferred series of calls (1 call per extant instance) + @rate_limited(1.0, classlevel=True, ts_after=True) def update_tabs(self): if self.cleaned_up: return @@ -1741,9 +1734,7 @@ def new_payment_request(self): self.set_receive_address(addr) self.expires_label.hide() self.expires_combo.show() - self.request_list.setCurrentItem( - None - ) # We want the current item to always reflect what's in the UI. So if new, clear selection. + self.request_list.setCurrentItem(None) self.receive_message_e.setFocus(1) def set_receive_address(self, addr: Address): @@ -1760,9 +1751,7 @@ def update_receive_address_widget(self): text = self.receive_address.to_ui_string() self.receive_address_e.setText(text) - @rate_limited( - 0.250, ts_after=True - ) # this function potentially re-computes the QR widget, so it's rate limited to once every 250ms + @rate_limited(0.250, ts_after=True) def check_and_reset_receive_address_if_needed(self): """Check to make sure the receive tab is kosher and doesn't contain an already-used address. This should be called from the showEvent @@ -2709,13 +2698,12 @@ def broadcast_thread(): # and we proceed anyway with the broadcast status, msg = self.network.broadcast_transaction(tx) - # figure out what to return... - msg = ( - ack_msg or msg - ) # prefer the merchant's ack_msg over the broadcast msg, but fallback to broadcast msg if no ack_msg. - status = bool( - ack_status or status - ) # if both broadcast and merchant ACK failed -- it's a failure. if either succeeded -- it's a success + # prefer the merchant's ack_msg over the broadcast msg, but fallback + # to broadcast msg if no ack_msg. + msg = ack_msg or msg + # if both broadcast and merchant ACK failed -- it's a failure. if + # either succeeded -- it's a success + status = bool(ack_status or status) if status: self.invoices.set_paid(pr, tx.txid()) @@ -3157,9 +3145,7 @@ def get_coins(self, isInvoice=False): def spend_coins(self, coins): self.set_pay_from(coins) self.show_send_tab() - run_hook( - "on_spend_coins", self, coins - ) # CashShuffle: will set the mode of send tab to coins[0]'s shuffled/unshuffled state + run_hook("on_spend_coins", self, coins) self.update_fee() def paytomany(self): @@ -3938,9 +3924,10 @@ def do_process_from_txid(self, *, txid=None, parent=None): if not ok: parent.show_message(_("Error retrieving transaction") + ":\n" + r) return - tx = Transaction( - r, sign_schnorr=self.wallet.is_schnorr_enabled() - ) # note that presumably the tx is already signed if it comes from blockchain so this sign_schnorr parameter is superfluous, but here to satisfy my OCD -Calin + # note that presumably the tx is already signed if it comes from blockchain + # so this sign_schnorr parameter is superfluous, but here to satisfy + # my OCD -Calin + tx = Transaction(r, sign_schnorr=self.wallet.is_schnorr_enabled()) self.show_transaction(tx) def do_create_invoice(self): @@ -5074,18 +5061,19 @@ def on_video_device(x): if qr_combo.isEnabled(): self.config.set_key("video_device", qr_combo.itemData(x), True) - set_no_camera() # pre-populate combo box with default so it has a sizeHint + # pre-populate combo box with default so it has a sizeHint + set_no_camera() - d.shown_signal.connect( - scan_cameras, Qt.QueuedConnection - ) # do the camera scan once dialog is shown, using QueuedConnection so it's called from top level event loop and not from the showEvent handler + # do the camera scan once dialog is shown, using QueuedConnection so it's + # called from top level event loop and not from the showEvent handler + d.shown_signal.connect(scan_cameras, Qt.QueuedConnection) qr_combo.currentIndexChanged.connect(on_video_device) gui_widgets.append((qr_label, qr_combo)) colortheme_combo = QtWidgets.QComboBox() - colortheme_combo.addItem( - _("Default"), "default" - ) # We can't name this "light" in the UI as sometimes the default is actually dark-looking eg on Mojave or on some Linux desktops. + # We can't name this "light" in the UI as sometimes the default is actually + # dark-looking eg on Mojave or on some Linux desktops. + colortheme_combo.addItem(_("Default"), "default") colortheme_combo.addItem(_("Dark"), "dark") theme_name = self.config.get("qt_gui_color_theme", "default") dark_theme_available = self.gui_object.is_dark_theme_available() @@ -5486,18 +5474,16 @@ def update_exchanges(): conf_exchange = self.fx.config_exchange() ex_combo.clear() ex_combo.addItems(sorted(exchanges)) - idx = ex_combo.findText( - conf_exchange - ) # try and restore previous exchange if in new list + # try and restore previous exchange if in new list + idx = ex_combo.findText(conf_exchange) if idx < 0: # hmm, previous exchange wasn't in new h= setting. Try default exchange. idx = ex_combo.findText(self.fx.default_exchange) - idx = ( - 0 if idx < 0 else idx - ) # if still no success (idx < 0) -> default to the first exchange in combo - if ( - exchanges - ): # don't set index if no exchanges, as any index is illegal. this shouldn't happen. + # if still no success (idx < 0) -> default to the first exchange in combo + idx = 0 if idx < 0 else idx + # don't set index if no exchanges, as any index is illegal. + # this shouldn't happen. + if exchanges: ex_combo.setCurrentIndex( idx ) # note this will emit a currentIndexChanged signal if it's changed @@ -5668,9 +5654,8 @@ def disconnect_signals(): sig.disconnect() except TypeError: pass # no connections - elif attr_name.endswith( - "__RateLimiter" - ): # <--- NB: this needs to match the attribute name in util.py rate_limited decorator + # NB: this needs to match the attribute name in util.py rate_limited decorator + elif attr_name.endswith("__RateLimiter"): rl_obj = getattr(self, attr_name) if isinstance(rl_obj, RateLimiter): rl_obj.kill_timer() @@ -5762,11 +5747,11 @@ def clean_up(self): if self.cleaned_up: return self.cleaned_up = True - if ( - self.wallet.thread - ): # guard against window close before load_wallet was called (#1554) + # guard against window close before load_wallet was called (#1554) + if self.wallet.thread: self.wallet.thread.stop() - self.wallet.thread.wait() # Join the thread to make sure it's really dead. + # Join the thread to make sure it's really dead. + self.wallet.thread.wait() for w in [ self.address_list, @@ -5776,7 +5761,9 @@ def clean_up(self): self.tx_update_mgr, ]: if w: - w.clean_up() # tell relevant object to clean itself up, unregister callbacks, disconnect signals, etc + # tell relevant object to clean itself up, unregister callbacks, + # disconnect signals, etc + w.clean_up() with contextlib.suppress(TypeError): self.gui_object.addr_fmt_changed.disconnect(self.utxo_list.update) @@ -6146,12 +6133,13 @@ def __init__(self, main_window_parent): self.need_process_v, self.need_process_n = False, False # /end thread-shared attributes self.weakParent = Weak.ref(main_window_parent) + # immediately clear verif_q on history update because it would be redundant + # to keep the verify queue around after a history list update main_window_parent.history_updated_signal.connect( self.verifs_get_and_clear, Qt.DirectConnection - ) # immediately clear verif_q on history update because it would be redundant to keep the verify queue around after a history list update - main_window_parent.on_timer_signal.connect( - self.do_check, Qt.DirectConnection - ) # hook into main_window's timer_actions function + ) + # hook into main_window's timer_actions function + main_window_parent.on_timer_signal.connect(self.do_check, Qt.DirectConnection) self.full_hist_refresh_timer = QTimer(self) self.full_hist_refresh_timer.setInterval(1000) self.full_hist_refresh_timer.setSingleShot(False) diff --git a/electrumabc_gui/qt/network_dialog.py b/electrumabc_gui/qt/network_dialog.py index 5c49a73363c8..e6e8b507162e 100644 --- a/electrumabc_gui/qt/network_dialog.py +++ b/electrumabc_gui/qt/network_dialog.py @@ -103,9 +103,7 @@ def on_network(self, event, *args): # print_error("[NetworkDialog] on_network:",event,*args) self.network_updated_signal.emit() # this enqueues call to on_update in GUI thread - @rate_limited( - 0.333 - ) # limit network window updates to max 3 per second. More frequent isn't that useful anyway -- and on large wallets/big synchs the network spams us with events which we would rather collapse into 1 + @rate_limited(0.333) def on_update(self): """This always runs in main GUI thread""" self.nlayout.update() @@ -1217,9 +1215,12 @@ def set_proxy(self): def suggest_proxy(self, found_proxy): if not found_proxy: self.tor_cb.setEnabled(False) - self._set_tor_use( - False - ) # It's not clear to me that if the tor service goes away and comes back later, and in the meantime they unchecked proxy_cb, that this should remain checked. I can see it being confusing for that to be the case. Better to uncheck. It gets auto-re-checked anyway if it comes back and it's the same due to code below. -Calin + # It's not clear to me that if the tor service goes away and comes back + # later, and in the meantime they unchecked proxy_cb, that this should + # remain checked. I can see it being confusing for that to be the case. + # Better to uncheck. It gets auto-re-checked anyway if it comes back and + # it's the same due to code below. -Calin + self._set_tor_use(False) return self.tor_proxy = found_proxy self.tor_cb.setText( @@ -1289,7 +1290,9 @@ def remove_pinned_certificate(self, server): def set_blacklisted(self, server, bl): self.network.server_set_blacklisted(server, bl, True) - self.set_server() # if the blacklisted server is the active server, this will force a reconnect to another server + # if the blacklisted server is the active server, this will force a reconnect + # to another server + self.set_server() self.update() def set_whitelisted(self, server, flag): @@ -1299,7 +1302,9 @@ def set_whitelisted(self, server, flag): def set_whitelisted_only(self, b): self.network.set_whitelist_only(b) - self.set_server() # forces us to send a set-server to network.py which recomputes eligible servers, etc + # forces us to send a set-server to network.py which recomputes eligible + # servers, etc + self.set_server() self.update() def on_view_blacklist(self, ignored): @@ -1366,9 +1371,9 @@ def on_tor_port_changed(self, controller: TorController): self.stopQ.put("kick") def start(self): - self.stopQ = ( - queue.Queue() - ) # create a new stopQ blowing away the old one just in case it has old data in it (this prevents races with stop/start arriving too quickly for the thread) + # create a new stopQ blowing away the old one just in case it has old data in + # it (this prevents races with stop/start arriving too quickly for the thread) + self.stopQ = queue.Queue() super().start() def stop(self): diff --git a/electrumabc_gui/qt/popup_widget.py b/electrumabc_gui/qt/popup_widget.py index 4ecd69ea2549..b1518111884e 100644 --- a/electrumabc_gui/qt/popup_widget.py +++ b/electrumabc_gui/qt/popup_widget.py @@ -95,9 +95,7 @@ def setPointerPosition(self, r): self.pointerPos = r self.update() - @pyqtProperty( - float - ) # Property so that Qt animations work. You may set the actual attrbute directly and ingore this in client code + @pyqtProperty(float) def popupOpacity(self): return self.popup_opacity @@ -106,9 +104,7 @@ def popupOpacity(self, value): self.popup_opacity = value self.setWindowOpacity(value) - @pyqtProperty( - float - ) # Property so that Qt animations work. You may set the actual attrbute directly and ingore this in client code + @pyqtProperty(float) def finalOpacity(self): return self.final_opacity diff --git a/electrumabc_gui/qt/qrwindow.py b/electrumabc_gui/qt/qrwindow.py index feb22b8f0e77..f67f9948b0e2 100644 --- a/electrumabc_gui/qt/qrwindow.py +++ b/electrumabc_gui/qt/qrwindow.py @@ -37,7 +37,8 @@ class QR_Window(QtWidgets.QWidget, MessageBoxMixin): def __init__(self): - super().__init__() # Top-level window. Parent needs to hold a reference to us and clean us up appropriately. + # Top-level window. + super().__init__() self.setWindowTitle(f"{PROJECT_NAME} - " + _("Payment Request")) self.label = "" self.amount = 0 @@ -83,9 +84,7 @@ def __init__(self): saveBut = QtWidgets.QPushButton(_("Save QR Image")) vbox.addLayout(Buttons(copyBut, saveBut)) - weakSelf = Weak.ref( - self - ) # Qt & Python GC hygeine: don't hold references to self in non-method slots as it appears Qt+Python GC don't like this too much and may leak memory in that case. + weakSelf = Weak.ref(self) weakQ = Weak.ref(self.qrw) weakBut = Weak.ref(copyBut) copyBut.clicked.connect(lambda: copy_to_clipboard(weakQ(), weakBut())) @@ -130,5 +129,7 @@ def closeEvent(self, e): # still up. for c in self.findChildren(QtWidgets.QDialog): if c.isWindow() and c.isModal() and c.isVisible(): - c.reject() # break out of local event loop for dialog as we are about to die and we will be invalidated. + # break out of local event loop for dialog as we are about to die and + # we will be invalidated. + c.reject() super().closeEvent(e) diff --git a/electrumabc_gui/qt/transaction_dialog.py b/electrumabc_gui/qt/transaction_dialog.py index 7afd9c374bbf..f570026aa59a 100644 --- a/electrumabc_gui/qt/transaction_dialog.py +++ b/electrumabc_gui/qt/transaction_dialog.py @@ -70,12 +70,11 @@ def show_transaction(tx, parent, desc=None, prompt_if_unsaved=False): class TxDialog(QtWidgets.QDialog, MessageBoxMixin, PrintError): - throttled_update_sig = ( - pyqtSignal() - ) # connected to self.throttled_update -- emit from thread to do update in main thread - dl_done_sig = ( - pyqtSignal() - ) # connected to an inner function to get a callback in main thread upon dl completion + # connected to self.throttled_update -- emit from thread to do update in main thread + throttled_update_sig = pyqtSignal() + + # connected to an inner function to get a callback in main thread upon dl completion + dl_done_sig = pyqtSignal() BROADCAST_COOLDOWN_SECS: int = 5 diff --git a/electrumabc_gui/qt/util.py b/electrumabc_gui/qt/util.py index 10ddffb5c964..f4b1ba680052 100644 --- a/electrumabc_gui/qt/util.py +++ b/electrumabc_gui/qt/util.py @@ -1400,9 +1400,9 @@ def invoke(cls, rate, ts_after, func, args, kwargs): obj = args[0] objcls = obj.__class__ args = list(args) - args.insert( - 0, objcls - ) # prepend obj class to trick super.invoke() into making this state object be class-level. + # prepend obj class to trick super.invoke() into making this state object be + # class-level. + args.insert(0, objcls) return super(RateLimiterClassLvl, cls).invoke( rate, ts_after, func, args, kwargs ) @@ -1527,9 +1527,9 @@ def webopen(url: str): if os.fork() == 0: del os.environ["LD_LIBRARY_PATH"] webbrowser.open(url) - os._exit( - 0 - ) # Python docs advise doing this after forking to prevent atexit handlers from executing. + # Python docs advise doing this after forking to prevent atexit handlers + # from executing. + os._exit(0) else: webbrowser.open(url) diff --git a/electrumabc_plugins/fusion/pedersen.py b/electrumabc_plugins/fusion/pedersen.py index 6544bad69a9d..9ff61f0500c7 100644 --- a/electrumabc_plugins/fusion/pedersen.py +++ b/electrumabc_plugins/fusion/pedersen.py @@ -266,9 +266,9 @@ def _calc_initial_fast(self): result_buf = create_string_buffer(64) # calculate (a - k) * H - a_k_bytes = int(a_k).to_bytes( - 32, "big" - ) # NB: a_k may be gmpy2.mpz here because sometimes it just is due to ecdsa changes. + # NB: a_k may be gmpy2.mpz here because sometimes it just is due to + # ecdsa changes. + a_k_bytes = int(a_k).to_bytes(32, "big") akH_buf = create_string_buffer(64) akH_buf.raw = self.setup._seclib_H # copy res = seclib.secp256k1_ec_pubkey_tweak_mul(ctx, akH_buf, a_k_bytes) diff --git a/electrumabc_plugins/fusion/qt.py b/electrumabc_plugins/fusion/qt.py index d64f16f28ab4..b490f8e44976 100644 --- a/electrumabc_plugins/fusion/qt.py +++ b/electrumabc_plugins/fusion/qt.py @@ -794,7 +794,9 @@ def action_callback(): else: tip = _("Fusion transactions are now shown") QtWidgets.QToolTip.showText(QCursor.pos(), tip, history_list) - history_list.update() # unconditionally update this history list as it may be embedded in the address_detail window and not a global history list.. + # unconditionally update this history list as it may be embedded in the + # address_detail window and not a global history list.. + history_list.update() for w in self.gui.windows: # Need to update all the other open windows. # Note: We still miss any other open windows' address-detail @@ -802,9 +804,8 @@ def action_callback(): # time it won't be noticed by people and actually # finding all those windows would just make this code # less maintainable. - if ( - history_list is not w.history_list - ): # check if not already updated above + # check if not already updated above + if history_list is not w.history_list: w.history_list.update() action = menu.addAction(_("Hide CashFusions"), action_callback) @@ -1026,14 +1027,13 @@ def toggle_autofuse(self): "To perform auto-fusion in the background, please enter your password." ), ) - self.plugin.widgets.add( - pd - ) # just in case this plugin is unloaded while this dialog is up + # just in case this plugin is unloaded while this dialog is up + self.plugin.widgets.add(pd) password = pd.run() del pd - if ( - password is None or not plugin.active - ): # must check plugin.active because user can theoretically kill plugin from another window while the above password dialog is up + # must check plugin.active because user can theoretically kill plugin + # from another window while the above password dialog is up + if password is None or not plugin.active: return try: plugin.enable_autofusing(self.wallet, password) @@ -1063,9 +1063,9 @@ def show_wallet_settings(self): self.plugin, self.wallet, ) - self.plugin.widgets.add( - win - ) # ensures if plugin is unloaded while dialog is up, that the dialog will be killed. + # ensures if plugin is unloaded while dialog is up, that the dialog will + # be killed. + self.plugin.widgets.add(win) win.show() win.raise_() @@ -1075,9 +1075,8 @@ def update_server_error(self): if not changed: return self.server_error = tup - name = "CashFusionError;" + str( - id(self) - ) # make sure name is unique per FusionButton widget + # make sure name is unique per FusionButton widget + name = "CashFusionError;" + str(id(self)) if self.server_error: weak_plugin = weakref.ref(self.plugin) @@ -1913,9 +1912,9 @@ def __init__(self, plugin, parent=None): for i, t in enumerate(Params.tiers): button = QtWidgets.QPushButton(_("Start")) button.setDefault(False) - button.setAutoDefault( - False - ) # on some platforms if we don't do this, one of the buttons traps "Enter" key + # on some platforms if we don't do this, one of the buttons traps "Enter" + # key + button.setAutoDefault(False) button.clicked.connect(partial(self.clicked_start_fuse, t)) self.t_server_waiting.setCellWidget(i, 2, button) slayout.addWidget(self.t_server_waiting) diff --git a/electrumabc_plugins/fusion/server.py b/electrumabc_plugins/fusion/server.py index 446d123697c0..e2478aeb894c 100644 --- a/electrumabc_plugins/fusion/server.py +++ b/electrumabc_plugins/fusion/server.py @@ -477,9 +477,9 @@ def new_client_job(self, client): client.error(f"Invalid tier selected: {t}") try: mytiers = list(mytierpools) - rng.shuffle( - mytiers - ) # shuffle the adding order so that if filling more than one pool, we don't have bias towards any particular tier + # shuffle the adding order so that if filling more than one pool, we don't + # have bias towards any particular tier + rng.shuffle(mytiers) with self.lock: if self.stopping: return diff --git a/electrumabc_plugins/hw_wallet/plugin.py b/electrumabc_plugins/hw_wallet/plugin.py index eb72d75a2dbe..dc030c562bd9 100644 --- a/electrumabc_plugins/hw_wallet/plugin.py +++ b/electrumabc_plugins/hw_wallet/plugin.py @@ -261,11 +261,16 @@ def is_any_tx_output_on_change_branch(tx: Transaction) -> bool: return False +# will return address.script[2:] (everyting after the first OP_RETURN & PUSH bytes) def validate_op_return_output_and_get_data( - output: tuple, # tuple(typ, 'address', amount) - max_size: int = 220, # in bytes - max_pushes: int = 1, # number of pushes supported after the OP_RETURN, most HW wallets support only 1 push, some more than 1. Specify None to omit the number-of-pushes check. -) -> bytes: # will return address.script[2:] (everyting after the first OP_RETURN & PUSH bytes) + # tuple(typ, 'address', amount) + output: tuple, + # in bytes + max_size: int = 220, + # number of pushes supported after the OP_RETURN, most HW wallets support only 1 + # push, some more than 1. Specify None to omit the number-of-pushes check. + max_pushes: int = 1, +) -> bytes: _type, address, _amount = output if max_pushes is None: diff --git a/electrumabc_plugins/labels/labels.py b/electrumabc_plugins/labels/labels.py index 350e1fc5d690..9dd104ec06d3 100644 --- a/electrumabc_plugins/labels/labels.py +++ b/electrumabc_plugins/labels/labels.py @@ -49,7 +49,8 @@ def set_label(self, wallet, item, label): return if not item: return - with wallet.lock: # need to hold the lock from get nonce to set nonce in order to prevent races. + # need to hold the lock from get nonce to set nonce in order to prevent races. + with wallet.lock: nonce = self.get_nonce(wallet) wallet_id = self.wallets[wallet][2] bundle = { diff --git a/electrumabc_plugins/labels/qt.py b/electrumabc_plugins/labels/qt.py index 485cc4f334ce..c86dac4e00f9 100644 --- a/electrumabc_plugins/labels/qt.py +++ b/electrumabc_plugins/labels/qt.py @@ -145,18 +145,18 @@ def do_force_upload(self, wallet, dlgRef): # this runs in a NON-GUI thread dlg = dlgRef() if dlg: - dlg.sigs.ok_button_disable_sig.emit( - True - ) # block window closing prematurely which can cause a temporary hang until thread completes + # block window closing prematurely which can cause a temporary hang + # until thread completes + dlg.sigs.ok_button_disable_sig.emit(True) self.push_thread(wallet) def do_force_download(self, wallet, dlgRef): # this runs in a NON-GUI thread dlg = dlgRef() if dlg: - dlg.sigs.ok_button_disable_sig.emit( - True - ) # block window closing prematurely which can cause a temporary hang until thread completes + # block window closing prematurely which can cause a temporary hang + # until thread completes + dlg.sigs.ok_button_disable_sig.emit(True) self.pull_thread(wallet, True) def done_processing(self, dlgRef, result): diff --git a/electrumabc_plugins/trezor/qt.py b/electrumabc_plugins/trezor/qt.py index 5261fa65319d..de777ed8c481 100644 --- a/electrumabc_plugins/trezor/qt.py +++ b/electrumabc_plugins/trezor/qt.py @@ -537,13 +537,15 @@ def read_and_convert_using_qt_to_raw_mono( if (img.width(), img.height()) != ( hs_cols, hs_rows, - ): # do we need to scale it ? + ): + # force to our dest size. Note that IgnoreAspectRatio guarantess + # the right size. Ther other modes don't img = img.scaled( hs_cols, hs_rows, Qt.IgnoreAspectRatio, Qt.SmoothTransformation, - ) # force to our dest size. Note that IgnoreAspectRatio guarantess the right size. Ther other modes don't + ) if img.isNull() or (img.width(), img.height()) != ( hs_cols, hs_rows, @@ -601,13 +603,15 @@ def read_and_convert_using_qt_to_toif( if (img.width(), img.height()) != ( hs_cols, hs_rows, - ): # do we need to scale it ? + ): + # force to our dest size. Note that IgnoreAspectRatio + # guarantess the right size. Ther other modes don't img = img.scaled( hs_cols, hs_rows, Qt.IgnoreAspectRatio, Qt.SmoothTransformation, - ) # force to our dest size. Note that IgnoreAspectRatio guarantess the right size. Ther other modes don't + ) if img.isNull() or (img.width(), img.height()) != ( hs_cols, hs_rows, @@ -619,9 +623,11 @@ def read_and_convert_using_qt_to_toif( ) return target_fmt = QImage.Format_RGB888 + # dither it down to 256 colors to reduce image complexity then back + # up to 24 bit for easy reading img = img.convertToFormat(QImage.Format_Indexed8).convertToFormat( target_fmt - ) # dither it down to 256 colors to reduce image complexity then back up to 24 bit for easy reading + ) if img.isNull(): handler.show_error(_("Could not dither or re-render image")) return