Browse Source

more type annotations in core lib

3.3.3.1
SomberNight 6 years ago
parent
commit
81cc20039e
No known key found for this signature in database GPG Key ID: B33B5F232C6271E9
  1. 10
      electrum/address_synchronizer.py
  2. 13
      electrum/base_wizard.py
  3. 5
      electrum/blockchain.py
  4. 9
      electrum/commands.py
  5. 18
      electrum/daemon.py
  6. 4
      electrum/exchange_rate.py
  7. 7
      electrum/interface.py
  8. 4
      electrum/network.py
  9. 8
      electrum/plugin.py
  10. 10
      electrum/synchronizer.py
  11. 12
      electrum/util.py
  12. 8
      electrum/verifier.py
  13. 20
      electrum/wallet.py
  14. 11
      electrum/websockets.py

10
electrum/address_synchronizer.py

@ -34,6 +34,9 @@ from .synchronizer import Synchronizer
from .verifier import SPV
from .blockchain import hash_header
from .i18n import _
from .storage import WalletStorage
from .network import Network
TX_HEIGHT_LOCAL = -2
TX_HEIGHT_UNCONF_PARENT = -1
@ -53,9 +56,9 @@ class AddressSynchronizer(PrintError):
inherited by wallet
"""
def __init__(self, storage):
def __init__(self, storage: WalletStorage):
self.storage = storage
self.network = None
self.network = None # type: Network
# verifier (SPV) and synchronizer are started in start_network
self.synchronizer = None # type: Synchronizer
self.verifier = None # type: SPV
@ -807,3 +810,6 @@ class AddressSynchronizer(PrintError):
def is_empty(self, address):
c, u, x = self.get_addr_balance(address)
return c+u+x == 0
def synchronize(self):
pass

13
electrum/base_wizard.py

@ -31,10 +31,15 @@ from functools import partial
from . import bitcoin
from . import keystore
from .keystore import bip44_derivation, purpose48_derivation
from .wallet import Imported_Wallet, Standard_Wallet, Multisig_Wallet, wallet_types, Wallet
from .storage import STO_EV_USER_PW, STO_EV_XPUB_PW, get_derivation_used_for_hw_device_encryption
from .wallet import (Imported_Wallet, Standard_Wallet, Multisig_Wallet,
wallet_types, Wallet, Abstract_Wallet)
from .storage import (WalletStorage, STO_EV_USER_PW, STO_EV_XPUB_PW,
get_derivation_used_for_hw_device_encryption)
from .i18n import _
from .util import UserCancelled, InvalidPassword, WalletFileException
from .simple_config import SimpleConfig
from .plugin import Plugins
# hardware device setup purpose
HWD_SETUP_NEW_WALLET, HWD_SETUP_DECRYPT_WALLET = range(0, 2)
@ -48,12 +53,12 @@ class GoBack(Exception): pass
class BaseWizard(object):
def __init__(self, config, plugins, storage):
def __init__(self, config: SimpleConfig, plugins: Plugins, storage: WalletStorage):
super(BaseWizard, self).__init__()
self.config = config
self.plugins = plugins
self.storage = storage
self.wallet = None
self.wallet = None # type: Abstract_Wallet
self.stack = []
self.plugin = None
self.keystores = []

5
electrum/blockchain.py

@ -28,6 +28,7 @@ from . import util
from .bitcoin import Hash, hash_encode, int_to_hex, rev_hex
from . import constants
from .util import bfh, bh2u
from .simple_config import SimpleConfig
HEADER_SIZE = 80 # bytes
@ -77,7 +78,7 @@ blockchains = {} # type: Dict[int, Blockchain]
blockchains_lock = threading.Lock()
def read_blockchains(config):
def read_blockchains(config: 'SimpleConfig') -> Dict[int, 'Blockchain']:
blockchains[0] = Blockchain(config, 0, None)
fdir = os.path.join(util.get_headers_dir(config), 'forks')
util.make_dir(fdir)
@ -100,7 +101,7 @@ class Blockchain(util.PrintError):
Manages blockchain headers and their verification
"""
def __init__(self, config, forkpoint: int, parent_id: Optional[int]):
def __init__(self, config: SimpleConfig, forkpoint: int, parent_id: Optional[int]):
self.config = config
self.forkpoint = forkpoint
self.checkpoints = constants.net.CHECKPOINTS

