URI: 
       tFix CLI. Some commands require wallet_path. Return error on exception. - electrum - Electrum Bitcoin wallet
  HTML git clone https://git.parazyd.org/electrum
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
       ---
   DIR commit 35b0b3a43c39fd862d71a2c861aea550982bbece
   DIR parent 5faa0ade3d7dff1ce1d93145d5f09fccfeea383e
  HTML Author: ThomasV <thomasv@electrum.org>
       Date:   Fri,  6 Sep 2019 11:06:08 +0200
       
       Fix CLI. Some commands require wallet_path. Return error on exception.
       
       Diffstat:
         M electrum/commands.py                |      57 +++++++++++++++++--------------
         M electrum/daemon.py                  |      14 ++------------
         M run_electrum                        |       4 +++-
       
       3 files changed, 37 insertions(+), 38 deletions(-)
       ---
   DIR diff --git a/electrum/commands.py b/electrum/commands.py
       t@@ -95,21 +95,30 @@ def command(s):
                name = func.__name__
                known_commands[name] = Command(func, s)
                @wraps(func)
       -        def func_wrapper(*args, **kwargs):
       -            c = known_commands[func.__name__]
       +        async def func_wrapper(*args, **kwargs):
       +            cmd_runner = args[0]
       +            cmd = known_commands[func.__name__]
                    password = kwargs.get('password')
       -            wallet = kwargs.get('wallet') # wallet is passed here if we are offline
       -            if c.requires_wallet and wallet is None:
       -                cmd_runner = args[0]
       -                path = cmd_runner.config.get_wallet_path()
       -                path = standardize_path(path)
       -                wallet = cmd_runner.daemon.wallets.get(path)
       -                if wallet is None:
       -                    raise Exception("wallet not loaded. Use 'electrum load_wallet'")
       -                kwargs['wallet'] = wallet
       -            if c.requires_password and password is None and wallet.has_password():
       +            daemon = cmd_runner.daemon
       +            if daemon:
       +                if (cmd.requires_wallet or 'wallet_path' in cmd.options) and kwargs.get('wallet_path') is None:
       +                    kwargs['wallet_path'] = daemon.config.get_wallet_path()
       +                if cmd.requires_wallet:
       +                    wallet_path = kwargs.pop('wallet_path')
       +                    wallet = daemon.wallets.get(wallet_path)
       +                    if wallet is None:
       +                        return {'error': "Wallet not loaded. try 'electrum load_wallet'" }
       +                    kwargs['wallet'] = wallet
       +            else:
       +                # we are offline. the wallet must have been passed
       +                pass
       +            if cmd.requires_password and password is None and wallet.has_password():
                        return {'error': 'Password required' }
       -            return func(*args, **kwargs)
       +            try:
       +                return await func(*args, **kwargs)
       +            except Exception as e:
       +                #traceback.print_exc(sys.stderr)
       +                return {'error':str(e)}
                return func_wrapper
            return decorator
        
       t@@ -182,27 +191,25 @@ class Commands:
                return [{'path':k, 'synchronized':w.is_up_to_date()} for k, w in self.daemon.wallets.items()]
        
            @command('n')
       -    async def load_wallet(self):
       +    async def load_wallet(self, wallet_path=None):
                """Open wallet in daemon"""
       -        path = self.config.get_wallet_path()
       -        wallet = self.daemon.load_wallet(path, self.config.get('password'))
       +        wallet = self.daemon.load_wallet(wallet_path, self.config.get('password'))
                if wallet is not None:
                    run_hook('load_wallet', wallet, None)
                response = wallet is not None
                return response
        
            @command('n')
       -    async def close_wallet(self):
       +    async def close_wallet(self, wallet_path=None):
                """Close wallet"""
       -        path = self.config.get_wallet_path()
       -        return self.daemon.stop_wallet(path)
       +        return self.daemon.stop_wallet(wallet_path)
        
            @command('')
       -    async def create(self, passphrase=None, password=None, encrypt_file=True, seed_type=None):
       +    async def create(self, passphrase=None, password=None, encrypt_file=True, seed_type=None, wallet_path=None):
                """Create a new wallet.
                If you want to be prompted for an argument, type '?' or ':' (concealed)
                """
       -        d = create_new_wallet(path=self.config.get_wallet_path(),
       +        d = create_new_wallet(path=wallet_path,
                                      passphrase=passphrase,
                                      password=password,
                                      encrypt_file=encrypt_file,
       t@@ -214,7 +221,7 @@ class Commands:
                }
        
            @command('')
       -    async def restore(self, text, passphrase=None, password=None, encrypt_file=True):
       +    async def restore(self, text, passphrase=None, password=None, encrypt_file=True, wallet_path=None):
                """Restore a wallet from text. Text can be a seed phrase, a master
                public key, a master private key, a list of bitcoin addresses
                or bitcoin private keys.
       t@@ -222,7 +229,7 @@ class Commands:
                """
                # TODO create a separate command that blocks until wallet is synced
                d = restore_wallet_from_text(text,
       -                                     path=self.config.get_wallet_path(),
       +                                     path=wallet_path,
                                             passphrase=passphrase,
                                             password=password,
                                             encrypt_file=encrypt_file)
       t@@ -1148,7 +1155,7 @@ def get_parser():
                p = subparsers.add_parser(cmdname, help=cmd.help, description=cmd.description)
                add_global_options(p)
                for optname, default in zip(cmd.options, cmd.defaults):
       -            if optname == 'wallet':
       +            if optname in ['wallet_path', 'wallet']:
                        continue
                    a, help = command_options[optname]
                    b = '--' + optname
       t@@ -1161,7 +1168,7 @@ def get_parser():
                        p.add_argument(*args, dest=optname, action=action, default=default, help=help)
        
                for param in cmd.params:
       -            if param == 'wallet':
       +            if param in ['wallet_path', 'wallet']:
                        continue
                    h = param_descriptions.get(param, '')
                    _type = arg_types.get(param, str)
   DIR diff --git a/electrum/daemon.py b/electrum/daemon.py
       t@@ -432,13 +432,6 @@ class Daemon(Logger):
                config.mempool_fees  = self.network.config.mempool_fees.copy()
                cmdname = config.get('cmd')
                cmd = known_commands[cmdname]
       -        if cmd.requires_wallet:
       -            path = config.get_wallet_path()
       -            path = standardize_path(path)
       -            wallet = self.wallets.get(path)
       -            if wallet is None:
       -                return {'error': 'Wallet "%s" is not loaded. Use "electrum load_wallet"'%os.path.basename(path) }
       -            config_options['wallet'] = wallet
                # arguments passed to function
                args = map(lambda x: config.get(x), cmd.params)
                # decode json arguments
       t@@ -446,12 +439,9 @@ class Daemon(Logger):
                # options
                kwargs = {}
                for x in cmd.options:
       -            kwargs[x] = (config_options.get(x) if x in ['wallet', 'password', 'new_password'] else config.get(x))
       +            kwargs[x] = (config_options.get(x) if x in ['password', 'new_password'] else config.get(x))
                func = getattr(self.cmd_runner, cmd.name)
       -        try:
       -            result = await func(*args, **kwargs)
       -        except TypeError as e:
       -            raise Exception("Wrapping TypeError to prevent JSONRPC-Pelix from hiding traceback") from e
       +        result = await func(*args, **kwargs)
                return result
        
            def run_daemon(self):
   DIR diff --git a/run_electrum b/run_electrum
       t@@ -203,6 +203,8 @@ async def run_offline_command(config, config_options, plugins):
            cmdname = config.get('cmd')
            cmd = known_commands[cmdname]
            password = config_options.get('password')
       +    if 'wallet_path' in cmd.options and config_options.get('wallet_path') is None:
       +        config_options['wallet_path'] = config.get_wallet_path()
            if cmd.requires_wallet:
                storage = WalletStorage(config.get_wallet_path())
                if storage.is_encrypted():
       t@@ -231,7 +233,7 @@ async def run_offline_command(config, config_options, plugins):
            # options
            kwargs = {}
            for x in cmd.options:
       -        kwargs[x] = (config_options.get(x) if x in ['wallet', 'password', 'new_password'] else config.get(x))
       +        kwargs[x] = (config_options.get(x) if x in ['wallet_path', 'wallet', 'password', 'new_password'] else config.get(x))
            cmd_runner = Commands(config=config)
            func = getattr(cmd_runner, cmd.name)
            result = await func(*args, **kwargs)