URI: 
       tmore type annotations in core lib - electrum - Electrum Bitcoin wallet
  HTML git clone https://git.parazyd.org/electrum
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
       ---
   DIR commit 81cc20039ea5d45204c00b75b283ea877029fbb0
   DIR parent 6958c0ccc3d97edfb7f8504f27270182cb3abcfa
  HTML Author: SomberNight <somber.night@protonmail.com>
       Date:   Mon, 22 Oct 2018 16:41:25 +0200
       
       more type annotations in core lib
       
       Diffstat:
         M electrum/address_synchronizer.py    |      10 ++++++++--
         M electrum/base_wizard.py             |      13 +++++++++----
         M electrum/blockchain.py              |       5 +++--
         M electrum/commands.py                |       9 +++++++--
         M electrum/daemon.py                  |      18 +++++++++---------
         M electrum/exchange_rate.py           |       4 +++-
         M electrum/interface.py               |       7 +++++--
         M electrum/network.py                 |       4 ++--
         M electrum/plugin.py                  |       8 +++++---
         M electrum/synchronizer.py            |      10 +++++++---
         M electrum/util.py                    |      12 ++++++++----
         M electrum/verifier.py                |       8 ++++++--
         M electrum/wallet.py                  |      20 ++++++++++----------
         M electrum/websockets.py              |      11 ++++++++---
       
       14 files changed, 90 insertions(+), 49 deletions(-)
       ---
   DIR diff --git a/electrum/address_synchronizer.py b/electrum/address_synchronizer.py
       t@@ -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
       t@@ -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
       t@@ -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
   DIR diff --git a/electrum/base_wizard.py b/electrum/base_wizard.py
       t@@ -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)
       t@@ -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 = []
   DIR diff --git a/electrum/blockchain.py b/electrum/blockchain.py
       t@@ -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
       t@@ -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)
       t@@ -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
   DIR diff --git a/electrum/commands.py b/electrum/commands.py
       t@@ -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
       t@@ -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 = {}
        
       t@@ -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
   DIR diff --git a/electrum/daemon.py b/electrum/daemon.py
       t@@ -29,7 +29,7 @@ import time
        import traceback
        import sys
        import threading
       -from typing import Dict
       +from typing import Dict, Optional, Tuple
        
        import jsonrpclib
        
       t@@ -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')
        
        
       t@@ -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.
       t@@ -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
       t@@ -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:
       t@@ -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:
       t@@ -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)
       t@@ -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]
       t@@ -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
        
   DIR diff --git a/electrum/exchange_rate.py b/electrum/exchange_rate.py
       t@@ -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,
       t@@ -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:
   DIR diff --git a/electrum/interface.py b/electrum/interface.py
       t@@ -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
       t@@ -43,6 +43,9 @@ from . import blockchain
        from .blockchain import Blockchain
        from . import constants
        
       +if TYPE_CHECKING:
       +    from .network import Network
       +
        
        class NotificationSession(ClientSession):
        
       t@@ -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
   DIR diff --git a/electrum/network.py b/electrum/network.py
       t@@ -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))
   DIR diff --git a/electrum/plugin.py b/electrum/plugin.py
       t@@ -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()
       t@@ -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__)
   DIR diff --git a/electrum/synchronizer.py b/electrum/synchronizer.py
       t@@ -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
       t@@ -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:
       t@@ -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)
        
       t@@ -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)
        
   DIR diff --git a/electrum/util.py b/electrum/util.py
       t@@ -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
       t@@ -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()}
       t@@ -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)
       t@@ -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)
        
   DIR diff --git a/electrum/verifier.py b/electrum/verifier.py
       t@@ -22,7 +22,7 @@
        # SOFTWARE.
        
        import asyncio
       -from typing import Sequence, Optional
       +from typing import Sequence, Optional, TYPE_CHECKING
        
        import aiorpcx
        
       t@@ -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
       t@@ -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)
        
   DIR diff --git a/electrum/wallet.py b/electrum/wallet.py
       t@@ -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
       t@@ -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'),
       t@@ -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)
       t@@ -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)
       t@@ -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:
       t@@ -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
       t@@ -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'):
   DIR diff --git a/electrum/websockets.py b/electrum/websockets.py
       t@@ -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
        
       t@@ -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()
        
        
       t@@ -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]]]
       t@@ -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