9
electrum/commands.py

@ -32,6 +32,7 @@ import ast
import base64
from functools import wraps
from decimal import Decimal
from typing import Optional
from .import util, ecc
from .util import bfh, bh2u, format_satoshis, json_decode, print_error, json_encode
@ -43,8 +44,11 @@ from .paymentrequest import PR_PAID, PR_UNPAID, PR_UNKNOWN, PR_EXPIRED
from .synchronizer import Notifier
from .storage import WalletStorage
from . import keystore
from .wallet import Wallet, Imported_Wallet
from .wallet import Wallet, Imported_Wallet, Abstract_Wallet
from .mnemonic import Mnemonic
from .network import Network
from .simple_config import SimpleConfig
known_commands = {}
@ -95,7 +99,8 @@ def command(s):
class Commands:
def __init__(self, config, wallet, network, callback = None):
def __init__(self, config: 'SimpleConfig', wallet: Abstract_Wallet,
network: Optional['Network'], callback=None):
self.config = config
self.wallet = wallet
self.network = network

18
electrum/daemon.py

@ -29,7 +29,7 @@ import time
import traceback
import sys
import threading
from typing import Dict
from typing import Dict, Optional, Tuple
import jsonrpclib
@ -46,7 +46,7 @@ from .exchange_rate import FxThread
from .plugin import run_hook
def get_lockfile(config):
def get_lockfile(config: SimpleConfig):
return os.path.join(config.path, 'daemon')
@ -54,7 +54,7 @@ def remove_lockfile(lockfile):
os.unlink(lockfile)
def get_fd_or_server(config):
def get_fd_or_server(config: SimpleConfig):
'''Tries to create the lockfile, using O_EXCL to
prevent races. If it succeeds it returns the FD.
Otherwise try and connect to the server specified in the lockfile.
@ -73,7 +73,7 @@ def get_fd_or_server(config):
remove_lockfile(lockfile)
def get_server(config):
def get_server(config: SimpleConfig) -> Optional[jsonrpclib.Server]:
lockfile = get_lockfile(config)
while True:
create_time = None
@ -99,7 +99,7 @@ def get_server(config):
time.sleep(1.0)
def get_rpc_credentials(config):
def get_rpc_credentials(config: SimpleConfig) -> Tuple[str, str]:
rpc_user = config.get('rpcuser', None)
rpc_password = config.get('rpcpassword', None)
if rpc_user is None or rpc_password is None:
@ -121,7 +121,7 @@ def get_rpc_credentials(config):
class Daemon(DaemonThread):
def __init__(self, config, fd=None, *, listen_jsonrpc=True):
def __init__(self, config: SimpleConfig, fd=None, *, listen_jsonrpc=True):
DaemonThread.__init__(self)
self.config = config
if fd is None and listen_jsonrpc:
@ -142,7 +142,7 @@ class Daemon(DaemonThread):
self.init_server(config, fd)
self.start()
def init_server(self, config, fd):
def init_server(self, config: SimpleConfig, fd):
host = config.get('rpchost', '127.0.0.1')
port = config.get('rpcport', 0)
rpc_user, rpc_password = get_rpc_credentials(config)
@ -230,7 +230,7 @@ class Daemon(DaemonThread):
response = "Error: Electrum is running in daemon mode. Please stop the daemon first."
return response
def load_wallet(self, path, password):
def load_wallet(self, path, password) -> Optional[Abstract_Wallet]:
# wizard will be launched if we return
if path in self.wallets:
wallet = self.wallets[path]
@ -251,7 +251,7 @@ class Daemon(DaemonThread):
self.wallets[path] = wallet
return wallet
def add_wallet(self, wallet):
def add_wallet(self, wallet: Abstract_Wallet):
path = wallet.storage.path
self.wallets[path] = wallet

4
electrum/exchange_rate.py

@ -17,6 +17,8 @@ from .i18n import _
from .util import PrintError, ThreadJob, make_dir, log_exceptions
from .util import make_aiohttp_session
from .network import Network
from .simple_config import SimpleConfig
# See https://en.wikipedia.org/wiki/ISO_4217
CCY_PRECISIONS = {'BHD': 3, 'BIF': 0, 'BYR': 0, 'CLF': 4, 'CLP': 0,
@ -434,7 +436,7 @@ def get_exchanges_by_ccy(history=True):
class FxThread(ThreadJob):
def __init__(self, config, network):
def __init__(self, config: SimpleConfig, network: Network):
self.config = config
self.network = network
if self.network:

7
electrum/interface.py

@ -28,7 +28,7 @@ import ssl
import sys
import traceback
import asyncio
from typing import Tuple, Union, List
from typing import Tuple, Union, List, TYPE_CHECKING
from collections import defaultdict
import aiorpcx
@ -43,6 +43,9 @@ from . import blockchain
from .blockchain import Blockchain
from . import constants
if TYPE_CHECKING:
from .network import Network
class NotificationSession(ClientSession):
@ -129,7 +132,7 @@ def serialize_server(host: str, port: Union[str, int], protocol: str) -> str:
class Interface(PrintError):
def __init__(self, network, server, config_path, proxy):
def __init__(self, network: 'Network', server: str, config_path, proxy: dict):
self.ready = asyncio.Future()
self.got_disconnected = asyncio.Future()
self.server = server

4
electrum/network.py

@ -164,12 +164,12 @@ class Network(PrintError):
"""
verbosity_filter = 'n'
def __init__(self, config=None):
def __init__(self, config: SimpleConfig=None):
global INSTANCE
INSTANCE = self
if config is None:
config = {} # Do not use mutables as default values!
self.config = SimpleConfig(config) if isinstance(config, dict) else config
self.config = SimpleConfig(config) if isinstance(config, dict) else config # type: SimpleConfig
self.num_server = 10 if not self.config.get('oneserver') else 0
blockchain.blockchains = blockchain.read_blockchains(self.config)
self.print_error("blockchains", list(blockchain.blockchains))

8
electrum/plugin.py

@ -30,11 +30,13 @@ import pkgutil
import time
import threading
from .util import print_error
from .i18n import _
from .util import profiler, PrintError, DaemonThread, UserCancelled, ThreadJob
from .util import (profiler, PrintError, DaemonThread, UserCancelled,
ThreadJob, print_error)
from . import bitcoin
from . import plugins
from .simple_config import SimpleConfig
plugin_loaders = {}
hook_names = set()
@ -45,7 +47,7 @@ class Plugins(DaemonThread):
verbosity_filter = 'p'
@profiler
def __init__(self, config, is_local, gui_name):
def __init__(self, config: SimpleConfig, is_local, gui_name):
DaemonThread.__init__(self)
self.setName('Plugins')
self.pkgpath = os.path.dirname(plugins.__file__)

10
electrum/synchronizer.py

@ -24,7 +24,7 @@
# SOFTWARE.
import asyncio
import hashlib
from typing import Dict, List
from typing import Dict, List, TYPE_CHECKING
from collections import defaultdict
from aiorpcx import TaskGroup, run_in_thread
@ -33,6 +33,10 @@ from .transaction import Transaction
from .util import bh2u, make_aiohttp_session, NetworkJobOnDefaultServer
from .bitcoin import address_to_scripthash
if TYPE_CHECKING:
from .network import Network
from .address_synchronizer import AddressSynchronizer
def history_status(h):
if not h:
@ -47,7 +51,7 @@ class SynchronizerBase(NetworkJobOnDefaultServer):
"""Subscribe over the network to a set of addresses, and monitor their statuses.
Every time a status changes, run a coroutine provided by the subclass.
"""
def __init__(self, network):
def __init__(self, network: 'Network'):
self.asyncio_loop = network.asyncio_loop
NetworkJobOnDefaultServer.__init__(self, network)
@ -112,7 +116,7 @@ class Synchronizer(SynchronizerBase):
we don't have the full history of, and requests binary transaction
data of any transactions the wallet doesn't have.
'''
def __init__(self, wallet):
def __init__(self, wallet: 'AddressSynchronizer'):
self.wallet = wallet
SynchronizerBase.__init__(self, wallet.network)

