URI: 
       tkill old-style namedtuples - electrum - Electrum Bitcoin wallet
  HTML git clone https://git.parazyd.org/electrum
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
       ---
   DIR commit 9037f25da13873c751a1a333b43bae29296b0c13
   DIR parent 34569d172ff797047d11ae6f6bb6f95a9189879b
  HTML Author: SomberNight <somber.night@protonmail.com>
       Date:   Sun, 28 Oct 2018 00:28:29 +0200
       
       kill old-style namedtuples
       
       Diffstat:
         M electrum/coinchooser.py             |      18 ++++++++++--------
         M electrum/gui/qt/util.py             |      11 ++++++++---
         M electrum/network.py                 |      11 ++++++-----
         M electrum/plugin.py                  |      23 ++++++++++++++++-------
         M electrum/plugins/coldcard/coldcard… |       4 ++--
         M electrum/plugins/hw_wallet/plugin.… |      13 ++++++-------
         M electrum/transaction.py             |      22 ++++++++++++++--------
         M electrum/util.py                    |      20 ++++++++++++--------
       
       8 files changed, 74 insertions(+), 48 deletions(-)
       ---
   DIR diff --git a/electrum/coinchooser.py b/electrum/coinchooser.py
       t@@ -22,8 +22,9 @@
        # 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 collections import defaultdict, namedtuple
       +from collections import defaultdict
        from math import floor, log10
       +from typing import NamedTuple, List
        
        from .bitcoin import sha256, COIN, TYPE_ADDRESS, is_address
        from .transaction import Transaction, TxOutput
       t@@ -68,13 +69,14 @@ class PRNG:
                    x[i], x[j] = x[j], x[i]
        
        
       -Bucket = namedtuple('Bucket',
       -                    ['desc',
       -                     'weight',      # as in BIP-141
       -                     'value',       # in satoshis
       -                     'coins',       # UTXOs
       -                     'min_height',  # min block height where a coin was confirmed
       -                     'witness'])    # whether any coin uses segwit
       +class Bucket(NamedTuple):
       +    desc: str
       +    weight: int         # as in BIP-141
       +    value: int          # in satoshis
       +    coins: List[dict]   # UTXOs
       +    min_height: int     # min block height where a coin was confirmed
       +    witness: bool       # whether any coin uses segwit
       +
        
        def strip_unneeded(bkts, sufficient_funds):
            '''Remove buckets that are unnecessary in achieving the spend amount'''
   DIR diff --git a/electrum/gui/qt/util.py b/electrum/gui/qt/util.py
       t@@ -3,8 +3,8 @@ import time
        import sys
        import platform
        import queue
       -from collections import namedtuple
        from functools import partial
       +from typing import NamedTuple, Callable, Optional
        
        from PyQt5.QtGui import *
        from PyQt5.QtCore import *
       t@@ -638,7 +638,12 @@ class TaskThread(QThread):
            '''Thread that runs background tasks.  Callbacks are guaranteed
            to happen in the context of its parent.'''
        
       -    Task = namedtuple("Task", "task cb_success cb_done cb_error")
       +    class Task(NamedTuple):
       +        task: Callable
       +        cb_success: Optional[Callable]
       +        cb_done: Optional[Callable]
       +        cb_error: Optional[Callable]
       +
            doneSig = pyqtSignal(object, object, object)
        
            def __init__(self, parent, on_error=None):
       t@@ -654,7 +659,7 @@ class TaskThread(QThread):
        
            def run(self):
                while True:
       -            task = self.tasks.get()
       +            task = self.tasks.get()  # type: TaskThread.Task
                    if not task:
                        break
                    try:
   DIR diff --git a/electrum/network.py b/electrum/network.py
       t@@ -110,11 +110,12 @@ def pick_random_server(hostmap = None, protocol = 's', exclude_set = set()):
            return random.choice(eligible) if eligible else None
        
        
       -NetworkParameters = NamedTuple("NetworkParameters", [("host", str),
       -                                                     ("port", str),
       -                                                     ("protocol", str),
       -                                                     ("proxy", Optional[dict]),
       -                                                     ("auto_connect", bool)])
       +class NetworkParameters(NamedTuple):
       +    host: str
       +    port: str
       +    protocol: str
       +    proxy: Optional[dict]
       +    auto_connect: bool
        
        
        proxy_modes = ['socks4', 'socks5']
   DIR diff --git a/electrum/plugin.py b/electrum/plugin.py
       t@@ -22,13 +22,13 @@
        # 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 collections import namedtuple
        import traceback
        import sys
        import os
        import pkgutil
        import time
        import threading
       +from typing import NamedTuple, Any, Union
        
        from .i18n import _
        from .util import (profiler, PrintError, DaemonThread, UserCancelled,
       t@@ -259,14 +259,23 @@ class BasePlugin(PrintError):
                pass
        
        
       -class DeviceNotFoundError(Exception):
       -    pass
       +class DeviceNotFoundError(Exception): pass
       +class DeviceUnpairableError(Exception): pass
        
       -class DeviceUnpairableError(Exception):
       -    pass
        
       -Device = namedtuple("Device", "path interface_number id_ product_key usage_page")
       -DeviceInfo = namedtuple("DeviceInfo", "device label initialized")
       +class Device(NamedTuple):
       +    path: Union[str, bytes]
       +    interface_number: int
       +    id_: str
       +    product_key: Any   # when using hid, often Tuple[int, int]
       +    usage_page: int
       +
       +
       +class DeviceInfo(NamedTuple):
       +    device: Device
       +    label: str
       +    initialized: bool
       +
        
        class DeviceMgr(ThreadJob, PrintError):
            '''Manages hardware clients.  A client communicates over a hardware
   DIR diff --git a/electrum/plugins/coldcard/coldcard.py b/electrum/plugins/coldcard/coldcard.py
       t@@ -374,7 +374,7 @@ class Coldcard_KeyStore(Hardware_KeyStore):
                # give empty bytes for error cases; it seems to clear the old signature box
                return b''
        
       -    def build_psbt(self, tx, wallet=None, xfp=None):
       +    def build_psbt(self, tx: Transaction, wallet=None, xfp=None):
                # Render a PSBT file, for upload to Coldcard.
                # 
                if xfp is None:
       t@@ -390,7 +390,7 @@ class Coldcard_KeyStore(Hardware_KeyStore):
                    wallet.add_hw_info(tx)
        
                # wallet.add_hw_info installs this attr
       -        assert hasattr(tx, 'output_info'), 'need data about outputs'
       +        assert tx.output_info, 'need data about outputs'
        
                # Build map of pubkey needed as derivation from master, in PSBT binary format
                # 1) binary version of the common subpath for all keys
   DIR diff --git a/electrum/plugins/hw_wallet/plugin.py b/electrum/plugins/hw_wallet/plugin.py
       t@@ -28,7 +28,7 @@ from electrum.plugin import BasePlugin, hook
        from electrum.i18n import _
        from electrum.bitcoin import is_address, TYPE_SCRIPT
        from electrum.util import bfh, versiontuple
       -from electrum.transaction import opcodes, TxOutput
       +from electrum.transaction import opcodes, TxOutput, Transaction
        
        
        class HW_PluginBase(BasePlugin):
       t@@ -113,14 +113,13 @@ class HW_PluginBase(BasePlugin):
                return message
        
        
       -def is_any_tx_output_on_change_branch(tx):
       -    if not hasattr(tx, 'output_info'):
       +def is_any_tx_output_on_change_branch(tx: Transaction):
       +    if not tx.output_info:
                return False
       -    for _type, address, amount in tx.outputs():
       -        info = tx.output_info.get(address)
       +    for o in tx.outputs():
       +        info = tx.output_info.get(o.address)
                if info is not None:
       -            index, xpubs, m = info.address_index, info.sorted_xpubs, info.num_sig
       -            if index[0] == 1:
       +            if info.address_index[0] == 1:
                        return True
            return False
        
   DIR diff --git a/electrum/transaction.py b/electrum/transaction.py
       t@@ -31,7 +31,7 @@ import struct
        import traceback
        import sys
        from typing import (Sequence, Union, NamedTuple, Tuple, Optional, Iterable,
       -                    Callable, List)
       +                    Callable, List, Dict)
        
        from . import ecc, bitcoin, constants, segwit_addr
        from .util import print_error, profiler, to_bytes, bh2u, bfh
       t@@ -63,17 +63,22 @@ class MalformedBitcoinScript(Exception):
            pass
        
        
       -TxOutput = NamedTuple("TxOutput", [('type', int), ('address', str), ('value', Union[int, str])])
       -# ^ value is str when the output is set to max: '!'
       +class TxOutput(NamedTuple):
       +    type: int
       +    address: str
       +    value: Union[int, str]  # str when the output is set to max: '!'
        
        
       -TxOutputForUI = NamedTuple("TxOutputForUI", [('address', str), ('value', int)])
       +class TxOutputForUI(NamedTuple):
       +    address: str
       +    value: int
        
        
       -TxOutputHwInfo = NamedTuple("TxOutputHwInfo", [('address_index', Tuple),
       -                                               ('sorted_xpubs', Iterable[str]),
       -                                               ('num_sig', Optional[int]),
       -                                               ('script_type', str)])
       +class TxOutputHwInfo(NamedTuple):
       +    address_index: Tuple
       +    sorted_xpubs: Iterable[str]
       +    num_sig: Optional[int]
       +    script_type: str
        
        
        class BCDataStream(object):
       t@@ -682,6 +687,7 @@ class Transaction:
                # this value will get properly set when deserializing
                self.is_partial_originally = True
                self._segwit_ser = None  # None means "don't know"
       +        self.output_info = None  # type: Optional[Dict[str, TxOutputHwInfo]]
        
            def update(self, raw):
                self.raw = raw
   DIR diff --git a/electrum/util.py b/electrum/util.py
       t@@ -902,14 +902,18 @@ def ignore_exceptions(func):
            return wrapper
        
        
       -TxMinedStatus = NamedTuple("TxMinedStatus", [("height", int),
       -                                             ("conf", int),
       -                                             ("timestamp", int),
       -                                             ("header_hash", str)])
       -VerifiedTxInfo = NamedTuple("VerifiedTxInfo", [("height", int),
       -                                               ("timestamp", int),
       -                                               ("txpos", int),
       -                                               ("header_hash", str)])
       +class TxMinedStatus(NamedTuple):
       +    height: int
       +    conf: int
       +    timestamp: int
       +    header_hash: str
       +
       +
       +class VerifiedTxInfo(NamedTuple):
       +    height: int
       +    timestamp: int
       +    txpos: int
       +    header_hash: str
        
        
        def make_aiohttp_session(proxy: dict, headers=None, timeout=None):