From b590c864eea2a4b358111a949d0902b7e0ed5b4a Mon Sep 17 00:00:00 2001 From: SomberNight Date: Wed, 25 Jun 2025 17:11:52 +0000 Subject: [PATCH] config: fix setting CLI_TIMEOUT configvar, and add "convert_setter"s "type_=float" behaves a bit weirdly. Was kinda broken before, still not fully "fixed" here. With this commit, if used together with convert_setter, it at least behaves in a sane way. ``` $ ./run_electrum -o setconfig timeout 10 1.16 | E | __main__ | error running command (without daemon) Traceback (most recent call last): File "/home/user/wspace/electrum/./run_electrum", line 593, in handle_cmd result = fut.result() File "/usr/lib/python3.10/concurrent/futures/_base.py", line 458, in result return self.__get_result() File "/usr/lib/python3.10/concurrent/futures/_base.py", line 403, in __get_result raise self._exception File "/home/user/wspace/electrum/./run_electrum", line 268, in run_offline_command result = await func(*args, **kwargs) File "/home/user/wspace/electrum/electrum/commands.py", line 194, in func_wrapper return await func(*args, **kwargs) File "/home/user/wspace/electrum/electrum/commands.py", line 408, in setconfig self._setconfig(key, value) File "/home/user/wspace/electrum/electrum/commands.py", line 398, in _setconfig cv.set(value) File "/home/user/wspace/electrum/electrum/simple_config.py", line 126, in set self._config_var._set_config_value(self._config, value, save=save) File "/home/user/wspace/electrum/electrum/simple_config.py", line 89, in _set_config_value raise ValueError( ValueError: ConfigVar.set type-check failed. key='timeout'. type=. value=10 ``` --- electrum/simple_config.py | 8 +++++++- tests/test_simple_config.py | 13 +++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/electrum/simple_config.py b/electrum/simple_config.py index d497bab11..4f83abfc3 100644 --- a/electrum/simple_config.py +++ b/electrum/simple_config.py @@ -37,6 +37,7 @@ class ConfigVar(property): default: Union[Any, Callable[['SimpleConfig'], Any]], # typically a literal, but can also be a callable type_=None, convert_getter: Callable[[Any], Any] = None, + convert_setter: Callable[[Any], Any] = None, short_desc: Callable[[], str] = None, long_desc: Callable[[], str] = None, plugin: Optional[str] = None, @@ -45,6 +46,7 @@ class ConfigVar(property): self._default = default self._type = type_ self._convert_getter = convert_getter + self._convert_setter = convert_setter # note: the descriptions are callables instead of str literals, to delay evaluating the _() translations # until after the language is set. assert short_desc is None or callable(short_desc) @@ -84,6 +86,10 @@ class ConfigVar(property): return value def _set_config_value(self, config: 'SimpleConfig', value, *, save=True): + # run converter + if self._convert_setter is not None and value is not None: + value = self._convert_setter(value) + # type-check if self._type is not None and value is not None: if not isinstance(value, self._type): raise ValueError( @@ -853,7 +859,7 @@ Warning: setting this to too low will result in lots of payment failures."""), 'For more information, see https://openalias.org'), ) HWD_SESSION_TIMEOUT = ConfigVar('session_timeout', default=300, type_=int) - CLI_TIMEOUT = ConfigVar('timeout', default=60, type_=float) + CLI_TIMEOUT = ConfigVar('timeout', default=60.0, type_=float, convert_setter=lambda v: float(v)) AUTOMATIC_CENTRALIZED_UPDATE_CHECKS = ConfigVar( 'check_updates', default=False, type_=bool, short_desc=lambda: _("Automatically check for software updates"), diff --git a/tests/test_simple_config.py b/tests/test_simple_config.py index 0a2aa2e7f..6b8ade704 100644 --- a/tests/test_simple_config.py +++ b/tests/test_simple_config.py @@ -161,6 +161,19 @@ class Test_SimpleConfig(ElectrumTestCase): config.NETWORK_PROXY = None self.assertEqual(None, config.NETWORK_PROXY) + def test_configvars_convert_setter(self): + config = SimpleConfig(self.options) + self.assertEqual(60, config.CLI_TIMEOUT) + assert isinstance(config.CLI_TIMEOUT, float) + + config.CLI_TIMEOUT = 10 + self.assertEqual(10, config.CLI_TIMEOUT) + assert isinstance(config.CLI_TIMEOUT, float) + + config.CLI_TIMEOUT = None + self.assertEqual(60, config.CLI_TIMEOUT) + assert isinstance(config.CLI_TIMEOUT, float) + def test_configvars_is_set(self): config = SimpleConfig(self.options) self.assertEqual(MAX_MSG_SIZE_DEFAULT, config.NETWORK_MAX_INCOMING_MSG_SIZE)