12
electrum/util.py

@ -23,7 +23,7 @@
import binascii
import os, sys, re, json
from collections import defaultdict
from typing import NamedTuple, Union
from typing import NamedTuple, Union, TYPE_CHECKING
from datetime import datetime
import decimal
from decimal import Decimal
@ -46,6 +46,10 @@ from aiorpcx import TaskGroup
from .i18n import _
if TYPE_CHECKING:
from .network import Network
from .interface import Interface
def inv_dict(d):
return {v: k for k, v in d.items()}
@ -923,10 +927,10 @@ class NetworkJobOnDefaultServer(PrintError):
interface. Every time the main interface changes, the job is
restarted, and some of its internals are reset.
"""
def __init__(self, network):
def __init__(self, network: 'Network'):
asyncio.set_event_loop(network.asyncio_loop)
self.network = network
self.interface = None
self.interface = None # type: Interface
self._restart_lock = asyncio.Lock()
self._reset()
asyncio.run_coroutine_threadsafe(self._restart(), network.asyncio_loop)
@ -938,7 +942,7 @@ class NetworkJobOnDefaultServer(PrintError):
"""
self.group = SilentTaskGroup()
async def _start(self, interface):
async def _start(self, interface: 'Interface'):
self.interface = interface
await interface.group.spawn(self._start_tasks)

