From 612d3493df2e0fc5a84ea7d8cfa00c4faed4d6fb Mon Sep 17 00:00:00 2001 From: SomberNight Date: Sun, 23 Apr 2023 02:00:50 +0000 Subject: [PATCH] fix flake8-bugbear B017 B017 `assertRaises(Exception)` and `pytest.raises(Exception)` should be considered evil. They can lead to your test passing even if the code being tested is never executed due to a typo. Assert for a more specific exception (builtin or custom), or use `assertRaisesRegex` (if using `assertRaises`), or add the `match` keyword argument (if using `pytest.raises`), or use the context manager form with a target. --- electrum/blockchain.py | 14 +++++++------- electrum/tests/test_blockchain.py | 16 ++++++++-------- electrum/tests/test_commands.py | 13 +++++++------ electrum/wallet.py | 6 +++--- 4 files changed, 25 insertions(+), 24 deletions(-) diff --git a/electrum/blockchain.py b/electrum/blockchain.py index 4a6aad4ed..4cca1d282 100644 --- a/electrum/blockchain.py +++ b/electrum/blockchain.py @@ -296,17 +296,17 @@ class Blockchain(Logger): def verify_header(cls, header: dict, prev_hash: str, target: int, expected_header_hash: str=None) -> None: _hash = hash_header(header) if expected_header_hash and expected_header_hash != _hash: - raise Exception("hash mismatches with expected: {} vs {}".format(expected_header_hash, _hash)) + raise InvalidHeader("hash mismatches with expected: {} vs {}".format(expected_header_hash, _hash)) if prev_hash != header.get('prev_block_hash'): - raise Exception("prev hash mismatch: %s vs %s" % (prev_hash, header.get('prev_block_hash'))) + raise InvalidHeader("prev hash mismatch: %s vs %s" % (prev_hash, header.get('prev_block_hash'))) if constants.net.TESTNET: return bits = cls.target_to_bits(target) if bits != header.get('bits'): - raise Exception("bits mismatch: %s vs %s" % (bits, header.get('bits'))) + raise InvalidHeader("bits mismatch: %s vs %s" % (bits, header.get('bits'))) block_hash_as_num = int.from_bytes(bfh(_hash), byteorder='big') if block_hash_as_num > target: - raise Exception(f"insufficient proof of work: {block_hash_as_num} vs target {target}") + raise InvalidHeader(f"insufficient proof of work: {block_hash_as_num} vs target {target}") def verify_chunk(self, index: int, data: bytes) -> None: num = len(data) // HEADER_SIZE @@ -544,7 +544,7 @@ class Blockchain(Logger): def bits_to_target(cls, bits: int) -> int: # arith_uint256::SetCompact in Bitcoin Core if not (0 <= bits < (1 << 32)): - raise Exception(f"bits should be uint32. got {bits!r}") + raise InvalidHeader(f"bits should be uint32. got {bits!r}") bitsN = (bits >> 24) & 0xff bitsBase = bits & 0x7fffff if bitsN <= 3: @@ -553,12 +553,12 @@ class Blockchain(Logger): target = bitsBase << (8 * (bitsN-3)) if target != 0 and bits & 0x800000 != 0: # Bit number 24 (0x800000) represents the sign of N - raise Exception("target cannot be negative") + raise InvalidHeader("target cannot be negative") if (target != 0 and (bitsN > 34 or (bitsN > 33 and bitsBase > 0xff) or (bitsN > 32 and bitsBase > 0xffff))): - raise Exception("target has overflown") + raise InvalidHeader("target has overflown") return target @classmethod diff --git a/electrum/tests/test_blockchain.py b/electrum/tests/test_blockchain.py index cc57d21ef..b16850045 100644 --- a/electrum/tests/test_blockchain.py +++ b/electrum/tests/test_blockchain.py @@ -4,7 +4,7 @@ import os from electrum import constants, blockchain from electrum.simple_config import SimpleConfig -from electrum.blockchain import Blockchain, deserialize_header, hash_header +from electrum.blockchain import Blockchain, deserialize_header, hash_header, InvalidHeader from electrum.util import bfh, make_dir from . import ElectrumTestCase @@ -418,11 +418,11 @@ class TestBlockchain(ElectrumTestCase): # Make sure that we don't generate compacts with the 0x00800000 bit set self.assertEqual(0x02008000, Blockchain.target_to_bits(0x80)) - with self.assertRaises(Exception): # target cannot be negative + with self.assertRaises(InvalidHeader): # target cannot be negative Blockchain.bits_to_target(0x01fedcba) - with self.assertRaises(Exception): # target cannot be negative + with self.assertRaises(InvalidHeader): # target cannot be negative Blockchain.bits_to_target(0x04923456) - with self.assertRaises(Exception): # overflow + with self.assertRaises(InvalidHeader): # overflow Blockchain.bits_to_target(0xff123456) @@ -441,20 +441,20 @@ class TestVerifyHeader(ElectrumTestCase): Blockchain.verify_header(self.header, self.prev_hash, self.target) def test_expected_hash_mismatch(self): - with self.assertRaises(Exception): + with self.assertRaises(InvalidHeader): Blockchain.verify_header(self.header, self.prev_hash, self.target, expected_header_hash="foo") def test_prev_hash_mismatch(self): - with self.assertRaises(Exception): + with self.assertRaises(InvalidHeader): Blockchain.verify_header(self.header, "foo", self.target) def test_target_mismatch(self): - with self.assertRaises(Exception): + with self.assertRaises(InvalidHeader): other_target = Blockchain.bits_to_target(0x1d00eeee) Blockchain.verify_header(self.header, self.prev_hash, other_target) def test_insufficient_pow(self): - with self.assertRaises(Exception): + with self.assertRaises(InvalidHeader): self.header["nonce"] = 42 Blockchain.verify_header(self.header, self.prev_hash, self.target) diff --git a/electrum/tests/test_commands.py b/electrum/tests/test_commands.py index ff27a0db8..49eaa1165 100644 --- a/electrum/tests/test_commands.py +++ b/electrum/tests/test_commands.py @@ -8,6 +8,7 @@ from electrum.wallet import restore_wallet_from_text from electrum.address_synchronizer import TX_HEIGHT_UNCONFIRMED from electrum.simple_config import SimpleConfig from electrum.transaction import Transaction, TxOutput, tx_from_any +from electrum.util import UserFacingException from . import ElectrumTestCase from .test_wallet_vertical import WalletIntegrityHelper @@ -91,14 +92,14 @@ class TestCommands(ElectrumTestCase): config=self.config)['wallet'] cmds = Commands(config=self.config) # single address tests - with self.assertRaises(Exception): + with self.assertRaises(UserFacingException): await cmds.getprivatekeys("asdasd", wallet=wallet) # invalid addr, though might raise "not in wallet" - with self.assertRaises(Exception): + with self.assertRaises(UserFacingException): await cmds.getprivatekeys("bc1qgfam82qk7uwh5j2xxmcd8cmklpe0zackyj6r23", wallet=wallet) # not in wallet self.assertEqual("p2wpkh:L4jkdiXszG26SUYvwwJhzGwg37H2nLhrbip7u6crmgNeJysv5FHL", await cmds.getprivatekeys("bc1q2ccr34wzep58d4239tl3x3734ttle92a8srmuw", wallet=wallet)) # list of addresses tests - with self.assertRaises(Exception): + with self.assertRaises(UserFacingException): await cmds.getprivatekeys(['bc1q2ccr34wzep58d4239tl3x3734ttle92a8srmuw', 'asd'], wallet=wallet) self.assertEqual(['p2wpkh:L4jkdiXszG26SUYvwwJhzGwg37H2nLhrbip7u6crmgNeJysv5FHL', 'p2wpkh:L4rYY5QpfN6wJEF4SEKDpcGhTPnCe9zcGs6hiSnhpprZqVywFifN'], await cmds.getprivatekeys(['bc1q2ccr34wzep58d4239tl3x3734ttle92a8srmuw', 'bc1q9pzjpjq4nqx5ycnywekcmycqz0wjp2nq604y2n'], wallet=wallet)) @@ -111,14 +112,14 @@ class TestCommands(ElectrumTestCase): config=self.config)['wallet'] cmds = Commands(config=self.config) # single address tests - with self.assertRaises(Exception): + with self.assertRaises(UserFacingException): await cmds.getprivatekeys("asdasd", wallet=wallet) # invalid addr, though might raise "not in wallet" - with self.assertRaises(Exception): + with self.assertRaises(UserFacingException): await cmds.getprivatekeys("bc1qgfam82qk7uwh5j2xxmcd8cmklpe0zackyj6r23", wallet=wallet) # not in wallet self.assertEqual("p2wpkh:L15oxP24NMNAXxq5r2aom24pHPtt3Fet8ZutgL155Bad93GSubM2", await cmds.getprivatekeys("bc1q3g5tmkmlvxryhh843v4dz026avatc0zzr6h3af", wallet=wallet)) # list of addresses tests - with self.assertRaises(Exception): + with self.assertRaises(UserFacingException): await cmds.getprivatekeys(['bc1q3g5tmkmlvxryhh843v4dz026avatc0zzr6h3af', 'asd'], wallet=wallet) self.assertEqual(['p2wpkh:L15oxP24NMNAXxq5r2aom24pHPtt3Fet8ZutgL155Bad93GSubM2', 'p2wpkh:L4rYY5QpfN6wJEF4SEKDpcGhTPnCe9zcGs6hiSnhpprZqVywFifN'], await cmds.getprivatekeys(['bc1q3g5tmkmlvxryhh843v4dz026avatc0zzr6h3af', 'bc1q9pzjpjq4nqx5ycnywekcmycqz0wjp2nq604y2n'], wallet=wallet)) diff --git a/electrum/wallet.py b/electrum/wallet.py index dff9cef8a..cb0e5d01a 100644 --- a/electrum/wallet.py +++ b/electrum/wallet.py @@ -721,11 +721,11 @@ class Abstract_Wallet(ABC, Logger, EventListener): def export_private_key(self, address: str, password: Optional[str]) -> str: if self.is_watching_only(): - raise Exception(_("This is a watching-only wallet")) + raise UserFacingException(_("This is a watching-only wallet")) if not is_address(address): - raise Exception(f"Invalid bitcoin address: {address}") + raise UserFacingException(f"Invalid bitcoin address: {address}") if not self.is_mine(address): - raise Exception(_('Address not in wallet.') + f' {address}') + raise UserFacingException(_('Address not in wallet.') + f' {address}') index = self.get_address_index(address) pk, compressed = self.keystore.get_private_key(index, password) txin_type = self.get_txin_type(address)