8
electrum/verifier.py

@ -22,7 +22,7 @@
# SOFTWARE.
import asyncio
from typing import Sequence, Optional
from typing import Sequence, Optional, TYPE_CHECKING
import aiorpcx
@ -33,6 +33,10 @@ from .blockchain import hash_header
from .interface import GracefulDisconnect
from . import constants
if TYPE_CHECKING:
from .network import Network
from .address_synchronizer import AddressSynchronizer
class MerkleVerificationFailure(Exception): pass
class MissingBlockHeader(MerkleVerificationFailure): pass
@ -43,7 +47,7 @@ class InnerNodeOfSpvProofIsValidTx(MerkleVerificationFailure): pass
class SPV(NetworkJobOnDefaultServer):
""" Simple Payment Verification """
def __init__(self, network, wallet):
def __init__(self, network: 'Network', wallet: 'AddressSynchronizer'):
self.wallet = wallet
NetworkJobOnDefaultServer.__init__(self, network)

20
electrum/wallet.py

@ -48,7 +48,7 @@ from .util import (NotEnoughFunds, PrintError, UserCancelled, profiler,
from .bitcoin import *
from .version import *
from .keystore import load_keystore, Hardware_KeyStore
from .storage import multisig_type, STO_EV_PLAINTEXT, STO_EV_USER_PW, STO_EV_XPUB_PW
from .storage import multisig_type, STO_EV_PLAINTEXT, STO_EV_USER_PW, STO_EV_XPUB_PW, WalletStorage
from . import transaction, bitcoin, coinchooser, paymentrequest, contacts
from .transaction import Transaction, TxOutput, TxOutputHwInfo
from .plugin import run_hook
@ -57,6 +57,9 @@ from .address_synchronizer import (AddressSynchronizer, TX_HEIGHT_LOCAL,
from .paymentrequest import PR_PAID, PR_UNPAID, PR_UNKNOWN, PR_EXPIRED
from .paymentrequest import InvoiceStore
from .contacts import Contacts
from .network import Network
from .simple_config import SimpleConfig
TX_STATUS = [
_('Unconfirmed'),
@ -67,18 +70,18 @@ TX_STATUS = [
def relayfee(network):
def relayfee(network: Network):
from .simple_config import FEERATE_DEFAULT_RELAY
MAX_RELAY_FEE = 50000
f = network.relay_fee if network and network.relay_fee else FEERATE_DEFAULT_RELAY
return min(f, MAX_RELAY_FEE)
def dust_threshold(network):
def dust_threshold(network: Network):
# Change <= dust threshold is added to the tx fee
return 182 * 3 * relayfee(network) / 1000
def append_utxos_to_inputs(inputs, network, pubkey, txin_type, imax):
def append_utxos_to_inputs(inputs, network: Network, pubkey, txin_type, imax):
if txin_type != 'p2pk':
address = bitcoin.pubkey_to_address(txin_type, pubkey)
scripthash = bitcoin.address_to_scripthash(address)
@ -101,7 +104,7 @@ def append_utxos_to_inputs(inputs, network, pubkey, txin_type, imax):
item['num_sig'] = 1
inputs.append(item)
def sweep_preparations(privkeys, network, imax=100):
def sweep_preparations(privkeys, network: Network, imax=100):
def find_utxos_for_privkey(txin_type, privkey, compressed):
pubkey = ecc.ECPrivkey(privkey).get_public_key_hex(compressed=compressed)
@ -127,7 +130,7 @@ def sweep_preparations(privkeys, network, imax=100):
return inputs, keypairs
def sweep(privkeys, network, config, recipient, fee=None, imax=100):
def sweep(privkeys, network: Network, config: SimpleConfig, recipient, fee=None, imax=100):
inputs, keypairs = sweep_preparations(privkeys, network, imax)
total = sum(i.get('value') for i in inputs)
if fee is None:
@ -164,7 +167,7 @@ class Abstract_Wallet(AddressSynchronizer):
gap_limit_for_change = 6
verbosity_filter = 'w'
def __init__(self, storage):
def __init__(self, storage: WalletStorage):
AddressSynchronizer.__init__(self, storage)
# saved fields
@ -220,9 +223,6 @@ class Abstract_Wallet(AddressSynchronizer):
if not bitcoin.is_address(addrs[0]):
raise WalletFileException('The addresses in this wallet are not bitcoin addresses.')
def synchronize(self):
pass
def calc_unused_change_addresses(self):
with self.lock:
if hasattr(self, '_unused_change_addresses'):

11
electrum/websockets.py

@ -27,7 +27,7 @@ import os
import json
from collections import defaultdict
import asyncio
from typing import Dict, List, Tuple
from typing import Dict, List, Tuple, TYPE_CHECKING
import traceback
import sys
@ -40,6 +40,11 @@ from .util import PrintError
from . import bitcoin
from .synchronizer import SynchronizerBase
if TYPE_CHECKING:
from .network import Network
from .simple_config import SimpleConfig
request_queue = asyncio.Queue()
@ -61,7 +66,7 @@ class ElectrumWebSocket(WebSocket, PrintError):
class BalanceMonitor(SynchronizerBase):
def __init__(self, config, network):
def __init__(self, config: 'SimpleConfig', network: 'Network'):
SynchronizerBase.__init__(self, network)
self.config = config
self.expected_payments = defaultdict(list) # type: Dict[str, List[Tuple[WebSocket, int]]]
@ -104,7 +109,7 @@ class BalanceMonitor(SynchronizerBase):
class WebSocketServer(threading.Thread):
def __init__(self, config, network):
def __init__(self, config: 'SimpleConfig', network: 'Network'):
threading.Thread.__init__(self)
self.config = config
self.network = network

Loading…
Cancel
Save